In case a xsdt table is present (and located below 4G) prefer it over rsdt.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/std/acpi.h | 11 +++++++++++ src/fw/biostables.c | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/src/std/acpi.h b/src/std/acpi.h index c01fa7be827c..81c22757f50e 100644 --- a/src/std/acpi.h +++ b/src/std/acpi.h @@ -132,6 +132,17 @@ struct rsdt_descriptor_rev1 /* ACPI tables */ } PACKED;
+/* + * ACPI 2.0 eXtended System Description Table (XSDT) + */ +#define XSDT_SIGNATURE 0x54445358 // XSDT +struct xsdt_descriptor_rev2 +{ + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ + u64 table_offset_entry[0]; /* Array of pointers to other */ + /* ACPI tables */ +} PACKED; + /* * ACPI 1.0 Firmware ACPI Control Structure (FACS) */ diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626efc05d..0d4fdb9c22e8 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -141,18 +141,38 @@ find_acpi_table(u32 signature) if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE) return NULL; struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address; + struct xsdt_descriptor_rev2 *xsdt = + RsdpAddr->xsdt_physical_address >= 0x100000000 + ? NULL : (void*)(u32)(RsdpAddr->xsdt_physical_address); dprintf(4, "rsdt=%p\n", rsdt); - if (!rsdt || rsdt->signature != RSDT_SIGNATURE) - return NULL; - void *end = (void*)rsdt + rsdt->length; - int i; - for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) { - struct acpi_table_header *tbl = (void*)rsdt->table_offset_entry[i]; - if (!tbl || tbl->signature != signature) - continue; - dprintf(4, "table(%x)=%p\n", signature, tbl); - return tbl; + dprintf(4, "xsdt=%p\n", xsdt); + + if (xsdt && xsdt->signature == XSDT_SIGNATURE) { + void *end = (void*)xsdt + xsdt->length; + int i; + for (i=0; (void*)&xsdt->table_offset_entry[i] < end; i++) { + if (xsdt->table_offset_entry[i] >= 0x100000000) + continue; /* above 4G */ + struct acpi_table_header *tbl = (void*)(u32)xsdt->table_offset_entry[i]; + if (!tbl || tbl->signature != signature) + continue; + dprintf(1, "table(%x)=%p (via xsdt)\n", signature, tbl); + return tbl; + } } + + if (rsdt && rsdt->signature == RSDT_SIGNATURE) { + void *end = (void*)rsdt + rsdt->length; + int i; + for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) { + struct acpi_table_header *tbl = (void*)rsdt->table_offset_entry[i]; + if (!tbl || tbl->signature != signature) + continue; + dprintf(1, "table(%x)=%p (via rsdt)\n", signature, tbl); + return tbl; + } + } + dprintf(4, "no table %x found\n", signature); return NULL; }
On Fri, 27 Mar 2020 09:24:10 +0100 Gerd Hoffmann kraxel@redhat.com wrote:
In case a xsdt table is present (and located below 4G) prefer it over rsdt.
not related to this patch, but in connection to supporting HW reduced profile, check places that use FADT. i.e. * check for newer FADT revision * skip pm timer init if hw reduced flag is set * not sure what to do but there isn't FACS in hw reduced so we might need something else in find_resume_vector()
Signed-off-by: Gerd Hoffmann kraxel@redhat.com
src/std/acpi.h | 11 +++++++++++ src/fw/biostables.c | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/src/std/acpi.h b/src/std/acpi.h index c01fa7be827c..81c22757f50e 100644 --- a/src/std/acpi.h +++ b/src/std/acpi.h @@ -132,6 +132,17 @@ struct rsdt_descriptor_rev1 /* ACPI tables */ } PACKED;
+/*
- ACPI 2.0 eXtended System Description Table (XSDT)
- */
+#define XSDT_SIGNATURE 0x54445358 // XSDT +struct xsdt_descriptor_rev2 +{
- ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- u64 table_offset_entry[0]; /* Array of pointers to other */
- /* ACPI tables */
+} PACKED;
/*
- ACPI 1.0 Firmware ACPI Control Structure (FACS)
*/ diff --git a/src/fw/biostables.c b/src/fw/biostables.c index fe8626efc05d..0d4fdb9c22e8 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -141,18 +141,38 @@ find_acpi_table(u32 signature) if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE) return NULL; struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address;
- struct xsdt_descriptor_rev2 *xsdt =
RsdpAddr->xsdt_physical_address >= 0x100000000
dprintf(4, "rsdt=%p\n", rsdt);? NULL : (void*)(u32)(RsdpAddr->xsdt_physical_address);
- if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
return NULL;
- void *end = (void*)rsdt + rsdt->length;
- int i;
- for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
struct acpi_table_header *tbl = (void*)rsdt->table_offset_entry[i];
if (!tbl || tbl->signature != signature)
continue;
dprintf(4, "table(%x)=%p\n", signature, tbl);
return tbl;
- dprintf(4, "xsdt=%p\n", xsdt);
- if (xsdt && xsdt->signature == XSDT_SIGNATURE) {
void *end = (void*)xsdt + xsdt->length;
int i;
for (i=0; (void*)&xsdt->table_offset_entry[i] < end; i++) {
if (xsdt->table_offset_entry[i] >= 0x100000000)
continue; /* above 4G */
can it print a error in such cases, so that user could see that there are unsupported tables in used machine?
struct acpi_table_header *tbl = (void*)(u32)xsdt->table_offset_entry[i];
if (!tbl || tbl->signature != signature)
continue;
dprintf(1, "table(%x)=%p (via xsdt)\n", signature, tbl);
return tbl;
}}
- if (rsdt && rsdt->signature == RSDT_SIGNATURE) {
void *end = (void*)rsdt + rsdt->length;
int i;
for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
struct acpi_table_header *tbl = (void*)rsdt->table_offset_entry[i];
if (!tbl || tbl->signature != signature)
continue;
dprintf(1, "table(%x)=%p (via rsdt)\n", signature, tbl);
return tbl;
}
- }
- dprintf(4, "no table %x found\n", signature); return NULL;
}
On Fri, Mar 27, 2020 at 04:05:56PM +0100, Igor Mammedov wrote:
On Fri, 27 Mar 2020 09:24:10 +0100 Gerd Hoffmann kraxel@redhat.com wrote:
In case a xsdt table is present (and located below 4G) prefer it over rsdt.
not related to this patch, but in connection to supporting HW reduced profile, check places that use FADT. i.e.
- check for newer FADT revision
- skip pm timer init if hw reduced flag is set
seabios doesn't look at acpi tables to find pm timer. It depends on acpi pci devices instead, i.e. on microvm seabios doesn't use pmtimer anyway.
- not sure what to do but there isn't FACS in hw reduced so we might need something else in find_resume_vector()
microvm doesn't support S3/S4, I don't think seabios will ever need a resume vector ...
cheers, Gerd