def dump_psram(config): print("\t<RTCT>", file=config) rtct = None if os.path.exists("/sys/firmware/acpi/tables/PTCT"): rtct = parse_rtct(path="/sys/firmware/acpi/tables/PTCT") elif os.path.exists("/sys/firmware/acpi/tables/RTCT"): rtct = parse_rtct(path="/sys/firmware/acpi/tables/RTCT") if rtct: for entry in rtct.entries: if entry.type == acpiparser.rtct.ACPI_RTCT_TYPE_SoftwareSRAM: print("\t\t<SoftwareSRAM>", file=config) print("\t\t\t<cache_level>{}</cache_level>".format( entry.cache_level), file=config) print("\t\t\t<base>{}</base>".format(hex(entry.base)), file=config) print("\t\t\t<ways>{}</ways>".format(hex(entry.ways)), file=config) print("\t\t\t<size>{}</size>".format(hex(entry.size)), file=config) for apic_id in entry.apic_id_tbl: print("\t\t\t<apic_id>{}</apic_id>".format(hex(apic_id)), file=config) print("\t\t</SoftwareSRAM>", file=config) else: parser_lib.print_yel( "No PTCT or RTCT found. The platform may not support pseudo RAM.") print("\t</RTCT>", file=config) print("", file=config)
def get_clos_info(): """Get max clos, mask supported and clos cache type""" rdt_res = [] rdt_clos_max = [] rdt_mask_max = [] cmd = "cpuid -1 -r -l 0x10" rdt_res = dump_cpuid_reg(cmd, "ebx") if len(rdt_res) == 0: parser_lib.print_yel("Resource Allocation is not supported!") else: for i in range(len(rdt_res)): if rdt_res[i] == "L2": cmd = "cpuid -1 -r -l 0x10 --subleaf 2" rdt_clos_max.append(dump_cpuid_reg(cmd, "edx")) l2_info = dump_cpuid_reg(cmd, "eax") rdt_mask_max.append(hex((1 << l2_info) - 1)) if rdt_res[i] == "L3": cmd = "cpuid -1 -r -l 0x10 --subleaf 1" rdt_clos_max.append(dump_cpuid_reg(cmd, "edx")) l3_info = dump_cpuid_reg(cmd, "eax") rdt_mask_max.append(hex((1 << l3_info) - 1)) if rdt_res[i] == "MBA": cmd = "cpuid -1 -r -l 0x10 --subleaf 3" rdt_clos_max.append(dump_cpuid_reg(cmd, "edx")) rdt_mask_max.append(hex(dump_cpuid_reg(cmd, "eax"))) return (rdt_res, rdt_clos_max, rdt_mask_max)
def check_env(): """Check if there is appropriate environment on this system""" if os.path.exists(PY_CACHE): shutil.rmtree(PY_CACHE) # check cpu vendor id if not vendor_check(): parser_lib.print_red("Please run this tools on {}!".format(CPU_VENDOR)) sys.exit(1) # check if required tools are exists for excute in BIN_LIST: res = subprocess.Popen("which {}".format(excute), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) line = res.stdout.readline().decode('ascii') if not line: parser_lib.print_yel("'{}' not found, please install it!".format(excute)) sys.exit(1) if excute == 'cpuid': res = subprocess.Popen("cpuid -v", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) line = res.stdout.readline().decode('ascii') version = line.split()[2] if int(version) < 20170122: parser_lib.print_yel("Need CPUID version >= 20170122") sys.exit(1) if os.path.exists(OUTPUT): shutil.rmtree(OUTPUT)
def get_clos_info(): """Get clos max and clos cache type""" clos_max = 0 clos_cache = False cmd = "cpuid -r -l 0x10" clos_cache = dump_cpuid_reg(cmd, "ebx") if clos_cache == "L2": cmd = "cpuid -r -l 0x10 --subleaf 2" elif clos_cache == "L3": cmd = "cpuid -r -l 0x10 --subleaf 1" else: clos_max = 0 parser_lib.print_yel("CLOS is not supported!") return (clos_cache, clos_max) clos_max = dump_cpuid_reg(cmd, "edx") return (clos_cache, clos_max)
def store_px_data(sysnode, config): """This will get Px data of power and store it to px data :param sysnode: the path of system power state, such as: /sys/devices/system/cpu/ :param config: file pointer that opened for writing board config information """ px_tmp = PxPkg() px_data = {} try: with open(sysnode + 'cpu0/cpufreq/scaling_driver', 'r') as f_node: freq_driver = f_node.read() if freq_driver.find("acpi-cpufreq") == -1: parser_lib.print_yel("The Px data for ACRN relies on " +\ "acpi-cpufreq driver but it is not found, ", warn=True, end=False) if freq_driver.find("intel_pstate") == 0: print("please add intel_pstate=disable in kernel " +\ "cmdline to fall back to acpi-cpufreq driver") else: parser_lib.print_yel( "please make sure ACPI Pstate is enabled in BIOS.", warn=True) print("\t/* Px data is not available */", file=config) return except IOError: parser_lib.print_yel("No scaling_driver found.", warn=True) print("\t/* Px data is not available */", file=config) return try: with open(sysnode + 'cpufreq/boost', 'r') as f_node: boost = f_node.read() except IOError: boost = 0 parser_lib.print_yel("CPU turbo is not enabled!") with open(sysnode + 'cpu0/cpufreq/scaling_available_frequencies', 'r') as f_node: freqs = f_node.read() with open(sysnode + 'cpu0/cpufreq/cpuinfo_transition_latency') as f_node: latency = int(f_node.read().strip()) latency = latency // 1000 i = 0 p_cnt = 0 for freq in freqs.split(): if boost != 0 and i == 0: try: subprocess.check_call('/usr/sbin/rdmsr 0x1ad', shell=True, stdout=subprocess.PIPE) except subprocess.CalledProcessError: parser_lib.print_red("MSR 0x1ad not support in this platform!", err=True) sys.exit(1) res = subprocess.Popen('/usr/sbin/rdmsr 0x1ad', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) result = res.stdout.readline().strip() #max_ratio_cpu = result[-2:] ctl_state = int(result[-2:], 16) << 8 i += 1 else: ctl_state = int(freq) // 100000 << 8 px_tmp.core_freq = int(int(freq) / 1000) px_tmp.power = 0 px_tmp.trans_latency = latency px_tmp.bus_latency = latency px_tmp.control = ctl_state px_tmp.status = ctl_state px_data[freq] = px_tmp print("\t{{0x{:0>2X}UL, 0x{:0>2X}UL, 0x{:0>2X}UL, ".format( px_data[freq].core_freq, px_data[freq].power, px_data[freq].trans_latency), file=config, end="") print("0x{:0>2X}UL, 0x{:0>6X}UL, 0x{:0>6X}UL}},\t/* P{} */".format( px_data[freq].bus_latency, px_data[freq].control, px_data[freq].status, p_cnt), file=config) p_cnt += 1
def store_cx_data(sysnode1, sysnode2, config): """This will get Cx data of power and store it to PackedCx :param sysnode1: the path of cx power state driver :param sysnode2: the path of cpuidle :param config: file pointer that opened for writing board config information """ i = 0 state_cpus = {} try: with open(sysnode1, 'r') as acpi_idle: idle_driver = acpi_idle.read(32) if idle_driver.find("acpi_idle") == -1: parser_lib.print_yel("The Cx data for ACRN relies on " +\ "acpi_idle driver but it is not found, ", warn=True, end=False) if idle_driver.find("intel_idle") == 0: print("please add idle=nomwait in kernel " +\ "cmdline to fall back to acpi_idle driver") else: parser_lib.print_yel( "please make sure ACPI Cstate is enabled in BIOS.", warn=True) print("\t/* Cx data is not available */", file=config) return except IOError: parser_lib.print_yel("No idle driver found.", warn=True) print("\t/* Cx data is not available */", file=config) return files = os.listdir(sysnode2) for d_path in files: if os.path.isdir(sysnode2 + d_path): state_cpus[d_path] = sysnode2 + d_path state_cpus = sorted(state_cpus.keys()) del state_cpus[0] cpu_state = ['desc', 'latency', 'power'] acpi_hw_type = ['HLT', 'MWAIT', 'IOPORT'] cx_state = defaultdict(dict) c_cnt = 1 for state in state_cpus: i += 1 for item in cpu_state: cx_data_file = open(sysnode2 + state + '/' + item, 'r') cx_state[state][item] = cx_data_file.read().strip() cx_state[state]['type'] = i PackedCx.space_id_8b = SPACE_ID[0x7F] if cx_state[state][cpu_state[0]].find(acpi_hw_type[0]) != -1: PackedCx.bit_width_8b = 0 PackedCx.bit_offset_8b = 0 PackedCx.access_size_8b = 0 PackedCx.address_64b = 0 elif cx_state[state][cpu_state[0]].find(acpi_hw_type[1]) != -1: PackedCx.bit_width_8b = 1 PackedCx.bit_offset_8b = 2 PackedCx.access_size_8b = 1 addr_val = get_value_after_str(cx_state[state][cpu_state[0]], acpi_hw_type[1]) PackedCx.address_64b = addr_val elif cx_state[state][cpu_state[0]].find(acpi_hw_type[2]) != -1: PackedCx.space_id_8b = SPACE_ID[1] PackedCx.bit_width_8b = 8 PackedCx.bit_offset_8b = 0 PackedCx.access_size_8b = 0 addr_val = get_value_after_str(cx_state[state][cpu_state[0]], acpi_hw_type[2]) PackedCx.address_64b = addr_val print("\t{{{{{}, 0x{:0>2X}U, 0x{:0>2X}U, 0x{:0>2X}U, ".format( PackedCx.space_id_8b, PackedCx.bit_width_8b, PackedCx.bit_offset_8b, PackedCx.access_size_8b), file=config, end="") print( "0x{:0>2X}UL}}, 0x{:0>2X}U, 0x{:0>2X}U, 0x{:0>2X}U}},\t/* C{} */". format(int(str(PackedCx.address_64b), 16), cx_state[state]['type'], int(cx_state[state][cpu_state[1]]), int(cx_state[state][cpu_state[2]]), c_cnt), file=config) c_cnt += 1
def store_px_data(sysnode, config): """This will get Px data of power and store it to px data""" px_tmp = PxPkg() px_data = {} with open(sysnode+'cpu0/cpufreq/scaling_driver', 'r') as f_node: freq_driver = f_node.read() if freq_driver.find("acpi-cpufreq") == -1: if freq_driver.find("intel_pstate") == 0: parser_lib.print_red("The tool need to run with acpi_cpufreq driver, " + "please add intel_pstate=disable in kernel cmdline " + "to fall back to acpi-cpufreq driver.", err=True) else: parser_lib.print_red("acpi-cpufreq driver is not found.", err=True) sys.exit(1) try: with open(sysnode+'cpufreq/boost', 'r') as f_node: boost = f_node.read() except IOError: boost = 0 parser_lib.print_yel("CPU turbo is not enabled!") with open(sysnode + 'cpu0/cpufreq/scaling_available_frequencies', 'r') as f_node: freqs = f_node.read() with open(sysnode + 'cpu0/cpufreq/cpuinfo_transition_latency') as f_node: latency = int(f_node.read().strip()) latency = latency//1000 i = 0 p_cnt = 0 for freq in freqs.split(): if boost != 0 and i == 0: try: subprocess.check_call('/usr/sbin/rdmsr 0x1ad', shell=True, stdout=subprocess.PIPE) except subprocess.CalledProcessError: parser_lib.print_red("MSR 0x1ad not support in this platform!", err=True) sys.exit(1) res = subprocess.Popen('/usr/sbin/rdmsr 0x1ad', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) result = res.stdout.readline().strip() #max_ratio_cpu = result[-2:] ctl_state = int(result[-2:], 16) << 8 i += 1 else: ctl_state = int(freq)//100000 << 8 px_tmp.core_freq = int(int(freq) / 1000) px_tmp.power = 0 px_tmp.trans_latency = latency px_tmp.bus_latency = latency px_tmp.control = ctl_state px_tmp.status = ctl_state px_data[freq] = px_tmp print("\t\t{{0x{:0>2X}UL, 0x{:0>2X}UL, 0x{:0>2X}UL, ".format( px_data[freq].core_freq, px_data[freq].power, px_data[freq].trans_latency), file=config, end="") print("0x{:0>2X}UL, 0x{:0>6X}UL, 0x{:0>6X}UL}}, /* P{} */".format( px_data[freq].bus_latency, px_data[freq].control, px_data[freq].status, p_cnt), file=config) p_cnt += 1