1# Copyright (C) 2019-2022 Intel Corporation. 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5 6import os 7import sys 8import shutil 9import argparse 10import pci_dev 11import dmi 12import acpi 13import clos 14import misc 15import parser_lib 16import logging 17from inspectorlib import external_tools 18 19OUTPUT = "./out/" 20PY_CACHE = "__pycache__" 21 22CPU_VENDOR = "GenuineIntel" 23 24def check_permission(): 25 """Check if it is root permission""" 26 if os.getuid(): 27 logging.critical("Run this tool with root privileges (sudo).") 28 sys.exit(1) 29 30def vendor_check(): 31 """Check the CPU vendor""" 32 with open("/proc/cpuinfo", 'r') as f_node: 33 while True: 34 line = f_node.readline() 35 if len(line.split(':')) == 2: 36 if line.split(':')[0].strip() == "vendor_id": 37 vendor_name = line.split(':')[1].strip() 38 return vendor_name == CPU_VENDOR 39 40def check_msr_nodes(cpu_dirs): 41 cpu_list_of_no_msr_node = [] 42 for cpu_num in os.listdir(cpu_dirs): 43 if cpu_num.isdigit(): 44 if os.path.exists(os.path.join(cpu_dirs, "{}/msr".format(cpu_num))): 45 continue 46 else: 47 cpu_list_of_no_msr_node.append(cpu_num) 48 return cpu_list_of_no_msr_node 49 50def check_env(): 51 """Check if there is appropriate environment on this system""" 52 if os.path.exists(PY_CACHE): 53 shutil.rmtree(PY_CACHE) 54 55 if not external_tools.locate_tools(['cpuid', 'rdmsr', 'lspci', 'dmidecode', 'blkid', 'stty', 'modprobe']): 56 sys.exit(1) 57 58 # check cpu msr file 59 cpu_dirs = "/dev/cpu" 60 if check_msr_nodes(cpu_dirs): 61 res = external_tools.run("modprobe msr") 62 err_msg = res.stderr.readline().decode('ascii') 63 if err_msg: 64 logging.critical("{}".format(err_msg)) 65 exit(-1) 66 msr_node_unavailable_cpus = check_msr_nodes(cpu_dirs) 67 if msr_node_unavailable_cpus: 68 for cpu_num in msr_node_unavailable_cpus: 69 logging.critical("Missing CPU MSR file at {}/{}/msr".format(cpu_dirs, cpu_num)) 70 logging.critical("Missing CPU MSR file /dev/cpu/#/msr. Check the value of CONFIG_X86_MSR in the kernel config." \ 71 " Set it to 'Y' and rebuild the OS. Then rerun the Board Inspector.") 72 exit(-1) 73 74 # check cpu vendor id 75 if not vendor_check(): 76 logging.critical(f"Unsupported processor {CPU_VENDOR} found. ACRN requires using a {CPU_VENDOR} processor.") 77 sys.exit(1) 78 79 if os.path.exists(OUTPUT): 80 shutil.rmtree(OUTPUT) 81 82 83if __name__ == '__main__': 84 check_permission() 85 86 check_env() 87 88 # arguments to parse 89 PARSER = argparse.ArgumentParser(usage='%(prog)s <board_name> [--out board_info_file]') 90 PARSER.add_argument('board_name', help=": the name of the board that runs the ACRN hypervisor") 91 PARSER.add_argument('--out', help=": the name of board info file.") 92 ARGS = PARSER.parse_args() 93 94 if not ARGS.out: 95 os.makedirs(OUTPUT) 96 BOARD_INFO = OUTPUT + ARGS.board_name + ".xml" 97 else: 98 BOARD_INFO = ARGS.out 99 100 with open(BOARD_INFO, 'w+') as f: 101 print('<acrn-config board="{}">'.format(ARGS.board_name), file=f) 102 103 # Get bios and base board info and store to board info 104 dmi.generate_info(BOARD_INFO) 105 106 # Get pci devicse table and store pci info to board info 107 pci_dev.generate_info(BOARD_INFO) 108 109 # Generate board info 110 acpi.generate_info(BOARD_INFO) 111 112 # Generate clos info 113 clos.generate_info(BOARD_INFO) 114 115 # Generate misc info 116 misc.generate_info(BOARD_INFO) 117 118 with open(BOARD_INFO, 'a+') as f: 119 print("</acrn-config>", file=f) 120