[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 |