|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC XEN PATCH v4 37/41] tools/libacpi: load QEMU ACPI
If libacpi detects QEMU fw_cfg interface, it will try to detect and
execute QEMU BIOSLinkerLoader ROM to load QEMU-built ACPI. If any QEMU
ACPI table is conflict with Xen-built ACPI tables, libacpi will refuse
to load all QEMU ACPI tables.
Signed-off-by: Haozhong Zhang <haozhong.zhang@xxxxxxxxx>
---
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
---
tools/libacpi/acpi2_0.h | 1 +
tools/libacpi/build.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+)
diff --git a/tools/libacpi/acpi2_0.h b/tools/libacpi/acpi2_0.h
index 2619ba32db..733bed684e 100644
--- a/tools/libacpi/acpi2_0.h
+++ b/tools/libacpi/acpi2_0.h
@@ -435,6 +435,7 @@ struct acpi_20_slit {
#define ACPI_2_0_WAET_SIGNATURE ASCII32('W','A','E','T')
#define ACPI_2_0_SRAT_SIGNATURE ASCII32('S','R','A','T')
#define ACPI_2_0_SLIT_SIGNATURE ASCII32('S','L','I','T')
+#define ACPI_2_0_SSDT_SIGNATURE ASCII32('S','S','D','T')
/*
* Table revision numbers.
diff --git a/tools/libacpi/build.c b/tools/libacpi/build.c
index f2d65574ff..32405a4c77 100644
--- a/tools/libacpi/build.c
+++ b/tools/libacpi/build.c
@@ -16,6 +16,7 @@
#include LIBACPI_STDUTILS
#include "acpi2_0.h"
#include "libacpi.h"
+#include "qemu.h"
#include "ssdt_s3.h"
#include "ssdt_s4.h"
#include "ssdt_tpm.h"
@@ -105,6 +106,18 @@ static int dm_acpi_blacklist_signature(struct acpi_config
*config, uint64_t sig)
return 0;
}
+/* Return true if no collision is found. */
+static bool dm_acpi_check_signature_collision(uint64_t sig)
+{
+ unsigned int i;
+
+ for ( i = 0; i < NR_SIGNATURE_BLACKLIST_ENTS; i++ )
+ if ( sig == dm_acpi_signature_blacklist[i] )
+ return false;
+
+ return true;
+}
+
void set_checksum(void *table, uint32_t checksum_offset, uint32_t length)
{
uint8_t *p, sum = 0;
@@ -388,6 +401,94 @@ static int construct_passthrough_tables(struct acpi_ctxt
*ctxt,
return nr_added;
}
+static int load_qemu_xen_tables(struct acpi_ctxt *ctxt,
+ unsigned long *table_ptrs,
+ int nr_tables,
+ struct acpi_config *config)
+{
+ struct acpi_header *header;
+ struct acpi_20_rsdp *rsdp;
+ struct acpi_20_rsdt *rsdt;
+ uint32_t table_paddr, sig;
+ unsigned int nr_added = 0, nr_rsdt_ents;
+
+ printf("Loading QEMU ACPI tables ...\n");
+
+ if ( fw_cfg_probe_roms(ctxt) )
+ return 0;
+
+ if ( loader_exec(ctxt) )
+ return 0;
+
+ rsdp = loader_get_rsdp();
+ if ( !rsdp )
+ {
+ printf("Cannot find QEMU RSDP\n");
+ return 0;
+ }
+
+ rsdt = (struct acpi_20_rsdt *)ctxt->mem_ops.p2v(ctxt, rsdp->rsdt_address);
+
+ nr_rsdt_ents =
+ (rsdt->header.length - sizeof(struct acpi_header)) / sizeof(uint32_t);
+ if ( nr_rsdt_ents > ACPI_MAX_SECONDARY_TABLES - nr_tables )
+ {
+ printf("Too many tables in QEMU ACPI tables\n");
+ goto exit;
+ }
+
+ for ( nr_added = 0; nr_added < nr_rsdt_ents; nr_added++ )
+ {
+ table_paddr = rsdt->entry[nr_added];
+ header = ctxt->mem_ops.p2v(ctxt, table_paddr);
+ sig = header->signature;
+
+ if ( !dm_acpi_check_signature_collision(sig) )
+ {
+ printf("QEMU ACPI table conflict with Xen ACPI table '%c%c%c%c'\n",
+ (char)(sig & 0xff),
+ (char)((sig >> 8) & 0xff),
+ (char)((sig >> 16) & 0xff),
+ (char)((sig >> 24) & 0xff));
+ break;
+ }
+
+ if ( sig != ACPI_2_0_SSDT_SIGNATURE )
+ dm_acpi_blacklist_signature(config, sig);
+
+ table_ptrs[nr_tables++] = table_paddr;
+ }
+
+ if ( nr_added < nr_rsdt_ents )
+ while ( nr_added )
+ {
+ table_ptrs[--nr_tables] = 0;
+ nr_added--;
+ }
+
+exit:
+ /* Cleanup unused QEMU RSDP & RSDT. */
+ memset(rsdp, 0,
+ rsdp->revision == ACPI_2_0_RSDP_REVISION ?
+ rsdp->length : sizeof(struct acpi_10_rsdp));
+ memset(rsdt, 0, rsdt->header.length);
+
+ return nr_added;
+}
+
+static int construct_dm_acpi_tables(struct acpi_ctxt *ctxt,
+ unsigned long *table_ptrs,
+ int nr_tables,
+ struct acpi_config *config)
+{
+ int nr_added = 0;
+
+ if ( config->table_flags & ACPI_HAS_QEMU_XEN )
+ nr_added += load_qemu_xen_tables(ctxt, table_ptrs, nr_tables, config);
+
+ return nr_added;
+}
+
static int construct_secondary_tables(struct acpi_ctxt *ctxt,
unsigned long *table_ptrs,
struct acpi_config *config,
@@ -530,6 +631,10 @@ static int construct_secondary_tables(struct acpi_ctxt
*ctxt,
nr_tables += construct_passthrough_tables(ctxt, table_ptrs,
nr_tables, config);
+ /* Load ACPI built by device model */
+ if ( config->table_flags & ACPI_HAS_DM )
+ nr_tables += construct_dm_acpi_tables(ctxt, table_ptrs,
+ nr_tables, config);
table_ptrs[nr_tables] = 0;
return nr_tables;
--
2.15.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |