diff --git a/misc/config_tools/acpi_gen/bin_gen.py b/misc/config_tools/acpi_gen/bin_gen.py index 8ff71feb1..51f6a3d6e 100644 --- a/misc/config_tools/acpi_gen/bin_gen.py +++ b/misc/config_tools/acpi_gen/bin_gen.py @@ -13,9 +13,47 @@ import lxml.etree from acpi_const import * import acpiparser.tpm2 import inspectorlib.cdata +import acpiparser.rtct import common -def asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path): +def move_rtct_ssram_and_bin_entries(rtct, new_base_addr, new_area_max_size): + ''' + move the guest ssram and ctl bin entries to a new base addr. the entries keeps their relative layout + :param rtct: parsed rtct bit struct + :param new_base_addr: the top address of the new area + :param new_area_max_size: max size of the new area. for valid check + :return: + ''' + if rtct.version == 1: + expect_ssram_type = acpiparser.rtct.ACPI_RTCT_V1_TYPE_SoftwareSRAM + expect_bin_type = acpiparser.rtct.ACPI_RTCT_V1_TYPE_CRL_Binary + elif rtct.version == 2: + expect_ssram_type = acpiparser.rtct.ACPI_RTCT_V2_TYPE_SoftwareSRAM + expect_bin_type = acpiparser.rtct.ACPI_RTCT_V2_TYPE_CRL_Binary + else: + raise Exception("RTCT version error! ", rtct.version) + top = 0 + base = 0 + for entry in rtct.entries: + if entry.type == expect_ssram_type: + top = (entry.base + entry.size) if top < (entry.base + entry.size) else top + base = entry.base if base == 0 or entry.base < base else base + elif entry.type == expect_bin_type: + top = (entry.address + entry.size) if top < (entry.address + entry.size) else top + base = entry.address if base == 0 or entry.address < base else base + if new_area_max_size < (top - base): + raise Exception("not enough space in guest VE820 SSRAM area!") + rtct_move_offset = new_base_addr - base + for entry in rtct.entries: + if entry.type == expect_ssram_type: + entry.base += rtct_move_offset + elif entry.type == expect_bin_type: + entry.address += rtct_move_offset + # re-calculate checksum + rtct.header.checksum = 0 + rtct.header.checksum = 0 - sum(bytes(rtct)) + +def asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path, scenario_etree, allocation_etree): ''' compile asl code of ACPI table to aml code. :param dest_vm_acpi_path: the path of the asl code of ACPI tables @@ -39,14 +77,20 @@ def asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path): os.remove(os.path.join(dest_vm_acpi_path, acpi_table[1])) rmsg = 'failed to compile {}'.format(acpi_table[0]) break - elif acpi_table[0] == 'PTCT': - if 'PTCT' in os.listdir(dest_vm_acpi_path): - shutil.copyfile(os.path.join(dest_vm_acpi_path, acpi_table[0]), - os.path.join(dest_vm_acpi_bin_path, acpi_table[1])) - elif acpi_table[0] == 'RTCT': - if 'RTCT' in os.listdir(dest_vm_acpi_path): - shutil.copyfile(os.path.join(dest_vm_acpi_path, acpi_table[0]), - os.path.join(dest_vm_acpi_bin_path, acpi_table[1])) + elif acpi_table[0] in ['PTCT', 'RTCT']: + if acpi_table[0] in os.listdir(dest_vm_acpi_path): + rtct = acpiparser.rtct.RTCT(os.path.join(dest_vm_acpi_path, acpi_table[0])) + outfile = os.path.join(dest_vm_acpi_bin_path, acpi_table[1]) + # move the guest ssram area to the area next to ACPI region + pre_rt_vms = common.get_node("//vm[vm_type ='PRE_RT_VM']", scenario_etree) + vm_id = pre_rt_vms.get("id") + allocation_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", allocation_etree) + ssram_start_gpa = common.get_node("./ssram/start_gpa/text()", allocation_vm_node) + ssram_max_size = common.get_node("./ssram/max_size/text()", allocation_vm_node) + move_rtct_ssram_and_bin_entries(rtct, int(ssram_start_gpa, 16), int(ssram_max_size, 16)) + fp = open(outfile, mode='wb') + fp.write(rtct) + fp.close() else: if acpi_table[0].endswith(".asl"): rc = exec_command('iasl {}'.format(acpi_table[0])) @@ -242,7 +286,7 @@ def main(args): dest_vm_acpi_path = os.path.join(DEST_ACPI_PATH, config) dest_vm_acpi_bin_path = os.path.join(DEST_ACPI_BIN_PATH, config) os.makedirs(dest_vm_acpi_bin_path) - if asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path): + if asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path, scenario_etree, allocation_etree): return 1 aml_to_bin(dest_vm_acpi_path, dest_vm_acpi_bin_path, config+'.bin', board_etree, scenario_etree, allocation_etree) diff --git a/misc/config_tools/static_allocators/gpa.py b/misc/config_tools/static_allocators/gpa.py index 64be68f3a..29ea4d139 100644 --- a/misc/config_tools/static_allocators/gpa.py +++ b/misc/config_tools/static_allocators/gpa.py @@ -72,11 +72,15 @@ VMSIX_VBAR_SIZE = 4 * SIZE_K # Constant for VIRT_ACPI_NVS_ADDR """ -VIRT_ACPI_NVS_ADDR needs to be consistant with the layout of hypervisor\arch\x86\guest\ve820.c +VIRT_ACPI_NVS_ADDR, PRE_RTVM_SW_SRAM_BASE_GPA and PRE_RTVM_SW_SRAM_MAX_SIZE +need to be consistant with the layout of hypervisor\arch\x86\guest\ve820.c """ VIRT_ACPI_NVS_ADDR = 0x7FF00000 RESERVED_NVS_AREA = 0xB0000 +PRE_RTVM_SW_SRAM_BASE_GPA = 0x7F5FB000 +PRE_RTVM_SW_SRAM_MAX_SIZE = 0x800000 + class AddrWindow(namedtuple( "AddrWindow", [ "start", @@ -489,8 +493,9 @@ def allocate_ssram_region(board_etree, scenario_etree, allocation_etree): allocation_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", allocation_etree) if allocation_vm_node is None: allocation_vm_node = common.append_node("/acrn-config/vm", None, allocation_etree, id = vm_id) - common.append_node("./ssram/start_gpa", hex(start), allocation_vm_node) - common.append_node("./ssram/end_gpa", hex(end), allocation_vm_node) + common.append_node("./ssram/start_gpa", hex(PRE_RTVM_SW_SRAM_BASE_GPA), allocation_vm_node) + common.append_node("./ssram/end_gpa", hex(PRE_RTVM_SW_SRAM_BASE_GPA + (end - start)), allocation_vm_node) + common.append_node("./ssram/max_size", hex(PRE_RTVM_SW_SRAM_MAX_SIZE), allocation_vm_node) def allocate_log_area(board_etree, scenario_etree, allocation_etree): tpm2_enabled = common.get_node(f"//vm[@id = '0']/mmio_resources/TPM2/text()", scenario_etree) @@ -527,6 +532,8 @@ def pt_dev_io_port_passthrough(board_etree, scenario_etree, allocation_etree): | | Offset 0x80000000 ... ... | TPM2 log area at 0x7FFB0000 | +... ... + | SSRAM area at 0x7F5FB000 | ... ... | | +--------------------------------------------------+ <--Offset 0