Skip to content

Commit

Permalink
acpi: track vaddr of ACPI tables
Browse files Browse the repository at this point in the history
Previously, the physical address of the ACPI tables were being
tracked. This caused a Linux error while parsing the ACPI tables. Since
Linux does not have access to those memory regions, they would appear
empty, causing an Invalid Table Length bug print. By tracking the
virtual address that Linux expects and placing the vaddr into the ACPI
tables, Linux can parse the tables properly.

Signed-off-by: Chris Guikema <[email protected]>
  • Loading branch information
chrisguikema authored and abrandnewusername committed May 2, 2023
1 parent 779bd6d commit 0f67bde
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions libsel4vmmplatsupport/src/arch/x86/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,16 +257,19 @@ int make_guest_acpi_tables(vm_t *vm)
}

uintptr_t xsdt_addr = lower_bios_addr + (XSDT_START - LOWER_BIOS_START);
uintptr_t xsdt_vaddr = XSDT_START;

acpi_xsdt_t *xsdt = calloc(1, xsdt_size);
acpi_fill_table_head(&xsdt->header, "XSDT", 1);

// Add previous tables to XSDT pointer list
uintptr_t table_paddr = xsdt_addr + xsdt_size;
uintptr_t table_vaddr = xsdt_vaddr + xsdt_size;
uint64_t *entry = (uint64_t *)((char *)xsdt + sizeof(acpi_xsdt_t));
for (int i = 1; i < num_tables; i++) {
*entry++ = (uint64_t)table_paddr;
*entry++ = (uint64_t)table_vaddr;
table_paddr += table_sizes[i];
table_vaddr += table_sizes[i];
}

xsdt->header.length = xsdt_size;
Expand All @@ -277,19 +280,21 @@ int make_guest_acpi_tables(vm_t *vm)

// Copy all the tables to guest
table_paddr = xsdt_addr;
table_vaddr = xsdt_vaddr;
for (int i = 0; i < num_tables; i++) {

// Need to fill in DSDT address
if (i == fadt_index) {
fadt->dsdt_address = table_paddr - table_sizes[dsdt_index];
fadt->x_dsdt_address = table_paddr - table_sizes[dsdt_index];
fadt->dsdt_address = table_vaddr - table_sizes[dsdt_index];
fadt->x_dsdt_address = table_vaddr - table_sizes[dsdt_index];
fadt->header.checksum = acpi_calc_checksum((char *)fadt, fadt_size);
}

ZF_LOGD("ACPI table \"%.4s\", addr = %p, size = %zu bytes\n",
(char *)tables[i], (void *)table_paddr, table_sizes[i]);
(char *)tables[i], (void *)table_vaddr, table_sizes[i]);
memcpy((void *)table_paddr, (char *)tables[i], table_sizes[i]);
table_paddr += table_sizes[i];
table_vaddr += table_sizes[i];
}

// RSDP
Expand All @@ -299,11 +304,11 @@ int make_guest_acpi_tables(vm_t *vm)
.oem_id = "NICTA ",
.revision = 2, /* ACPI v3*/
.checksum = 0,
.rsdt_address = xsdt_addr,
.rsdt_address = xsdt_vaddr,
/* rsdt_addrss will not be inspected as the xsdt is present.
This is not ACPI 1 compliant */
.length = sizeof(acpi_rsdp_t),
.xsdt_address = xsdt_addr,
.xsdt_address = xsdt_vaddr,
.extended_checksum = 0,
.reserved = {0}
};
Expand Down

0 comments on commit 0f67bde

Please sign in to comment.