[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Add acpi_table_disable() into xen/drivers/acpi/tables.c
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1185791268 -3600 # Node ID c0fbee66aff63978addc5f8b263947553f606d08 # Parent d9c3836e068409ddb7620f7bd5b4c09f16a55f86 Add acpi_table_disable() into xen/drivers/acpi/tables.c This function can disable a ACPI table by updating the table header. Signed-off-by: Akio Takebe <takebe_akio@xxxxxxxxxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/acpi/boot.c | 15 +++- xen/drivers/acpi/tables.c | 143 +++++++++++++++++++++++++++++++++++++++++++++- xen/include/xen/acpi.h | 2 3 files changed, 151 insertions(+), 9 deletions(-) diff -r d9c3836e0684 -r c0fbee66aff6 xen/arch/x86/acpi/boot.c --- a/xen/arch/x86/acpi/boot.c Mon Jul 30 10:59:27 2007 +0100 +++ b/xen/arch/x86/acpi/boot.c Mon Jul 30 11:27:48 2007 +0100 @@ -371,11 +371,18 @@ extern u32 pmtmr_ioport; #ifdef CONFIG_ACPI_SLEEP /* Get pm1x_cnt and pm1x_evt information for ACPI sleep */ -static int __init +static void __init acpi_fadt_parse_sleep_info(struct fadt_descriptor_rev2 *fadt) { + struct acpi_table_rsdp *rsdp; + unsigned long rsdp_phys; struct facs_descriptor_rev2 *facs = NULL; uint64_t facs_pa; + + rsdp_phys = acpi_find_rsdp(); + if (!rsdp_phys || acpi_disabled) + goto bad; + rsdp = __va(rsdp_phys); if (fadt->revision >= FADT2_REVISION_ID) { /* Sanity check on FADT Rev. 2 */ @@ -432,8 +439,7 @@ acpi_fadt_parse_sleep_info(struct fadt_d "FACS is shorter than ACPI spec allow: 0x%x", facs->length); - if ((acpi_rsdp_rev < 2) || - (facs->length < 32)) { + if ((rsdp->revision < 2) || (facs->length < 32)) { acpi_sinfo.wakeup_vector = facs_pa + offsetof(struct facs_descriptor_rev2, firmware_waking_vector); @@ -451,10 +457,9 @@ acpi_fadt_parse_sleep_info(struct fadt_d acpi_sinfo.pm1a_cnt, acpi_sinfo.pm1b_cnt, acpi_sinfo.pm1a_evt, acpi_sinfo.pm1b_cnt, acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width); - return 0; + return; bad: memset(&acpi_sinfo, 0, sizeof(acpi_sinfo)); - return 0; } #endif diff -r d9c3836e0684 -r c0fbee66aff6 xen/drivers/acpi/tables.c --- a/xen/drivers/acpi/tables.c Mon Jul 30 10:59:27 2007 +0100 +++ b/xen/drivers/acpi/tables.c Mon Jul 30 11:27:48 2007 +0100 @@ -73,7 +73,6 @@ struct acpi_table_sdt { static unsigned long sdt_pa; /* Physical Address */ static unsigned long sdt_count; /* Table count */ -unsigned char acpi_rsdp_rev; static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata; @@ -610,8 +609,6 @@ int __init acpi_table_init(void) "RSDP (v%3.3d %6.6s ) @ 0x%p\n", rsdp->revision, rsdp->oem_id, (void *)rsdp_phys); - acpi_rsdp_rev = rsdp->revision; - if (rsdp->revision < 2) result = acpi_table_compute_checksum(rsdp, @@ -634,3 +631,143 @@ int __init acpi_table_init(void) return 0; } + +int __init +acpi_table_disable(enum acpi_table_id table_id) +{ + struct acpi_table_header *header = NULL; + struct acpi_table_rsdp *rsdp; + unsigned long rsdp_phys; + char *table_name; + int id; + + rsdp_phys = acpi_find_rsdp(); + if (!rsdp_phys) + return -ENODEV; + + rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys, + sizeof(struct acpi_table_rsdp)); + if (!rsdp) + return -ENODEV; + + for (id = 0; id < sdt_count; id++) + if (sdt_entry[id].id == table_id) + break; + + if (id == sdt_count) + return -ENOENT; + + table_name = acpi_table_signatures[table_id]; + + /* First check XSDT (but only on ACPI 2.0-compatible systems) */ + + if ((rsdp->revision >= 2) && + (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) { + + struct acpi_table_xsdt *mapped_xsdt = NULL; + + sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + + if (!header) { + printk(KERN_WARNING PREFIX + "Unable to map XSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_xsdt = (struct acpi_table_xsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_xsdt) { + printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); + return -ENODEV; + } + header = &mapped_xsdt->header; + + if (strncmp(header->signature, "XSDT", 4)) { + printk(KERN_WARNING PREFIX + "XSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); + return -ENODEV; + } + + if (id < sdt_count) { + header = (struct acpi_table_header *) + __acpi_map_table(mapped_xsdt->entry[id], sizeof(struct acpi_table_header)); + } else { + printk(KERN_WARNING PREFIX + "Unable to disable entry %d\n", + id); + return -ENODEV; + } + } + + /* Then check RSDT */ + + else if (rsdp->rsdt_address) { + + struct acpi_table_rsdt *mapped_rsdt = NULL; + + sdt_pa = rsdp->rsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + if (!header) { + printk(KERN_WARNING PREFIX + "Unable to map RSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_rsdt = (struct acpi_table_rsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_rsdt) { + printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); + return -ENODEV; + } + header = &mapped_rsdt->header; + + if (strncmp(header->signature, "RSDT", 4)) { + printk(KERN_WARNING PREFIX + "RSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n"); + return -ENODEV; + } + if (id < sdt_count) { + header = (struct acpi_table_header *) + __acpi_map_table(mapped_rsdt->entry[id], sizeof(struct acpi_table_header)); + } else { + printk(KERN_WARNING PREFIX + "Unable to disable entry %d\n", + id); + return -ENODEV; + } + } + + else { + printk(KERN_WARNING PREFIX + "No System Description Table (RSDT/XSDT) specified in RSDP\n"); + return -ENODEV; + } + + memcpy(header->signature, "OEMx", 4); + memcpy(header->oem_id, "xxxxxx", 6); + memcpy(header->oem_id+1, table_name, 4); + memcpy(header->oem_table_id, "Xen ", 8); + header->checksum = 0; + header->checksum = generate_acpi_checksum(header, header->length); + + return 0; +} diff -r d9c3836e0684 -r c0fbee66aff6 xen/include/xen/acpi.h --- a/xen/include/xen/acpi.h Mon Jul 30 10:59:27 2007 +0100 +++ b/xen/include/xen/acpi.h Mon Jul 30 11:27:48 2007 +0100 @@ -383,6 +383,7 @@ int acpi_numa_init (void); int acpi_numa_init (void); int acpi_table_init (void); +int acpi_table_disable(enum acpi_table_id table_id); int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler); int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); @@ -535,6 +536,5 @@ static inline int acpi_get_pxm(acpi_hand #endif extern int pnpacpi_disabled; -extern unsigned char acpi_rsdp_rev; #endif /*_LINUX_ACPI_H*/ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |