[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Pull in ACPI table parsing code from Linux 2.6.26-rc4.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1213101929 -3600 # Node ID 9af7a535225f3924b8b5c8acfd362a2e6bffc3d0 # Parent 7a0f1bf865160893b6fcb085abf2b518a0d69af7 Pull in ACPI table parsing code from Linux 2.6.26-rc4. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/drivers/acpi/utglobal.c | 136 ---- xen/arch/ia64/xen/acpi.c | 36 - xen/arch/ia64/xen/dom_fw_dom0.c | 65 +- xen/arch/x86/acpi/boot.c | 114 +-- xen/drivers/acpi/Makefile | 4 xen/drivers/acpi/numa.c | 54 - xen/drivers/acpi/osl.c | 35 + xen/drivers/acpi/tables.c | 773 +++++--------------------- xen/drivers/acpi/tables/Makefile | 5 xen/drivers/acpi/tables/tbfadt.c | 458 +++++++++++++++ xen/drivers/acpi/tables/tbinstal.c | 150 +++++ xen/drivers/acpi/tables/tbutils.c | 560 ++++++++++++++++++ xen/drivers/acpi/tables/tbxface.c | 261 ++++++++ xen/drivers/acpi/tables/tbxfroot.c | 275 +++++++++ xen/drivers/acpi/utilities/Makefile | 2 xen/drivers/acpi/utilities/utglobal.c | 740 ++++++++++++++++++++++++ xen/drivers/acpi/utilities/utmisc.c | 229 +++++++ xen/drivers/passthrough/amd/iommu_acpi.c | 5 xen/drivers/passthrough/amd/pci_amd_iommu.c | 2 xen/drivers/passthrough/vtd/dmar.c | 21 xen/include/acpi/acnamesp.h | 305 ++++++++++ xen/include/acpi/actables.h | 118 +++ xen/include/acpi/platform/aclinux.h | 64 -- xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 2 xen/include/xen/acpi.h | 79 -- xen/include/xen/compiler.h | 6 26 files changed, 3439 insertions(+), 1060 deletions(-) diff -r 7a0f1bf86516 -r 9af7a535225f xen/arch/ia64/xen/acpi.c --- a/xen/arch/ia64/xen/acpi.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/arch/ia64/xen/acpi.c Tue Jun 10 13:45:29 2008 +0100 @@ -58,7 +58,7 @@ #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) + ((struct acpi_subtable_header *)entry)->length != sizeof(*entry)) #define PREFIX "ACPI: " @@ -167,7 +167,7 @@ static u8 has_8259; static int __init acpi_parse_lapic_addr_ovr ( - acpi_table_entry_header *header, const unsigned long end) + struct acpi_subtable_header *header, const unsigned long end) { struct acpi_table_lapic_addr_ovr *lapic; @@ -187,7 +187,7 @@ acpi_parse_lapic_addr_ovr ( static int __init -acpi_parse_lsapic (acpi_table_entry_header *header, const unsigned long end) +acpi_parse_lsapic (struct acpi_subtable_header *header, const unsigned long end) { struct acpi_table_lsapic *lsapic; @@ -227,7 +227,7 @@ acpi_parse_lsapic (acpi_table_entry_head static int __init -acpi_parse_lapic_nmi (acpi_table_entry_header *header, const unsigned long end) +acpi_parse_lapic_nmi (struct acpi_subtable_header *header, const unsigned long end) { struct acpi_table_lapic_nmi *lacpi_nmi; @@ -244,7 +244,7 @@ acpi_parse_lapic_nmi (acpi_table_entry_h static int __init -acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) +acpi_parse_iosapic (struct acpi_subtable_header *header, const unsigned long end) { struct acpi_table_iosapic *iosapic; @@ -262,7 +262,7 @@ acpi_parse_iosapic (acpi_table_entry_hea static int __init acpi_parse_plat_int_src ( - acpi_table_entry_header *header, const unsigned long end) + struct acpi_subtable_header *header, const unsigned long end) { struct acpi_table_plat_int_src *plintsrc; int vector; @@ -293,7 +293,7 @@ acpi_parse_plat_int_src ( static int __init acpi_parse_int_src_ovr ( - acpi_table_entry_header *header, const unsigned long end) + struct acpi_subtable_header *header, const unsigned long end) { struct acpi_table_int_src_ovr *p; @@ -311,7 +311,7 @@ acpi_parse_int_src_ovr ( } static int __init -acpi_parse_nmi_src (acpi_table_entry_header *header, const unsigned long end) +acpi_parse_nmi_src (struct acpi_subtable_header *header, const unsigned long end) { struct acpi_table_nmi_src *nmi_src; @@ -345,12 +345,9 @@ void __init acpi_madt_oem_check(char *oe } static int __init -acpi_parse_madt (unsigned long phys_addr, unsigned long size) -{ - if (!phys_addr || !size) - return -EINVAL; - - acpi_madt = (struct acpi_table_madt *) __va(phys_addr); +acpi_parse_madt (struct acpi_table_header *table) +{ + acpi_madt = (struct acpi_table_madt *)table; /* remember the value for reference after free_initmem() */ #ifdef CONFIG_ITANIUM @@ -560,15 +557,12 @@ EXPORT_SYMBOL(acpi_register_gsi); EXPORT_SYMBOL(acpi_register_gsi); #endif static int __init -acpi_parse_fadt (unsigned long phys_addr, unsigned long size) +acpi_parse_fadt (struct acpi_table_header *table) { struct acpi_table_header *fadt_header; struct acpi_table_fadt *fadt; - if (!phys_addr || !size) - return -EINVAL; - - fadt_header = (struct acpi_table_header *) __va(phys_addr); + fadt_header = (struct acpi_table_header *)table; if (fadt_header->revision != 3) return -ENODEV; /* Only deal with ACPI 2.0 FADT */ @@ -610,7 +604,7 @@ acpi_boot_init (void) * information -- the successor to MPS tables. */ - if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) { + if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { printk(KERN_ERR PREFIX "Can't find MADT\n"); goto skip_madt; } @@ -649,7 +643,7 @@ acpi_boot_init (void) * gets interrupts such as power and sleep buttons. If it's not * on a Legacy interrupt, it needs to be setup. */ - if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1) + if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) printk(KERN_ERR PREFIX "Can't find FADT\n"); #ifdef CONFIG_SMP diff -r 7a0f1bf86516 -r 9af7a535225f xen/arch/ia64/xen/dom_fw_dom0.c --- a/xen/arch/ia64/xen/dom_fw_dom0.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/arch/ia64/xen/dom_fw_dom0.c Tue Jun 10 13:45:29 2008 +0100 @@ -50,7 +50,7 @@ static u32 lsapic_nbr; /* Modify lsapic table. Provides LPs. */ static int __init -acpi_update_lsapic(acpi_table_entry_header * header, const unsigned long end) +acpi_update_lsapic(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_lsapic *lsapic; int enable; @@ -79,7 +79,7 @@ acpi_update_lsapic(acpi_table_entry_head } static int __init -acpi_patch_plat_int_src(acpi_table_entry_header * header, +acpi_patch_plat_int_src(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_plat_int_src *plintsrc; @@ -96,14 +96,11 @@ acpi_patch_plat_int_src(acpi_table_entry } static int __init -acpi_update_madt_checksum(unsigned long phys_addr, unsigned long size) +acpi_update_madt_checksum(struct acpi_table_header *table) { struct acpi_table_madt *acpi_madt; - if (!phys_addr || !size) - return -EINVAL; - - acpi_madt = (struct acpi_table_madt *)__va(phys_addr); + acpi_madt = (struct acpi_table_madt *)table; acpi_madt->header.checksum = 0; acpi_madt->header.checksum = generate_acpi_checksum(acpi_madt, size); @@ -111,32 +108,26 @@ acpi_update_madt_checksum(unsigned long } static int __init -acpi_backup_table(unsigned long phys_addr, unsigned long size) +acpi_backup_table(struct acpi_table_header *table) { struct acpi_backup_table_entry *entry; - void *vaddr = __va(phys_addr); - - if (!phys_addr || !size) - return -EINVAL; - - entry = xmalloc_bytes(sizeof(*entry) + size); + + entry = xmalloc_bytes(sizeof(*entry) + table->length); if (!entry) { dprintk(XENLOG_WARNING, "Failed to allocate memory for " - "%.4s table backup\n", - ((struct acpi_table_header *)vaddr)->signature); + "%.4s table backup\n", table->signature); return -ENOMEM; } - entry->pa = phys_addr; - entry->size = size; - - memcpy(entry->data, vaddr, size); + entry->pa = __pa(table); + entry->size = table->length; + + memcpy(entry->data, table, table->length); list_add(&entry->list, &acpi_backup_table_list); printk(XENLOG_INFO "Backup %.4s table stored @0x%p\n", - ((struct acpi_table_header *)entry->data)->signature, - entry->data); + table->signature, entry->data); return 0; } @@ -154,6 +145,22 @@ acpi_restore_tables() memcpy(__va(entry->pa), entry->data, entry->size); /* Only called from kexec path, no need to free entries */ } +} + +static int __init __acpi_table_disable(struct acpi_table_header *header) +{ + memcpy(header->oem_id, "xxxxxx", 6); + memcpy(header->oem_id+1, header->signature, 4); + memcpy(header->oem_table_id, "Xen ", 8); + memcpy(header->signature, "OEMx", 4); + header->checksum = 0; + header->checksum = generate_acpi_checksum(header, header->length); + return 0; +} + +static void __init acpi_table_disable(char *id) +{ + acpi_table_parse(id, __acpi_table_disable); } /* base is physical address of acpi table */ @@ -170,7 +177,7 @@ static void __init touch_acpi_table(void * * ACPI tables must be backed-up before modification! */ - acpi_table_parse(ACPI_APIC, acpi_backup_table); + acpi_table_parse(ACPI_SIG_MADT, acpi_backup_table); if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0) printk("Error parsing MADT - no LAPIC entries\n"); @@ -178,7 +185,7 @@ static void __init touch_acpi_table(void acpi_patch_plat_int_src, 0) < 0) printk("Error parsing MADT - no PLAT_INT_SRC entries\n"); - acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum); + acpi_table_parse(ACPI_SIG_MADT, acpi_update_madt_checksum); /* * SRAT & SLIT tables aren't useful for Dom0 until @@ -186,16 +193,16 @@ static void __init touch_acpi_table(void * * NB - backup ACPI tables first. */ - acpi_table_parse(ACPI_SRAT, acpi_backup_table); - acpi_table_parse(ACPI_SLIT, acpi_backup_table); - - result = acpi_table_disable(ACPI_SRAT); + acpi_table_parse(ACPI_SIG_SRAT, acpi_backup_table); + acpi_table_parse(ACPI_SIG_SLIT, acpi_backup_table); + + result = acpi_table_disable(ACPI_SIG_SRAT); if ( result == 0 ) printk("Success Disabling SRAT\n"); else if ( result != -ENOENT ) printk("ERROR: Failed Disabling SRAT\n"); - result = acpi_table_disable(ACPI_SLIT); + result = acpi_table_disable(ACPI_SIG_SLIT); if ( result == 0 ) printk("Success Disabling SLIT\n"); else if ( result != -ENOENT ) diff -r 7a0f1bf86516 -r 9af7a535225f xen/arch/x86/acpi/boot.c --- a/xen/arch/x86/acpi/boot.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/arch/x86/acpi/boot.c Tue Jun 10 13:45:29 2008 +0100 @@ -45,7 +45,7 @@ int sbf_port; #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) + ((struct acpi_subtable_header *)entry)->length != sizeof(*entry)) #define PREFIX "ACPI: " @@ -111,7 +111,7 @@ char *__acpi_map_table(unsigned long phy int idx; /* XEN: RAM holes above 1MB are not permanently mapped. */ - if (phys + size < 1 * 1024 * 1024) + if ((phys + size) <= (1 * 1024 * 1024)) return __va(phys); offset = phys & (PAGE_SIZE - 1); @@ -135,18 +135,11 @@ char *__acpi_map_table(unsigned long phy } #ifdef CONFIG_X86_LOCAL_APIC -static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) -{ - struct acpi_table_madt *madt = NULL; - - if (!phys_addr || !size) - return -EINVAL; - - madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); - if (!madt) { - printk(KERN_WARNING PREFIX "Unable to map MADT\n"); - return -ENODEV; - } +static int __init acpi_parse_madt(struct acpi_table_header *table) +{ + struct acpi_table_madt *madt; + + madt = (struct acpi_table_madt *)table; if (madt->address) { acpi_lapic_addr = (u64) madt->address; @@ -161,7 +154,7 @@ static int __init acpi_parse_madt(unsign } static int __init -acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_lapic *processor = NULL; @@ -190,7 +183,7 @@ acpi_parse_lapic(acpi_table_entry_header } static int __init -acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, +acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; @@ -206,7 +199,7 @@ acpi_parse_lapic_addr_ovr(acpi_table_ent } static int __init -acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_lapic_nmi *lapic_nmi = NULL; @@ -228,7 +221,7 @@ acpi_parse_lapic_nmi(acpi_table_entry_he #if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/ static int __init -acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_ioapic *ioapic = NULL; @@ -246,7 +239,7 @@ acpi_parse_ioapic(acpi_table_entry_heade } static int __init -acpi_parse_int_src_ovr(acpi_table_entry_header * header, +acpi_parse_int_src_ovr(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_int_src_ovr *intsrc = NULL; @@ -272,7 +265,7 @@ acpi_parse_int_src_ovr(acpi_table_entry_ } static int __init -acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_nmi_src *nmi_src = NULL; @@ -309,38 +302,26 @@ acpi_scan_rsdp(unsigned long start, unsi return 0; } -static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) -{ - struct acpi_table_sbf *sb; - - if (!phys_addr || !size) - return -EINVAL; - - sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); +static int __init acpi_parse_sbf(struct acpi_table_header *table) +{ + struct acpi_table_boot *sb; + + sb = (struct acpi_table_boot *)table; if (!sb) { printk(KERN_WARNING PREFIX "Unable to map SBF\n"); return -ENODEV; } - sbf_port = sb->sbf_cmos; /* Save CMOS port */ + sbf_port = sb->cmos_index; /* Save CMOS port */ return 0; } #ifdef CONFIG_HPET_TIMER -static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) -{ - struct acpi_table_hpet *hpet_tbl; - - if (!phys || !size) - return -EINVAL; - - hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size); - if (!hpet_tbl) { - printk(KERN_WARNING PREFIX "Unable to map HPET\n"); - return -ENODEV; - } +static int __init acpi_parse_hpet(struct acpi_table_header *table) +{ + struct acpi_table_hpet *hpet_tbl = (struct acpi_table_hpet *)table; if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { printk(KERN_WARNING PREFIX "HPET timers must be located in " @@ -454,37 +435,9 @@ bad: } #endif -static void __init -acpi_fadt_parse_reg(struct acpi_table_fadt *fadt) -{ - unsigned int len; - - len = min_t(unsigned int, fadt->header.length, sizeof(*fadt)); - memcpy(&acpi_gbl_FADT, fadt, len); - - if (len > offsetof(struct acpi_table_fadt, xpm1b_event_block)) { - memcpy(&acpi_gbl_xpm1a_enable, &fadt->xpm1a_event_block, - sizeof(acpi_gbl_xpm1a_enable)); - memcpy(&acpi_gbl_xpm1b_enable, &fadt->xpm1b_event_block, - sizeof(acpi_gbl_xpm1b_enable)); - - acpi_gbl_xpm1a_enable.address += - acpi_gbl_FADT.pm1_event_length / 2; - if ( acpi_gbl_xpm1b_enable.address ) - acpi_gbl_xpm1b_enable.address += - acpi_gbl_FADT.pm1_event_length / 2; - } -} - -static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) -{ - struct acpi_table_fadt *fadt = NULL; - - fadt = (struct acpi_table_fadt *)__acpi_map_table(phys, size); - if (!fadt) { - printk(KERN_WARNING PREFIX "Unable to map FADT\n"); - return 0; - } +static int __init acpi_parse_fadt(struct acpi_table_header *table) +{ + struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; #ifdef CONFIG_ACPI_INTERPRETER /* initialize sci_int early for INT_SRC_OVR MADT parsing */ @@ -523,8 +476,6 @@ static int __init acpi_parse_fadt(unsign acpi_enable_value = fadt->acpi_enable; acpi_disable_value = fadt->acpi_disable; - acpi_fadt_parse_reg(fadt); - #ifdef CONFIG_ACPI_SLEEP acpi_fadt_parse_sleep_info(fadt); #endif @@ -692,10 +643,9 @@ static void __init acpi_process_madt(voi static void __init acpi_process_madt(void) { #ifdef CONFIG_X86_LOCAL_APIC - int count, error; - - count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); - if (count >= 1) { + int error; + + if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { /* * Parse MADT LAPIC entries @@ -990,7 +940,7 @@ int __init acpi_boot_table_init(void) return error; } - acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); /* * blacklist may disable ACPI entirely @@ -1020,19 +970,19 @@ int __init acpi_boot_init(void) if (acpi_disabled && !acpi_ht) return 1; - acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); /* * set sci_int and PM timer address */ - acpi_table_parse(ACPI_FADT, acpi_parse_fadt); + acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt); /* * Process the Multiple APIC Description Table (MADT), if present */ acpi_process_madt(); - acpi_table_parse(ACPI_HPET, acpi_parse_hpet); + acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); acpi_dmar_init(); diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/Makefile --- a/xen/drivers/acpi/Makefile Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/drivers/acpi/Makefile Tue Jun 10 13:45:29 2008 +0100 @@ -1,6 +1,8 @@ obj-y += tables.o +subdir-y += tables +subdir-y += utilities + obj-y += tables.o obj-y += numa.o obj-y += osl.o obj-$(x86) += hwregs.o -obj-$(x86) += utglobal.o diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/numa.c --- a/xen/drivers/acpi/numa.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/drivers/acpi/numa.c Tue Jun 10 13:45:29 2008 +0100 @@ -35,13 +35,7 @@ #define _COMPONENT ACPI_NUMA ACPI_MODULE_NAME("numa") -extern int __init acpi_table_parse_madt_family(enum acpi_table_id id, - unsigned long madt_size, - int entry_id, - acpi_madt_entry_handler handler, - unsigned int max_entries); - -void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) +void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) { ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); @@ -93,26 +87,15 @@ void __init acpi_table_print_srat_entry( } } -static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size) +static int __init acpi_parse_slit(struct acpi_table_header *table) { - struct acpi_table_slit *slit; - u32 localities; - - if (!phys_addr || !size) - return -EINVAL; - - slit = (struct acpi_table_slit *)__acpi_map_table(phys_addr, size); - - /* downcast just for %llu vs %lu for i386/ia64 */ - localities = (u32) slit->locality_count; - - acpi_numa_slit_init(slit); + acpi_numa_slit_init((struct acpi_table_slit *)table); return 0; } static int __init -acpi_parse_processor_affinity(acpi_table_entry_header * header, +acpi_parse_processor_affinity(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_processor_affinity *processor_affinity; @@ -130,7 +113,7 @@ acpi_parse_processor_affinity(acpi_table } static int __init -acpi_parse_memory_affinity(acpi_table_entry_header * header, +acpi_parse_memory_affinity(struct acpi_subtable_header * header, const unsigned long end) { struct acpi_table_memory_affinity *memory_affinity; @@ -147,15 +130,8 @@ acpi_parse_memory_affinity(acpi_table_en return 0; } -static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size) +static int __init acpi_parse_srat(struct acpi_table_header *table) { - struct acpi_table_srat *srat; - - if (!phys_addr || !size) - return -EINVAL; - - srat = (struct acpi_table_srat *)__acpi_map_table(phys_addr, size); - return 0; } @@ -163,27 +139,23 @@ acpi_table_parse_srat(enum acpi_srat_ent acpi_table_parse_srat(enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries) { - return acpi_table_parse_madt_family(ACPI_SRAT, - sizeof(struct acpi_table_srat), id, - handler, max_entries); + return acpi_table_parse_entries(ACPI_SIG_SRAT, + sizeof(struct acpi_table_srat), id, + handler, max_entries); } int __init acpi_numa_init(void) { - int result; - /* SRAT: Static Resource Affinity Table */ - result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat); - - if (result > 0) { - result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, + if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { + acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, acpi_parse_processor_affinity, NR_CPUS); - result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific + acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific } /* SLIT: System Locality Information Table */ - result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit); + acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); acpi_numa_arch_fixup(); return 0; diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/osl.c --- a/xen/drivers/acpi/osl.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/drivers/acpi/osl.c Tue Jun 10 13:45:29 2008 +0100 @@ -63,6 +63,41 @@ int acpi_specific_hotkey_enabled = TRUE; int acpi_specific_hotkey_enabled = TRUE; EXPORT_SYMBOL(acpi_specific_hotkey_enabled); +void acpi_os_printf(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + acpi_os_vprintf(fmt, args); + va_end(args); +} + +void acpi_os_vprintf(const char *fmt, va_list args) +{ + static char buffer[512]; + + vsnprintf(buffer, sizeof(buffer), fmt, args); + + printk("%s", buffer); +} + +acpi_physical_address __init acpi_os_get_root_pointer(void) +{ + acpi_physical_address pa = 0; + acpi_find_root_pointer(&pa); + return pa; +} + +void __iomem * +acpi_os_map_memory(acpi_physical_address phys, acpi_size size) +{ + return __acpi_map_table((unsigned long)phys, size); +} +EXPORT_SYMBOL_GPL(acpi_os_map_memory); + +void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) +{ +} +EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width) { diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/tables.c --- a/xen/drivers/acpi/tables.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/drivers/acpi/tables.c Tue Jun 10 13:45:29 2008 +0100 @@ -23,172 +23,112 @@ * */ -#include <xen/config.h> #include <xen/init.h> #include <xen/kernel.h> -#include <xen/sched.h> #include <xen/smp.h> #include <xen/string.h> #include <xen/types.h> #include <xen/irq.h> #include <xen/errno.h> #include <xen/acpi.h> -/*#include <xen/bootmem.h>*/ #define PREFIX "ACPI: " #define ACPI_MAX_TABLES 128 - -static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { - [ACPI_TABLE_UNKNOWN] = "????", - [ACPI_APIC] = "APIC", - [ACPI_BOOT] = "BOOT", - [ACPI_DBGP] = "DBGP", - [ACPI_DSDT] = "DSDT", - [ACPI_ECDT] = "ECDT", - [ACPI_ETDT] = "ETDT", - [ACPI_FADT] = "FACP", - [ACPI_FACS] = "FACS", - [ACPI_OEMX] = "OEM", - [ACPI_PSDT] = "PSDT", - [ACPI_SBST] = "SBST", - [ACPI_SLIT] = "SLIT", - [ACPI_SPCR] = "SPCR", - [ACPI_SRAT] = "SRAT", - [ACPI_SSDT] = "SSDT", - [ACPI_SPMI] = "SPMI", - [ACPI_HPET] = "HPET", - [ACPI_MCFG] = "MCFG", - [ACPI_DMAR] = "DMAR", - [ACPI_IVRS] = "IVRS", -}; static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; -/* System Description Table (RSDT/XSDT) */ -struct acpi_table_sdt { - unsigned long pa; - enum acpi_table_id id; - unsigned long size; -} __attribute__ ((packed)); - -static unsigned long sdt_pa; /* Physical Address */ -static unsigned long sdt_count; /* Table count */ - -static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata; - -void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr) -{ - char *name = NULL; - +static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; + +static int acpi_apic_instance __initdata; + +void acpi_table_print_madt_entry(struct acpi_subtable_header *header) +{ if (!header) return; - /* Some table signatures aren't good table names */ - - if (!strncmp((char *)&header->signature, - acpi_table_signatures[ACPI_APIC], - sizeof(header->signature))) { - name = "MADT"; - } else if (!strncmp((char *)&header->signature, - acpi_table_signatures[ACPI_FADT], - sizeof(header->signature))) { - name = "FADT"; - } else - name = header->signature; - - printk(KERN_DEBUG PREFIX - "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", name, - header->revision, header->oem_id, header->oem_table_id, - header->oem_revision, header->asl_compiler_id, - header->asl_compiler_revision, (void *)phys_addr); -} - -void acpi_table_print_madt_entry(acpi_table_entry_header * header) -{ - if (!header) - return; - switch (header->type) { - case ACPI_MADT_LAPIC: - { - struct acpi_table_lapic *p = - (struct acpi_table_lapic *)header; + case ACPI_MADT_TYPE_LOCAL_APIC: + { + struct acpi_madt_local_apic *p = + (struct acpi_madt_local_apic *)header; printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", - p->acpi_id, p->id, - p->flags.enabled ? "enabled" : "disabled"); - } - break; - - case ACPI_MADT_IOAPIC: - { - struct acpi_table_ioapic *p = - (struct acpi_table_ioapic *)header; + p->processor_id, p->id, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + } + break; + + case ACPI_MADT_TYPE_IO_APIC: + { + struct acpi_madt_io_apic *p = + (struct acpi_madt_io_apic *)header; printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", p->id, p->address, p->global_irq_base); } break; - case ACPI_MADT_INT_SRC_OVR: - { - struct acpi_table_int_src_ovr *p = - (struct acpi_table_int_src_ovr *)header; + case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: + { + struct acpi_madt_interrupt_override *p = + (struct acpi_madt_interrupt_override *)header; printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", - p->bus, p->bus_irq, p->global_irq, - mps_inti_flags_polarity[p->flags.polarity], - mps_inti_flags_trigger[p->flags.trigger]); - if (p->flags.reserved) + p->bus, p->source_irq, p->global_irq, + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]); + if (p->inti_flags & + ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)) printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n", - p->flags.reserved); - - } - break; - - case ACPI_MADT_NMI_SRC: - { - struct acpi_table_nmi_src *p = - (struct acpi_table_nmi_src *)header; + p->inti_flags & + ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)); + + } + break; + + case ACPI_MADT_TYPE_NMI_SOURCE: + { + struct acpi_madt_nmi_source *p = + (struct acpi_madt_nmi_source *)header; printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n", - mps_inti_flags_polarity[p->flags.polarity], - mps_inti_flags_trigger[p->flags.trigger], + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], p->global_irq); } break; - case ACPI_MADT_LAPIC_NMI: - { - struct acpi_table_lapic_nmi *p = - (struct acpi_table_lapic_nmi *)header; + case ACPI_MADT_TYPE_LOCAL_APIC_NMI: + { + struct acpi_madt_local_apic_nmi *p = + (struct acpi_madt_local_apic_nmi *)header; printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", - p->acpi_id, - mps_inti_flags_polarity[p->flags.polarity], - mps_inti_flags_trigger[p->flags.trigger], + p->processor_id, + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], p->lint); } break; - case ACPI_MADT_LAPIC_ADDR_OVR: - { - struct acpi_table_lapic_addr_ovr *p = - (struct acpi_table_lapic_addr_ovr *)header; + case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: + { + struct acpi_madt_local_apic_override *p = + (struct acpi_madt_local_apic_override *)header; printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n", (void *)(unsigned long)p->address); } break; - case ACPI_MADT_IOSAPIC: - { - struct acpi_table_iosapic *p = - (struct acpi_table_iosapic *)header; + case ACPI_MADT_TYPE_IO_SAPIC: + { + struct acpi_madt_io_sapic *p = + (struct acpi_madt_io_sapic *)header; printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", p->id, (void *)(unsigned long)p->address, @@ -196,26 +136,26 @@ void acpi_table_print_madt_entry(acpi_ta } break; - case ACPI_MADT_LSAPIC: - { - struct acpi_table_lsapic *p = - (struct acpi_table_lsapic *)header; + case ACPI_MADT_TYPE_LOCAL_SAPIC: + { + struct acpi_madt_local_sapic *p = + (struct acpi_madt_local_sapic *)header; printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", - p->acpi_id, p->id, p->eid, - p->flags.enabled ? "enabled" : "disabled"); - } - break; - - case ACPI_MADT_PLAT_INT_SRC: - { - struct acpi_table_plat_int_src *p = - (struct acpi_table_plat_int_src *)header; + p->processor_id, p->id, p->eid, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + } + break; + + case ACPI_MADT_TYPE_INTERRUPT_SOURCE: + { + struct acpi_madt_interrupt_source *p = + (struct acpi_madt_interrupt_source *)header; printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", - mps_inti_flags_polarity[p->flags.polarity], - mps_inti_flags_trigger[p->flags.trigger], - p->type, p->id, p->eid, p->iosapic_vector, + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], + p->type, p->id, p->eid, p->io_sapic_vector, p->global_irq); } break; @@ -228,352 +168,117 @@ void acpi_table_print_madt_entry(acpi_ta } } -uint8_t -generate_acpi_checksum(void *tbl, unsigned long len) -{ - uint8_t *ptr, sum = 0; - - for (ptr = tbl; len > 0 ; len--, ptr++) - sum += *ptr; - - return 0 - sum; -} - -static int -acpi_table_compute_checksum(void *table_pointer, unsigned long length) -{ - u8 *p = (u8 *) table_pointer; - unsigned long remains = length; - unsigned long sum = 0; - - if (!p || !length) - return -EINVAL; - - while (remains--) - sum += *p++; - - return (sum & 0xFF); -} - -/* - * acpi_get_table_header_early() - * for acpi_blacklisted(), acpi_table_get_sdt() - */ + int __init -acpi_get_table_header_early(enum acpi_table_id id, - struct acpi_table_header **header) -{ - unsigned int i; - enum acpi_table_id temp_id; - - /* DSDT is different from the rest */ - if (id == ACPI_DSDT) - temp_id = ACPI_FADT; - else - temp_id = id; - - /* Locate the table. */ - - for (i = 0; i < sdt_count; i++) { - if (sdt_entry[i].id != temp_id) - continue; - *header = (void *) - __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); - if (!*header) { - printk(KERN_WARNING PREFIX "Unable to map %s\n", - acpi_table_signatures[temp_id]); - return -ENODEV; - } - break; - } - - if (!*header) { - printk(KERN_WARNING PREFIX "%s not present\n", - acpi_table_signatures[id]); - return -ENODEV; - } - - /* Map the DSDT header via the pointer in the FADT */ - if (id == ACPI_DSDT) { - struct acpi_table_fadt *fadt = - (struct acpi_table_fadt *)*header; - - if (fadt->header.revision == 3 && fadt->Xdsdt) { - *header = (void *)__acpi_map_table(fadt->Xdsdt, - sizeof(struct - acpi_table_header)); - } else if (fadt->dsdt) { - *header = (void *)__acpi_map_table(fadt->dsdt, - sizeof(struct - acpi_table_header)); - } else - *header = NULL; - - if (!*header) { - printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); - return -ENODEV; - } - } - - return 0; -} - -int __init -acpi_table_parse_madt_family(enum acpi_table_id id, - unsigned long madt_size, +acpi_table_parse_entries(char *id, + unsigned long table_size, int entry_id, - acpi_madt_entry_handler handler, + acpi_table_entry_handler handler, unsigned int max_entries) { - void *madt = NULL; - acpi_table_entry_header *entry; + struct acpi_table_header *table_header = NULL; + struct acpi_subtable_header *entry; unsigned int count = 0; - unsigned long madt_end; - unsigned int i; + unsigned long table_end; if (!handler) return -EINVAL; - /* Locate the MADT (if exists). There should only be one. */ - - for (i = 0; i < sdt_count; i++) { - if (sdt_entry[i].id != id) - continue; - madt = (void *) - __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); - if (!madt) { - printk(KERN_WARNING PREFIX "Unable to map %s\n", - acpi_table_signatures[id]); - return -ENODEV; - } - break; - } - - if (!madt) { - printk(KERN_WARNING PREFIX "%s not present\n", - acpi_table_signatures[id]); + if (strncmp(id, ACPI_SIG_MADT, 4) == 0) + acpi_get_table(id, acpi_apic_instance, &table_header); + else + acpi_get_table(id, 0, &table_header); + + if (!table_header) { + printk(KERN_WARNING PREFIX "%4.4s not present\n", id); return -ENODEV; } - madt_end = (unsigned long)madt + sdt_entry[i].size; + table_end = (unsigned long)table_header + table_header->length; /* Parse all entries looking for a match. */ - entry = (acpi_table_entry_header *) - ((unsigned long)madt + madt_size); - - while (((unsigned long)entry) + sizeof(acpi_table_entry_header) < - madt_end) { + entry = (struct acpi_subtable_header *) + ((unsigned long)table_header + table_size); + + while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < + table_end) { if (entry->type == entry_id && (!max_entries || count++ < max_entries)) - if (handler(entry, madt_end)) + if (handler(entry, table_end)) return -EINVAL; - entry = (acpi_table_entry_header *) + entry = (struct acpi_subtable_header *) ((unsigned long)entry + entry->length); } if (max_entries && count > max_entries) { - printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of " - "%i found\n", acpi_table_signatures[id], entry_id, - count - max_entries, count); + printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of " + "%i found\n", id, entry_id, count - max_entries, count); } return count; } int __init -acpi_table_parse_madt(enum acpi_madt_entry_id id, - acpi_madt_entry_handler handler, unsigned int max_entries) -{ - return acpi_table_parse_madt_family(ACPI_APIC, +acpi_table_parse_madt(enum acpi_madt_type id, + acpi_table_entry_handler handler, unsigned int max_entries) +{ + return acpi_table_parse_entries(ACPI_SIG_MADT, sizeof(struct acpi_table_madt), id, handler, max_entries); } -int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler) -{ - int count = 0; - unsigned int i = 0; +/** + * acpi_table_parse - find table with @id, run @handler on it + * + * @id: table id to find + * @handler: handler to run + * + * Scan the ACPI System Descriptor Table (STD) for a table matching @id, + * run @handler on it. Return 0 if table found, return on if not. + */ +int __init acpi_table_parse(char *id, acpi_table_handler handler) +{ + struct acpi_table_header *table = NULL; if (!handler) return -EINVAL; - for (i = 0; i < sdt_count; i++) { - if (sdt_entry[i].id != id) - continue; - count++; - if (count == 1) - handler(sdt_entry[i].pa, sdt_entry[i].size); - - else - printk(KERN_WARNING PREFIX - "%d duplicate %s table ignored.\n", count, - acpi_table_signatures[id]); - } - - return count; -} - -static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp) -{ - struct acpi_table_header *header = NULL; - unsigned int i, id = 0; - - if (!rsdp) - return -EINVAL; - - /* First check XSDT (but only on ACPI 2.0-compatible systems) */ - - if ((rsdp->revision >= 2) && rsdp->xsdt_physical_address) { - - struct acpi_table_xsdt *mapped_xsdt = NULL; - - sdt_pa = rsdp->xsdt_physical_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; - } - - sdt_count = - (header->length - sizeof(struct acpi_table_header)) >> 3; - if (sdt_count > ACPI_MAX_TABLES) { - printk(KERN_WARNING PREFIX - "Truncated %lu XSDT entries\n", - (sdt_count - ACPI_MAX_TABLES)); - sdt_count = ACPI_MAX_TABLES; - } - - for (i = 0; i < sdt_count; i++) - sdt_entry[i].pa = (unsigned long)mapped_xsdt->table_offset_entry[i]; - } - - /* Then check RSDT */ - - else if (rsdp->rsdt_physical_address) { - - struct acpi_table_rsdt *mapped_rsdt = NULL; - - sdt_pa = rsdp->rsdt_physical_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; - } - - sdt_count = - (header->length - sizeof(struct acpi_table_header)) >> 2; - if (sdt_count > ACPI_MAX_TABLES) { - printk(KERN_WARNING PREFIX - "Truncated %lu RSDT entries\n", - (sdt_count - ACPI_MAX_TABLES)); - sdt_count = ACPI_MAX_TABLES; - } - - for (i = 0; i < sdt_count; i++) - sdt_entry[i].pa = (unsigned long)mapped_rsdt->table_offset_entry[i]; - } - - else { + if (strncmp(id, ACPI_SIG_MADT, 4) == 0) + acpi_get_table(id, acpi_apic_instance, &table); + else + acpi_get_table(id, 0, &table); + + if (table) { + handler(table); + return 0; + } else + return 1; +} + +/* + * The BIOS is supposed to supply a single APIC/MADT, + * but some report two. Provide a knob to use either. + * (don't you wish instance 0 and 1 were not the same?) + */ +static void __init check_multiple_madt(void) +{ + struct acpi_table_header *table = NULL; + + acpi_get_table(ACPI_SIG_MADT, 2, &table); + if (table) { printk(KERN_WARNING PREFIX - "No System Description Table (RSDT/XSDT) specified in RSDP\n"); - return -ENODEV; - } - - acpi_table_print(header, sdt_pa); - - for (i = 0; i < sdt_count; i++) { - - /* map in just the header */ - header = (struct acpi_table_header *) - __acpi_map_table(sdt_entry[i].pa, - sizeof(struct acpi_table_header)); - if (!header) - continue; - - /* remap in the entire table before processing */ - header = (struct acpi_table_header *) - __acpi_map_table(sdt_entry[i].pa, header->length); - if (!header) - continue; - - acpi_table_print(header, sdt_entry[i].pa); - - if (acpi_table_compute_checksum(header, header->length)) { - printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); - continue; - } - - sdt_entry[i].size = header->length; - - for (id = 0; id < ACPI_TABLE_COUNT; id++) { - if (!strncmp((char *)&header->signature, - acpi_table_signatures[id], - sizeof(header->signature))) { - sdt_entry[i].id = id; - } - } - } - - /* - * The DSDT is *not* in the RSDT (why not? no idea.) but we want - * to print its info, because this is what people usually blacklist - * against. Unfortunately, we don't know the phys_addr, so just - * print 0. Maybe no one will notice. - */ - if (!acpi_get_table_header_early(ACPI_DSDT, &header)) - acpi_table_print(header, 0); - - return 0; + "BIOS bug: multiple APIC/MADT found," + " using %d\n", acpi_apic_instance); + printk(KERN_WARNING PREFIX + "If \"acpi_apic_instance=%d\" works better, " + "notify linux-acpi@xxxxxxxxxxxxxxx\n", + acpi_apic_instance ? 0 : 2); + + } else + acpi_apic_instance = 0; + + return; } /* @@ -581,190 +286,26 @@ static int __init acpi_table_get_sdt(str * * find RSDP, find and checksum SDT/XSDT. * checksum all tables, print SDT/XSDT - * + * * result: sdt_entry[] is initialized */ int __init acpi_table_init(void) { - struct acpi_table_rsdp *rsdp = NULL; - unsigned long rsdp_phys = 0; - int result = 0; - - /* Locate and map the Root System Description Table (RSDP) */ - - rsdp_phys = acpi_find_rsdp(); - if (!rsdp_phys) { - printk(KERN_ERR PREFIX "Unable to locate RSDP\n"); - return -ENODEV; - } - - rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys, - sizeof(struct acpi_table_rsdp)); - if (!rsdp) { - printk(KERN_WARNING PREFIX "Unable to map RSDP\n"); - return -ENODEV; - } - - printk(KERN_DEBUG PREFIX - "RSDP (v%3.3d %6.6s ) @ 0x%p\n", - rsdp->revision, rsdp->oem_id, (void *)rsdp_phys); - - if (rsdp->revision < 2) - result = - acpi_table_compute_checksum(rsdp, 20); - else - result = - acpi_table_compute_checksum(rsdp, rsdp->length); - - if (result) { - printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); - return -ENODEV; - } - - /* Locate and map the System Description table (RSDT/XSDT) */ - - if (acpi_table_get_sdt(rsdp)) - return -ENODEV; - + acpi_ut_init_globals(); + acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + check_multiple_madt(); 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) && rsdp->xsdt_physical_address) { - - struct acpi_table_xsdt *mapped_xsdt = NULL; - - sdt_pa = rsdp->xsdt_physical_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->table_offset_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_physical_address) { - - struct acpi_table_rsdt *mapped_rsdt = NULL; - - sdt_pa = rsdp->rsdt_physical_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->table_offset_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); +static int __init acpi_parse_apic_instance(char *str) +{ + + acpi_apic_instance = simple_strtoul(str, NULL, 0); + + printk(KERN_NOTICE PREFIX "Shall use APIC/MADT table %d\n", + acpi_apic_instance); return 0; } +custom_param("acpi_apic_instance", acpi_parse_apic_instance); diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/tables/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/tables/Makefile Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,5 @@ +obj-y += tbfadt.o +obj-y += tbinstal.o +obj-y += tbutils.o +obj-y += tbxface.o +obj-y += tbxfroot.o diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/tables/tbfadt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/tables/tbfadt.c Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,458 @@ +/****************************************************************************** + * + * Module Name: tbfadt - FADT table utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <xen/config.h> +#include <xen/init.h> +#include <acpi/acpi.h> +#include <acpi/actables.h> + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbfadt") + +/* Local prototypes */ +static void inline +acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, + u8 bit_width, u64 address); + +static void acpi_tb_convert_fadt(void); + +static void acpi_tb_validate_fadt(void); + +/* Table for conversion of FADT to common internal format and FADT validation */ + +typedef struct acpi_fadt_info { + char *name; + u8 target; + u8 source; + u8 length; + u8 type; + +} acpi_fadt_info; + +#define ACPI_FADT_REQUIRED 1 +#define ACPI_FADT_SEPARATE_LENGTH 2 + +static struct acpi_fadt_info fadt_info_table[] = { + {"Pm1aEventBlock", ACPI_FADT_OFFSET(xpm1a_event_block), + ACPI_FADT_OFFSET(pm1a_event_block), + ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_REQUIRED}, + + {"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block), + ACPI_FADT_OFFSET(pm1b_event_block), + ACPI_FADT_OFFSET(pm1_event_length), 0}, + + {"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block), + ACPI_FADT_OFFSET(pm1a_control_block), + ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_REQUIRED}, + + {"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block), + ACPI_FADT_OFFSET(pm1b_control_block), + ACPI_FADT_OFFSET(pm1_control_length), 0}, + + {"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block), + ACPI_FADT_OFFSET(pm2_control_block), + ACPI_FADT_OFFSET(pm2_control_length), ACPI_FADT_SEPARATE_LENGTH}, + + {"PmTimerBlock", ACPI_FADT_OFFSET(xpm_timer_block), + ACPI_FADT_OFFSET(pm_timer_block), + ACPI_FADT_OFFSET(pm_timer_length), ACPI_FADT_REQUIRED}, + + {"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block), + ACPI_FADT_OFFSET(gpe0_block), + ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_SEPARATE_LENGTH}, + + {"Gpe1Block", ACPI_FADT_OFFSET(xgpe1_block), + ACPI_FADT_OFFSET(gpe1_block), + ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_SEPARATE_LENGTH} +}; + +#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) + +/******************************************************************************* + * + * FUNCTION: acpi_tb_init_generic_address + * + * PARAMETERS: generic_address - GAS struct to be initialized + * bit_width - Width of this register + * Address - Address of the register + * + * RETURN: None + * + * DESCRIPTION: Initialize a Generic Address Structure (GAS) + * See the ACPI specification for a full description and + * definition of this structure. + * + ******************************************************************************/ + +static void inline +acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, + u8 bit_width, u64 address) +{ + + /* + * The 64-bit Address field is non-aligned in the byte packed + * GAS struct. + */ + ACPI_MOVE_64_TO_64(&generic_address->address, &address); + + /* All other fields are byte-wide */ + + generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; + generic_address->bit_width = bit_width; + generic_address->bit_offset = 0; + generic_address->access_width = 0; +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_parse_fadt + * + * PARAMETERS: table_index - Index for the FADT + * Flags - Flags + * + * RETURN: None + * + * DESCRIPTION: Initialize the FADT, DSDT and FACS tables + * (FADT contains the addresses of the DSDT and FACS) + * + ******************************************************************************/ + +void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) +{ + u32 length; + struct acpi_table_header *table; + + /* + * The FADT has multiple versions with different lengths, + * and it contains pointers to both the DSDT and FACS tables. + * + * Get a local copy of the FADT and convert it to a common format + * Map entire FADT, assumed to be smaller than one page. + */ + length = acpi_gbl_root_table_list.tables[table_index].length; + + table = + acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index]. + address, length); + if (!table) { + return; + } + + /* + * Validate the FADT checksum before we copy the table. Ignore + * checksum error as we want to try to get the DSDT and FACS. + */ + (void)acpi_tb_verify_checksum(table, length); + + /* Obtain a local copy of the FADT in common ACPI 2.0+ format */ + + acpi_tb_create_local_fadt(table, length); + + /* All done with the real FADT, unmap it */ + + acpi_os_unmap_memory(table, length); + + /* Obtain the DSDT and FACS tables via their addresses within the FADT */ + + acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, + flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); + + acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, + flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_create_local_fadt + * + * PARAMETERS: Table - Pointer to BIOS FADT + * Length - Length of the table + * + * RETURN: None + * + * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. + * Performs validation on some important FADT fields. + * + * NOTE: We create a local copy of the FADT regardless of the version. + * + ******************************************************************************/ + +void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) +{ + + /* + * Check if the FADT is larger than the largest table that we expect + * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue + * a warning. + */ + if (length > sizeof(struct acpi_table_fadt)) { + ACPI_WARNING((AE_INFO, + "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX", + table->revision, (unsigned)length, + sizeof(struct acpi_table_fadt))); + } + + /* Clear the entire local FADT */ + + ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); + + /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ + + ACPI_MEMCPY(&acpi_gbl_FADT, table, + ACPI_MIN(length, sizeof(struct acpi_table_fadt))); + + /* + * 1) Convert the local copy of the FADT to the common internal format + * 2) Validate some of the important values within the FADT + */ + acpi_tb_convert_fadt(); + acpi_tb_validate_fadt(); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_fadt + * + * PARAMETERS: None, uses acpi_gbl_FADT + * + * RETURN: None + * + * DESCRIPTION: Converts all versions of the FADT to a common internal format. + * Expand all 32-bit addresses to 64-bit. + * + * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), + * and must contain a copy of the actual FADT. + * + * ACPICA will use the "X" fields of the FADT for all addresses. + * + * "X" fields are optional extensions to the original V1.0 fields. Even if + * they are present in the structure, they can be optionally not used by + * setting them to zero. Therefore, we must selectively expand V1.0 fields + * if the corresponding X field is zero. + * + * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding + * "X" fields. + * + * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by + * expanding the corresponding ACPI 1.0 field. + * + ******************************************************************************/ + +static void acpi_tb_convert_fadt(void) +{ + u8 pm1_register_length; + struct acpi_generic_address *target; + acpi_native_uint i; + + /* Update the local FADT table header length */ + + acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); + + /* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */ + + if (!acpi_gbl_FADT.Xfacs) { + acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; + } + + if (!acpi_gbl_FADT.Xdsdt) { + acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; + } + + /* + * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which + * should be zero are indeed zero. This will workaround BIOSs that + * inadvertently place values in these fields. + * + * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at + * offset 45, 55, 95, and the word located at offset 109, 110. + */ + if (acpi_gbl_FADT.header.revision < 3) { + acpi_gbl_FADT.preferred_profile = 0; + acpi_gbl_FADT.pstate_control = 0; + acpi_gbl_FADT.cst_control = 0; + acpi_gbl_FADT.boot_flags = 0; + } + + /* + * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" + * generic address structures as necessary. + */ + for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { + target = + ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, + fadt_info_table[i].target); + + /* Expand only if the X target is null */ + + if (!target->address) { + acpi_tb_init_generic_address(target, + *ACPI_ADD_PTR(u8, + &acpi_gbl_FADT, + fadt_info_table + [i].length), + (u64) * ACPI_ADD_PTR(u32, + &acpi_gbl_FADT, + fadt_info_table + [i]. + source)); + } + } + + /* + * Calculate separate GAS structs for the PM1 Enable registers. + * These addresses do not appear (directly) in the FADT, so it is + * useful to calculate them once, here. + * + * The PM event blocks are split into two register blocks, first is the + * PM Status Register block, followed immediately by the PM Enable Register + * block. Each is of length (pm1_event_length/2) + */ + pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); + + /* The PM1A register block is required */ + + acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, + pm1_register_length, + (acpi_gbl_FADT.xpm1a_event_block.address + + pm1_register_length)); + /* Don't forget to copy space_id of the GAS */ + acpi_gbl_xpm1a_enable.space_id = + acpi_gbl_FADT.xpm1a_event_block.space_id; + + /* The PM1B register block is optional, ignore if not present */ + + if (acpi_gbl_FADT.xpm1b_event_block.address) { + acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, + pm1_register_length, + (acpi_gbl_FADT.xpm1b_event_block. + address + pm1_register_length)); + /* Don't forget to copy space_id of the GAS */ + acpi_gbl_xpm1b_enable.space_id = + acpi_gbl_FADT.xpm1a_event_block.space_id; + + } +} + +/****************************************************************************** + * + * FUNCTION: acpi_tb_validate_fadt + * + * PARAMETERS: Table - Pointer to the FADT to be validated + * + * RETURN: None + * + * DESCRIPTION: Validate various important fields within the FADT. If a problem + * is found, issue a message, but no status is returned. + * Used by both the table manager and the disassembler. + * + * Possible additional checks: + * (acpi_gbl_FADT.pm1_event_length >= 4) + * (acpi_gbl_FADT.pm1_control_length >= 2) + * (acpi_gbl_FADT.pm_timer_length >= 4) + * Gpe block lengths must be multiple of 2 + * + ******************************************************************************/ + +static void acpi_tb_validate_fadt(void) +{ + u32 *address32; + struct acpi_generic_address *address64; + u8 length; + acpi_native_uint i; + + /* Examine all of the 64-bit extended address fields (X fields) */ + + for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { + + /* Generate pointers to the 32-bit and 64-bit addresses and get the length */ + + address64 = + ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, + fadt_info_table[i].target); + address32 = + ACPI_ADD_PTR(u32, &acpi_gbl_FADT, + fadt_info_table[i].source); + length = + *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, + fadt_info_table[i].length); + + if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { + /* + * Field is required (Pm1a_event, Pm1a_control, pm_timer). + * Both the address and length must be non-zero. + */ + if (!address64->address || !length) { + ACPI_ERROR((AE_INFO, + "Required field \"%s\" has zero address and/or length: %8.8X%8.8X/%X", + fadt_info_table[i].name, + ACPI_FORMAT_UINT64(address64-> + address), + length)); + } + } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { + /* + * Field is optional (PM2Control, GPE0, GPE1) AND has its own + * length field. If present, both the address and length must be valid. + */ + if ((address64->address && !length) + || (!address64->address && length)) { + ACPI_WARNING((AE_INFO, + "Optional field \"%s\" has zero address or length: %8.8X%8.8X/%X", + fadt_info_table[i].name, + ACPI_FORMAT_UINT64(address64-> + address), + length)); + } + } + + /* If both 32- and 64-bit addresses are valid (non-zero), they must match */ + + if (address64->address && *address32 && + (address64->address != (u64) * address32)) { + ACPI_ERROR((AE_INFO, + "32/64X address mismatch in \"%s\": [%8.8X] [%8.8X%8.8X], using 64X", + fadt_info_table[i].name, *address32, + ACPI_FORMAT_UINT64(address64->address))); + } + } +} diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/tables/tbinstal.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/tables/tbinstal.c Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,150 @@ +/****************************************************************************** + * + * Module Name: tbinstal - ACPI table installation and removal + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include <acpi/acnamesp.h> +#include <acpi/actables.h> + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbinstal") + +/****************************************************************************** + * + * FUNCTION: acpi_tb_verify_table + * + * PARAMETERS: table_desc - table + * + * RETURN: Status + * + * DESCRIPTION: this function is called to verify and map table + * + *****************************************************************************/ +acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE(tb_verify_table); + + /* Map the table if necessary */ + + if (!table_desc->pointer) { + if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == + ACPI_TABLE_ORIGIN_MAPPED) { + table_desc->pointer = + acpi_os_map_memory(table_desc->address, + table_desc->length); + } + if (!table_desc->pointer) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + } + + /* FACS is the odd table, has no standard ACPI header and no checksum */ + + if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { + + /* Always calculate checksum, ignore bad checksum if requested */ + + status = + acpi_tb_verify_checksum(table_desc->pointer, + table_desc->length); + } + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_resize_root_table_list + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Expand the size of global table array + * + ******************************************************************************/ + +acpi_status acpi_tb_resize_root_table_list(void) +{ + struct acpi_table_desc *tables; + + ACPI_FUNCTION_TRACE(tb_resize_root_table_list); + + /* allow_resize flag is a parameter to acpi_initialize_tables */ + + if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { + ACPI_ERROR((AE_INFO, + "Resize of Root Table Array is not allowed")); + return_ACPI_STATUS(AE_SUPPORT); + } + + /* Increase the Table Array size */ + + tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size + + ACPI_ROOT_TABLE_SIZE_INCREMENT) + * sizeof(struct acpi_table_desc)); + if (!tables) { + ACPI_ERROR((AE_INFO, + "Could not allocate new root table array")); + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Copy and free the previous table array */ + + if (acpi_gbl_root_table_list.tables) { + ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, + acpi_gbl_root_table_list.size * + sizeof(struct acpi_table_desc)); + + if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { + ACPI_FREE(acpi_gbl_root_table_list.tables); + } + } + + acpi_gbl_root_table_list.tables = tables; + acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; + acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED; + + return_ACPI_STATUS(AE_OK); +} diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/tables/tbutils.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/tables/tbutils.c Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,560 @@ +/****************************************************************************** + * + * Module Name: tbutils - table utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <xen/config.h> +#include <xen/init.h> +#include <acpi/acpi.h> +#include <acpi/actables.h> + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbutils") + +/* Local prototypes */ +static acpi_physical_address +acpi_tb_get_root_table_entry(u8 * table_entry, + acpi_native_uint table_entry_size); +/******************************************************************************* + * + * FUNCTION: acpi_tb_check_xsdt + * + * PARAMETERS: address - Pointer to the XSDT + * + * RETURN: status + * AE_OK - XSDT is okay + * AE_NO_MEMORY - can't map XSDT + * AE_INVALID_TABLE_LENGTH - invalid table length + * AE_NULL_ENTRY - XSDT has NULL entry + * + * DESCRIPTION: validate XSDT +******************************************************************************/ + +static acpi_status +acpi_tb_check_xsdt(acpi_physical_address address) +{ + struct acpi_table_header *table; + u32 length; + u64 xsdt_entry_address; + u8 *table_entry; + u32 table_count; + int i; + + table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); + if (!table) + return AE_NO_MEMORY; + + length = table->length; + acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + if (length < sizeof(struct acpi_table_header)) + return AE_INVALID_TABLE_LENGTH; + + table = acpi_os_map_memory(address, length); + if (!table) + return AE_NO_MEMORY; + + /* Calculate the number of tables described in XSDT */ + table_count = + (u32) ((table->length - + sizeof(struct acpi_table_header)) / sizeof(u64)); + table_entry = + ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); + for (i = 0; i < table_count; i++) { + ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry); + if (!xsdt_entry_address) { + /* XSDT has NULL entry */ + break; + } + table_entry += sizeof(u64); + } + acpi_os_unmap_memory(table, length); + + if (i < table_count) + return AE_NULL_ENTRY; + else + return AE_OK; +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_tables_loaded + * + * PARAMETERS: None + * + * RETURN: TRUE if required ACPI tables are loaded + * + * DESCRIPTION: Determine if the minimum required ACPI tables are present + * (FADT, FACS, DSDT) + * + ******************************************************************************/ + +u8 acpi_tb_tables_loaded(void) +{ + + if (acpi_gbl_root_table_list.count >= 3) { + return (TRUE); + } + + return (FALSE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_print_table_header + * + * PARAMETERS: Address - Table physical address + * Header - Table header + * + * RETURN: None + * + * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. + * + ******************************************************************************/ + +void +acpi_tb_print_table_header(acpi_physical_address address, + struct acpi_table_header *header) +{ + + if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { + + /* FACS only has signature and length fields of common table header */ + + ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X", + header->signature, (unsigned long)address, + header->length)); + } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { + + /* RSDP has no common fields */ + + ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)", + (unsigned long)address, + (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> + revision > + 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, + header)->length : 20, + ACPI_CAST_PTR(struct acpi_table_rsdp, + header)->revision, + ACPI_CAST_PTR(struct acpi_table_rsdp, + header)->oem_id)); + } else { + /* Standard ACPI table with full common header */ + + ACPI_INFO((AE_INFO, + "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)", + header->signature, (unsigned long)address, + header->length, header->revision, header->oem_id, + header->oem_table_id, header->oem_revision, + header->asl_compiler_id, + header->asl_compiler_revision)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_validate_checksum + * + * PARAMETERS: Table - ACPI table to verify + * Length - Length of entire table + * + * RETURN: Status + * + * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns + * exception on bad checksum. + * + ******************************************************************************/ + +acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) +{ + u8 checksum; + + /* Compute the checksum on the table */ + + checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); + + /* Checksum ok? (should be zero) */ + + if (checksum) { + ACPI_WARNING((AE_INFO, + "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", + table->signature, table->checksum, + (u8) (table->checksum - checksum))); + +#if (ACPI_CHECKSUM_ABORT) + + return (AE_BAD_CHECKSUM); +#endif + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_checksum + * + * PARAMETERS: Buffer - Pointer to memory region to be checked + * Length - Length of this memory region + * + * RETURN: Checksum (u8) + * + * DESCRIPTION: Calculates circular checksum of memory region. + * + ******************************************************************************/ + +u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) +{ + u8 sum = 0; + u8 *end = buffer + length; + + while (buffer < end) { + sum = (u8) (sum + *(buffer++)); + } + + return sum; +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_install_table + * + * PARAMETERS: Address - Physical address of DSDT or FACS + * Flags - Flags + * Signature - Table signature, NULL if no need to + * match + * table_index - Index into root table array + * + * RETURN: None + * + * DESCRIPTION: Install an ACPI table into the global data structure. + * + ******************************************************************************/ + +void +acpi_tb_install_table(acpi_physical_address address, + u8 flags, char *signature, acpi_native_uint table_index) +{ + struct acpi_table_header *table; + + if (!address) { + ACPI_ERROR((AE_INFO, + "Null physical address for ACPI table [%s]", + signature)); + return; + } + + /* Map just the table header */ + + table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); + if (!table) { + return; + } + + /* If a particular signature is expected, signature must match */ + + if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { + ACPI_ERROR((AE_INFO, + "Invalid signature 0x%X for ACPI table [%s]", + *ACPI_CAST_PTR(u32, table->signature), signature)); + goto unmap_and_exit; + } + + /* Initialize the table entry */ + + acpi_gbl_root_table_list.tables[table_index].address = address; + acpi_gbl_root_table_list.tables[table_index].length = table->length; + acpi_gbl_root_table_list.tables[table_index].flags = flags; + + ACPI_MOVE_32_TO_32(& + (acpi_gbl_root_table_list.tables[table_index]. + signature), table->signature); + + acpi_tb_print_table_header(address, table); + + if (table_index == ACPI_TABLE_INDEX_DSDT) { + + /* Global integer width is based upon revision of the DSDT */ + + acpi_ut_set_integer_width(table->revision); + } + + unmap_and_exit: + acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_root_table_entry + * + * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry + * table_entry_size - sizeof 32 or 64 (RSDT or XSDT) + * + * RETURN: Physical address extracted from the root table + * + * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on + * both 32-bit and 64-bit platforms + * + * NOTE: acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on + * 64-bit platforms. + * + ******************************************************************************/ + +static acpi_physical_address +acpi_tb_get_root_table_entry(u8 * table_entry, + acpi_native_uint table_entry_size) +{ + u64 address64; + + /* + * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): + * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT + */ + if (table_entry_size == sizeof(u32)) { + /* + * 32-bit platform, RSDT: Return 32-bit table entry + * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return + */ + return ((acpi_physical_address) + (*ACPI_CAST_PTR(u32, table_entry))); + } else { + /* + * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return + * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit + */ + ACPI_MOVE_64_TO_64(&address64, table_entry); + +#if ACPI_MACHINE_WIDTH == 32 + if (address64 > ACPI_UINT32_MAX) { + + /* Will truncate 64-bit address to 32 bits, issue warning */ + + ACPI_WARNING((AE_INFO, + "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating", + ACPI_FORMAT_UINT64(address64))); + } +#endif + return ((acpi_physical_address) (address64)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_parse_root_table + * + * PARAMETERS: Rsdp - Pointer to the RSDP + * Flags - Flags + * + * RETURN: Status + * + * DESCRIPTION: This function is called to parse the Root System Description + * Table (RSDT or XSDT) + * + * NOTE: Tables are mapped (not copied) for efficiency. The FACS must + * be mapped and cannot be copied because it contains the actual + * memory location of the ACPI Global Lock. + * + ******************************************************************************/ + +acpi_status __init +acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) +{ + struct acpi_table_rsdp *rsdp; + acpi_native_uint table_entry_size; + acpi_native_uint i; + u32 table_count; + struct acpi_table_header *table; + acpi_physical_address address; + acpi_physical_address uninitialized_var(rsdt_address); + u32 length; + u8 *table_entry; + acpi_status status; + + ACPI_FUNCTION_TRACE(tb_parse_root_table); + + /* + * Map the entire RSDP and extract the address of the RSDT or XSDT + */ + rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp)); + if (!rsdp) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + acpi_tb_print_table_header(rsdp_address, + ACPI_CAST_PTR(struct acpi_table_header, + rsdp)); + + /* Differentiate between RSDT and XSDT root tables */ + + if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { + /* + * Root table is an XSDT (64-bit physical addresses). We must use the + * XSDT if the revision is > 1 and the XSDT pointer is present, as per + * the ACPI specification. + */ + address = (acpi_physical_address) rsdp->xsdt_physical_address; + table_entry_size = sizeof(u64); + rsdt_address = (acpi_physical_address) + rsdp->rsdt_physical_address; + } else { + /* Root table is an RSDT (32-bit physical addresses) */ + + address = (acpi_physical_address) rsdp->rsdt_physical_address; + table_entry_size = sizeof(u32); + } + + /* + * It is not possible to map more than one entry in some environments, + * so unmap the RSDP here before mapping other tables + */ + acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); + + if (table_entry_size == sizeof(u64)) { + if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) { + /* XSDT has NULL entry, RSDT is used */ + address = rsdt_address; + table_entry_size = sizeof(u32); + ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, " + "using RSDT")); + } + } + /* Map the RSDT/XSDT table header to get the full table length */ + + table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); + if (!table) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + acpi_tb_print_table_header(address, table); + + /* Get the length of the full table, verify length and map entire table */ + + length = table->length; + acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + + if (length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", + length)); + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + table = acpi_os_map_memory(address, length); + if (!table) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Validate the root table checksum */ + + status = acpi_tb_verify_checksum(table, length); + if (ACPI_FAILURE(status)) { + acpi_os_unmap_memory(table, length); + return_ACPI_STATUS(status); + } + + /* Calculate the number of tables described in the root table */ + + table_count = + (u32) ((table->length - + sizeof(struct acpi_table_header)) / table_entry_size); + + /* + * First two entries in the table array are reserved for the DSDT and FACS, + * which are not actually present in the RSDT/XSDT - they come from the FADT + */ + table_entry = + ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); + acpi_gbl_root_table_list.count = 2; + + /* + * Initialize the root table array from the RSDT/XSDT + */ + for (i = 0; i < table_count; i++) { + if (acpi_gbl_root_table_list.count >= + acpi_gbl_root_table_list.size) { + + /* There is no more room in the root table array, attempt resize */ + + status = acpi_tb_resize_root_table_list(); + if (ACPI_FAILURE(status)) { + ACPI_WARNING((AE_INFO, + "Truncating %u table entries!", + (unsigned) + (acpi_gbl_root_table_list.size - + acpi_gbl_root_table_list. + count))); + break; + } + } + + /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ + + acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. + address = + acpi_tb_get_root_table_entry(table_entry, table_entry_size); + + table_entry += table_entry_size; + acpi_gbl_root_table_list.count++; + } + + /* + * It is not possible to map more than one entry in some environments, + * so unmap the root table here before mapping other tables + */ + acpi_os_unmap_memory(table, length); + + /* + * Complete the initialization of the root table array by examining + * the header of each table + */ + for (i = 2; i < acpi_gbl_root_table_list.count; i++) { + acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. + address, flags, NULL, i); + + /* Special case for FADT - get the DSDT and FACS */ + + if (ACPI_COMPARE_NAME + (&acpi_gbl_root_table_list.tables[i].signature, + ACPI_SIG_FADT)) { + acpi_tb_parse_fadt(i, flags); + } + } + + return_ACPI_STATUS(AE_OK); +} diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/tables/tbxface.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/tables/tbxface.c Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,261 @@ +/****************************************************************************** + * + * Module Name: tbxface - Public interfaces to the ACPI subsystem + * ACPI table oriented interfaces + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <xen/config.h> +#include <xen/init.h> +#include <acpi/acpi.h> +#include <acpi/acnamesp.h> +#include <acpi/actables.h> + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbxface") + +/******************************************************************************* + * + * FUNCTION: acpi_allocate_root_table + * + * PARAMETERS: initial_table_count - Size of initial_table_array, in number of + * struct acpi_table_desc structures + * + * RETURN: Status + * + * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and + * acpi_initialize_tables. + * + ******************************************************************************/ + +acpi_status acpi_allocate_root_table(u32 initial_table_count) +{ + + acpi_gbl_root_table_list.size = initial_table_count; + acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; + + return (acpi_tb_resize_root_table_list()); +} + +/******************************************************************************* + * + * FUNCTION: acpi_initialize_tables + * + * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated + * struct acpi_table_desc structures. If NULL, the + * array is dynamically allocated. + * initial_table_count - Size of initial_table_array, in number of + * struct acpi_table_desc structures + * allow_realloc - Flag to tell Table Manager if resize of + * pre-allocated array is allowed. Ignored + * if initial_table_array is NULL. + * + * RETURN: Status + * + * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. + * + * NOTE: Allows static allocation of the initial table array in order + * to avoid the use of dynamic memory in confined environments + * such as the kernel boot sequence where it may not be available. + * + * If the host OS memory managers are initialized, use NULL for + * initial_table_array, and the table will be dynamically allocated. + * + ******************************************************************************/ + +acpi_status __init +acpi_initialize_tables(struct acpi_table_desc * initial_table_array, + u32 initial_table_count, u8 allow_resize) +{ + acpi_physical_address rsdp_address; + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_initialize_tables); + + /* + * Set up the Root Table Array + * Allocate the table array if requested + */ + if (!initial_table_array) { + status = acpi_allocate_root_table(initial_table_count); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } else { + /* Root Table Array has been statically allocated by the host */ + + ACPI_MEMSET(initial_table_array, 0, + initial_table_count * + sizeof(struct acpi_table_desc)); + + acpi_gbl_root_table_list.tables = initial_table_array; + acpi_gbl_root_table_list.size = initial_table_count; + acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN; + if (allow_resize) { + acpi_gbl_root_table_list.flags |= + ACPI_ROOT_ALLOW_RESIZE; + } + } + + /* Get the address of the RSDP */ + + rsdp_address = acpi_os_get_root_pointer(); + if (!rsdp_address) { + return_ACPI_STATUS(AE_NOT_FOUND); + } + + /* + * Get the root table (RSDT or XSDT) and extract all entries to the local + * Root Table Array. This array contains the information of the RSDT/XSDT + * in a common, more useable format. + */ + status = + acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_reallocate_root_table + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the + * root list from the previously provided scratch area. Should + * be called once dynamic memory allocation is available in the + * kernel + * + ******************************************************************************/ +acpi_status acpi_reallocate_root_table(void) +{ + struct acpi_table_desc *tables; + acpi_size new_size; + + ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); + + /* + * Only reallocate the root table if the host provided a static buffer + * for the table array in the call to acpi_initialize_tables. + */ + if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { + return_ACPI_STATUS(AE_SUPPORT); + } + + new_size = + (acpi_gbl_root_table_list.count + + ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); + + /* Create new array and copy the old array */ + + tables = ACPI_ALLOCATE_ZEROED(new_size); + if (!tables) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); + + acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; + acpi_gbl_root_table_list.tables = tables; + acpi_gbl_root_table_list.flags = + ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_get_table + * + * PARAMETERS: Signature - ACPI signature of needed table + * Instance - Which instance (for SSDTs) + * out_table - Where the pointer to the table is returned + * + * RETURN: Status and pointer to table + * + * DESCRIPTION: Finds and verifies an ACPI table. + * + *****************************************************************************/ +acpi_status +acpi_get_table(char *signature, + acpi_native_uint instance, struct acpi_table_header **out_table) +{ + acpi_native_uint i; + acpi_native_uint j; + acpi_status status; + + /* Parameter validation */ + + if (!signature || !out_table) { + return (AE_BAD_PARAMETER); + } + + /* + * Walk the root table list + */ + for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { + if (!ACPI_COMPARE_NAME + (&(acpi_gbl_root_table_list.tables[i].signature), + signature)) { + continue; + } + + if (++j < instance) { + continue; + } + + status = + acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); + if (ACPI_SUCCESS(status)) { + *out_table = acpi_gbl_root_table_list.tables[i].pointer; + } + + /*if (!acpi_gbl_permanent_mmap)*/ { + acpi_gbl_root_table_list.tables[i].pointer = NULL; + } + + return (status); + } + + return (AE_NOT_FOUND); +} + +ACPI_EXPORT_SYMBOL(acpi_get_table) diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/tables/tbxfroot.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/tables/tbxfroot.c Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,275 @@ +/****************************************************************************** + * + * Module Name: tbxfroot - Find the root ACPI table (RSDT) + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <xen/config.h> +#include <xen/init.h> +#include <acpi/acpi.h> +#include <acpi/actables.h> + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbxfroot") + +/* Local prototypes */ +static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); + +static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); + +/******************************************************************************* + * + * FUNCTION: acpi_tb_validate_rsdp + * + * PARAMETERS: Rsdp - Pointer to unvalidated RSDP + * + * RETURN: Status + * + * DESCRIPTION: Validate the RSDP (ptr) + * + ******************************************************************************/ + +static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) +{ + ACPI_FUNCTION_ENTRY(); + + /* + * The signature and checksum must both be correct + * + * Note: Sometimes there exists more than one RSDP in memory; the valid + * RSDP has a valid checksum, all others have an invalid checksum. + */ + if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) + != 0) { + + /* Nope, BAD Signature */ + + return (AE_BAD_SIGNATURE); + } + + /* Check the standard checksum */ + + if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { + return (AE_BAD_CHECKSUM); + } + + /* Check extended checksum if table version >= 2 */ + + if ((rsdp->revision >= 2) && + (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { + return (AE_BAD_CHECKSUM); + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_find_root_pointer + * + * PARAMETERS: table_address - Where the table pointer is returned + * + * RETURN: Status, RSDP physical address + * + * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor + * pointer structure. If it is found, set *RSDP to point to it. + * + * NOTE1: The RSDP must be either in the first 1_k of the Extended + * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) + * Only a 32-bit physical address is necessary. + * + * NOTE2: This function is always available, regardless of the + * initialization state of the rest of ACPI. + * + ******************************************************************************/ + +acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) +{ + u8 *table_ptr; + u8 *mem_rover; + u32 physical_address; + + ACPI_FUNCTION_TRACE(acpi_find_root_pointer); + + /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ + + table_ptr = acpi_os_map_memory((acpi_physical_address) + ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH); + if (!table_ptr) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); + + return_ACPI_STATUS(AE_NO_MEMORY); + } + + ACPI_MOVE_16_TO_32(&physical_address, table_ptr); + + /* Convert segment part to physical address */ + + physical_address <<= 4; + acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); + + /* EBDA present? */ + + if (physical_address > 0x400) { + /* + * 1b) Search EBDA paragraphs (EBDA is required to be a + * minimum of 1_k length) + */ + table_ptr = acpi_os_map_memory((acpi_native_uint) + physical_address, + ACPI_EBDA_WINDOW_SIZE); + if (!table_ptr) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + physical_address, ACPI_EBDA_WINDOW_SIZE)); + + return_ACPI_STATUS(AE_NO_MEMORY); + } + + mem_rover = + acpi_tb_scan_memory_for_rsdp(table_ptr, + ACPI_EBDA_WINDOW_SIZE); + acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); + + if (mem_rover) { + + /* Return the physical address */ + + physical_address += + (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); + + *table_address = physical_address; + return_ACPI_STATUS(AE_OK); + } + } + + /* + * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh + */ + table_ptr = acpi_os_map_memory((acpi_physical_address) + ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE); + + if (!table_ptr) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE)); + + return_ACPI_STATUS(AE_NO_MEMORY); + } + + mem_rover = + acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); + + if (mem_rover) { + + /* Return the physical address */ + + physical_address = (u32) + (ACPI_HI_RSDP_WINDOW_BASE + + ACPI_PTR_DIFF(mem_rover, table_ptr)); + + *table_address = physical_address; + return_ACPI_STATUS(AE_OK); + } + + /* A valid RSDP was not found */ + + ACPI_ERROR((AE_INFO, "A valid RSDP was not found")); + return_ACPI_STATUS(AE_NOT_FOUND); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_scan_memory_for_rsdp + * + * PARAMETERS: start_address - Starting pointer for search + * Length - Maximum length to search + * + * RETURN: Pointer to the RSDP if found, otherwise NULL. + * + * DESCRIPTION: Search a block of memory for the RSDP signature + * + ******************************************************************************/ +static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) +{ + acpi_status status; + u8 *mem_rover; + u8 *end_address; + + ACPI_FUNCTION_TRACE(tb_scan_memory_for_rsdp); + + end_address = start_address + length; + + /* Search from given start address for the requested length */ + + for (mem_rover = start_address; mem_rover < end_address; + mem_rover += ACPI_RSDP_SCAN_STEP) { + + /* The RSDP signature and checksum must both be correct */ + + status = + acpi_tb_validate_rsdp(ACPI_CAST_PTR + (struct acpi_table_rsdp, mem_rover)); + if (ACPI_SUCCESS(status)) { + + /* Sig and checksum valid, we have found a real RSDP */ + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "RSDP located at physical address %p\n", + mem_rover)); + return_PTR(mem_rover); + } + + /* No sig match or bad checksum, keep searching */ + } + + /* Searched entire block, no RSDP was found */ + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Searched entire block from %p, valid RSDP was not found\n", + start_address)); + return_PTR(NULL); +} diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/utglobal.c --- a/xen/drivers/acpi/utglobal.c Tue Jun 10 09:27:01 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/****************************************************************************** - * - * Module Name: utglobal - Global variables for the ACPI subsystem - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2007, R. Byron Moore - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -//#define DEFINE_ACPI_GLOBALS - -#include <acpi/acpi.h> -//#include <acpi/acnamesp.h> - -#define _COMPONENT ACPI_UTILITIES - ACPI_MODULE_NAME("utglobal") - -struct acpi_table_fadt acpi_gbl_FADT; - -/* These addresses are calculated from FADT address values */ - -struct acpi_generic_address acpi_gbl_xpm1a_enable; -struct acpi_generic_address acpi_gbl_xpm1b_enable; - -/****************************************************************************** - * - * Event and Hardware globals - * - ******************************************************************************/ - -struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = { - /* Name Parent Register Register Bit Position Register Bit Mask */ - - /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_TIMER_STATUS, - ACPI_BITMASK_TIMER_STATUS}, - /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_BUS_MASTER_STATUS, - ACPI_BITMASK_BUS_MASTER_STATUS}, - /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_GLOBAL_LOCK_STATUS, - ACPI_BITMASK_GLOBAL_LOCK_STATUS}, - /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_POWER_BUTTON_STATUS, - ACPI_BITMASK_POWER_BUTTON_STATUS}, - /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, - ACPI_BITMASK_SLEEP_BUTTON_STATUS}, - /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_RT_CLOCK_STATUS, - ACPI_BITMASK_RT_CLOCK_STATUS}, - /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_WAKE_STATUS, - ACPI_BITMASK_WAKE_STATUS}, - /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, - ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, - ACPI_BITMASK_PCIEXP_WAKE_STATUS}, - - /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, - ACPI_BITPOSITION_TIMER_ENABLE, - ACPI_BITMASK_TIMER_ENABLE}, - /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, - ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, - ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, - /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, - ACPI_BITPOSITION_POWER_BUTTON_ENABLE, - ACPI_BITMASK_POWER_BUTTON_ENABLE}, - /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, - ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, - ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, - /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, - ACPI_BITPOSITION_RT_CLOCK_ENABLE, - ACPI_BITMASK_RT_CLOCK_ENABLE}, - /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0}, - /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, - ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, - ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, - - /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, - ACPI_BITPOSITION_SCI_ENABLE, - ACPI_BITMASK_SCI_ENABLE}, - /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, - ACPI_BITPOSITION_BUS_MASTER_RLD, - ACPI_BITMASK_BUS_MASTER_RLD}, - /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, - ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, - ACPI_BITMASK_GLOBAL_LOCK_RELEASE}, - /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL, - ACPI_BITPOSITION_SLEEP_TYPE_X, - ACPI_BITMASK_SLEEP_TYPE_X}, - /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL, - ACPI_BITPOSITION_SLEEP_TYPE_X, - ACPI_BITMASK_SLEEP_TYPE_X}, - /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, - ACPI_BITPOSITION_SLEEP_ENABLE, - ACPI_BITMASK_SLEEP_ENABLE}, - - /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL, - ACPI_BITPOSITION_ARB_DISABLE, - ACPI_BITMASK_ARB_DISABLE} -}; - diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/utilities/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/utilities/Makefile Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,2 @@ +obj-y += utglobal.o +obj-y += utmisc.o diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/utilities/utglobal.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/utilities/utglobal.c Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,740 @@ +/****************************************************************************** + * + * Module Name: utglobal - Global variables for the ACPI subsystem + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define DEFINE_ACPI_GLOBALS + +#include <xen/config.h> +#include <xen/lib.h> +#include <acpi/acpi.h> +#include <acpi/acnamesp.h> + +ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME("utglobal") + +/******************************************************************************* + * + * Static global variable initialization. + * + ******************************************************************************/ +/* + * We want the debug switches statically initialized so they + * are already set when the debugger is entered. + */ +/* Debug switch - level and trace mask */ +u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT; + +/* Debug switch - layer (component) mask */ + +u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS; +u32 acpi_gbl_nesting_level = 0; + +/* Debugger globals */ + +u8 acpi_gbl_db_terminate_threads = FALSE; +u8 acpi_gbl_abort_method = FALSE; +u8 acpi_gbl_method_executing = FALSE; + +/* System flags */ + +u32 acpi_gbl_startup_flags = 0; + +/* System starts uninitialized */ + +u8 acpi_gbl_shutdown = TRUE; + +const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { + "\\_S0_", + "\\_S1_", + "\\_S2_", + "\\_S3_", + "\\_S4_", + "\\_S5_" +}; + +const char *acpi_gbl_highest_dstate_names[4] = { + "_S1D", + "_S2D", + "_S3D", + "_S4D" +}; + +/******************************************************************************* + * + * FUNCTION: acpi_format_exception + * + * PARAMETERS: Status - The acpi_status code to be formatted + * + * RETURN: A string containing the exception text. A valid pointer is + * always returned. + * + * DESCRIPTION: This function translates an ACPI exception into an ASCII string + * It is here instead of utxface.c so it is always present. + * + ******************************************************************************/ + +const char *acpi_format_exception(acpi_status status) +{ + const char *exception = NULL; + + ACPI_FUNCTION_ENTRY(); + + exception = acpi_ut_validate_exception(status); + if (!exception) { + + /* Exception code was not recognized */ + + ACPI_ERROR((AE_INFO, + "Unknown exception code: 0x%8.8X", status)); + + exception = "UNKNOWN_STATUS_CODE"; + dump_execution_state(); + } + + return (ACPI_CAST_PTR(const char, exception)); +} + +ACPI_EXPORT_SYMBOL(acpi_format_exception) + +/******************************************************************************* + * + * Namespace globals + * + ******************************************************************************/ +/* + * Predefined ACPI Names (Built-in to the Interpreter) + * + * NOTES: + * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run + * during the initialization sequence. + * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to + * perform a Notify() operation on it. + */ +const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { + {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_SB_", ACPI_TYPE_DEVICE, NULL}, + {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_TZ_", ACPI_TYPE_THERMAL, NULL}, + {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, + {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, + {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, + +#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) + {"_OSI", ACPI_TYPE_METHOD, (char *)1}, +#endif + + /* Table terminator */ + + {NULL, ACPI_TYPE_ANY, NULL} +}; + +/* + * Properties of the ACPI Object Types, both internal and external. + * The table is indexed by values of acpi_object_type + */ +const u8 acpi_gbl_ns_properties[] = { + ACPI_NS_NORMAL, /* 00 Any */ + ACPI_NS_NORMAL, /* 01 Number */ + ACPI_NS_NORMAL, /* 02 String */ + ACPI_NS_NORMAL, /* 03 Buffer */ + ACPI_NS_NORMAL, /* 04 Package */ + ACPI_NS_NORMAL, /* 05 field_unit */ + ACPI_NS_NEWSCOPE, /* 06 Device */ + ACPI_NS_NORMAL, /* 07 Event */ + ACPI_NS_NEWSCOPE, /* 08 Method */ + ACPI_NS_NORMAL, /* 09 Mutex */ + ACPI_NS_NORMAL, /* 10 Region */ + ACPI_NS_NEWSCOPE, /* 11 Power */ + ACPI_NS_NEWSCOPE, /* 12 Processor */ + ACPI_NS_NEWSCOPE, /* 13 Thermal */ + ACPI_NS_NORMAL, /* 14 buffer_field */ + ACPI_NS_NORMAL, /* 15 ddb_handle */ + ACPI_NS_NORMAL, /* 16 Debug Object */ + ACPI_NS_NORMAL, /* 17 def_field */ + ACPI_NS_NORMAL, /* 18 bank_field */ + ACPI_NS_NORMAL, /* 19 index_field */ + ACPI_NS_NORMAL, /* 20 Reference */ + ACPI_NS_NORMAL, /* 21 Alias */ + ACPI_NS_NORMAL, /* 22 method_alias */ + ACPI_NS_NORMAL, /* 23 Notify */ + ACPI_NS_NORMAL, /* 24 Address Handler */ + ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */ + ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */ + ACPI_NS_NEWSCOPE, /* 27 Scope */ + ACPI_NS_NORMAL, /* 28 Extra */ + ACPI_NS_NORMAL, /* 29 Data */ + ACPI_NS_NORMAL /* 30 Invalid */ +}; + +/* Hex to ASCII conversion table */ + +static const char acpi_gbl_hex_to_ascii[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_hex_to_ascii_char + * + * PARAMETERS: Integer - Contains the hex digit + * Position - bit position of the digit within the + * integer (multiple of 4) + * + * RETURN: The converted Ascii character + * + * DESCRIPTION: Convert a hex digit to an Ascii character + * + ******************************************************************************/ + +char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) +{ + + return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); +} + +/****************************************************************************** + * + * Event and Hardware globals + * + ******************************************************************************/ + +struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = { + /* Name Parent Register Register Bit Position Register Bit Mask */ + + /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_TIMER_STATUS, + ACPI_BITMASK_TIMER_STATUS}, + /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_BUS_MASTER_STATUS, + ACPI_BITMASK_BUS_MASTER_STATUS}, + /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_GLOBAL_LOCK_STATUS, + ACPI_BITMASK_GLOBAL_LOCK_STATUS}, + /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_POWER_BUTTON_STATUS, + ACPI_BITMASK_POWER_BUTTON_STATUS}, + /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, + ACPI_BITMASK_SLEEP_BUTTON_STATUS}, + /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_RT_CLOCK_STATUS, + ACPI_BITMASK_RT_CLOCK_STATUS}, + /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_WAKE_STATUS, + ACPI_BITMASK_WAKE_STATUS}, + /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, + ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, + ACPI_BITMASK_PCIEXP_WAKE_STATUS}, + + /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, + ACPI_BITPOSITION_TIMER_ENABLE, + ACPI_BITMASK_TIMER_ENABLE}, + /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, + ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, + ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, + /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, + ACPI_BITPOSITION_POWER_BUTTON_ENABLE, + ACPI_BITMASK_POWER_BUTTON_ENABLE}, + /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, + ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, + ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, + /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, + ACPI_BITPOSITION_RT_CLOCK_ENABLE, + ACPI_BITMASK_RT_CLOCK_ENABLE}, + /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0}, + /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, + ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, + ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, + + /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, + ACPI_BITPOSITION_SCI_ENABLE, + ACPI_BITMASK_SCI_ENABLE}, + /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, + ACPI_BITPOSITION_BUS_MASTER_RLD, + ACPI_BITMASK_BUS_MASTER_RLD}, + /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, + ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, + ACPI_BITMASK_GLOBAL_LOCK_RELEASE}, + /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL, + ACPI_BITPOSITION_SLEEP_TYPE_X, + ACPI_BITMASK_SLEEP_TYPE_X}, + /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL, + ACPI_BITPOSITION_SLEEP_TYPE_X, + ACPI_BITMASK_SLEEP_TYPE_X}, + /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, + ACPI_BITPOSITION_SLEEP_ENABLE, + ACPI_BITMASK_SLEEP_ENABLE}, + + /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL, + ACPI_BITPOSITION_ARB_DISABLE, + ACPI_BITMASK_ARB_DISABLE} +}; + +struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = { + /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS, + ACPI_BITREG_TIMER_ENABLE, + ACPI_BITMASK_TIMER_STATUS, + ACPI_BITMASK_TIMER_ENABLE}, + /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS, + ACPI_BITREG_GLOBAL_LOCK_ENABLE, + ACPI_BITMASK_GLOBAL_LOCK_STATUS, + ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, + /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS, + ACPI_BITREG_POWER_BUTTON_ENABLE, + ACPI_BITMASK_POWER_BUTTON_STATUS, + ACPI_BITMASK_POWER_BUTTON_ENABLE}, + /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS, + ACPI_BITREG_SLEEP_BUTTON_ENABLE, + ACPI_BITMASK_SLEEP_BUTTON_STATUS, + ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, + /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, + ACPI_BITREG_RT_CLOCK_ENABLE, + ACPI_BITMASK_RT_CLOCK_STATUS, + ACPI_BITMASK_RT_CLOCK_ENABLE}, +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_region_name + * + * PARAMETERS: None. + * + * RETURN: Status + * + * DESCRIPTION: Translate a Space ID into a name string (Debug only) + * + ******************************************************************************/ + +/* Region type decoding */ + +const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { + "SystemMemory", + "SystemIO", + "PCI_Config", + "EmbeddedControl", + "SMBus", + "CMOS", + "PCIBARTarget", + "DataTable" +}; + +char *acpi_ut_get_region_name(u8 space_id) +{ + + if (space_id >= ACPI_USER_REGION_BEGIN) { + return ("UserDefinedRegion"); + } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { + return ("InvalidSpaceId"); + } + + return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id])); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_event_name + * + * PARAMETERS: None. + * + * RETURN: Status + * + * DESCRIPTION: Translate a Event ID into a name string (Debug only) + * + ******************************************************************************/ + +/* Event type decoding */ + +static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = { + "PM_Timer", + "GlobalLock", + "PowerButton", + "SleepButton", + "RealTimeClock", +}; + +char *acpi_ut_get_event_name(u32 event_id) +{ + + if (event_id > ACPI_EVENT_MAX) { + return ("InvalidEventID"); + } + + return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id])); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_type_name + * + * PARAMETERS: None. + * + * RETURN: Status + * + * DESCRIPTION: Translate a Type ID into a name string (Debug only) + * + ******************************************************************************/ + +/* + * Elements of acpi_gbl_ns_type_names below must match + * one-to-one with values of acpi_object_type + * + * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; + * when stored in a table it really means that we have thus far seen no + * evidence to indicate what type is actually going to be stored for this entry. + */ +static const char acpi_gbl_bad_type[] = "UNDEFINED"; + +/* Printable names of the ACPI object types */ + +static const char *acpi_gbl_ns_type_names[] = { + /* 00 */ "Untyped", + /* 01 */ "Integer", + /* 02 */ "String", + /* 03 */ "Buffer", + /* 04 */ "Package", + /* 05 */ "FieldUnit", + /* 06 */ "Device", + /* 07 */ "Event", + /* 08 */ "Method", + /* 09 */ "Mutex", + /* 10 */ "Region", + /* 11 */ "Power", + /* 12 */ "Processor", + /* 13 */ "Thermal", + /* 14 */ "BufferField", + /* 15 */ "DdbHandle", + /* 16 */ "DebugObject", + /* 17 */ "RegionField", + /* 18 */ "BankField", + /* 19 */ "IndexField", + /* 20 */ "Reference", + /* 21 */ "Alias", + /* 22 */ "MethodAlias", + /* 23 */ "Notify", + /* 24 */ "AddrHandler", + /* 25 */ "ResourceDesc", + /* 26 */ "ResourceFld", + /* 27 */ "Scope", + /* 28 */ "Extra", + /* 29 */ "Data", + /* 30 */ "Invalid" +}; + +char *acpi_ut_get_type_name(acpi_object_type type) +{ + + if (type > ACPI_TYPE_INVALID) { + return (ACPI_CAST_PTR(char, acpi_gbl_bad_type)); + } + + return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type])); +} + +char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) +{ + + if (!obj_desc) { + return ("[NULL Object Descriptor]"); + } + + return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc))); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_descriptor_name + * + * PARAMETERS: Object - An ACPI object + * + * RETURN: Pointer to a string + * + * DESCRIPTION: Validate object and return the descriptor type + * + ******************************************************************************/ + +/* Printable names of object descriptor types */ + +static const char *acpi_gbl_desc_type_names[] = { + /* 00 */ "Invalid", + /* 01 */ "Cached", + /* 02 */ "State-Generic", + /* 03 */ "State-Update", + /* 04 */ "State-Package", + /* 05 */ "State-Control", + /* 06 */ "State-RootParseScope", + /* 07 */ "State-ParseScope", + /* 08 */ "State-WalkScope", + /* 09 */ "State-Result", + /* 10 */ "State-Notify", + /* 11 */ "State-Thread", + /* 12 */ "Walk", + /* 13 */ "Parser", + /* 14 */ "Operand", + /* 15 */ "Node" +}; + +char *acpi_ut_get_descriptor_name(void *object) +{ + + if (!object) { + return ("NULL OBJECT"); + } + + if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) { + return (ACPI_CAST_PTR(char, acpi_gbl_bad_type)); + } + + return (ACPI_CAST_PTR(char, + acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE + (object)])); + +} + +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +/* + * Strings and procedures used for debug only + */ + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_mutex_name + * + * PARAMETERS: mutex_id - The predefined ID for this mutex. + * + * RETURN: String containing the name of the mutex. Always returns a valid + * pointer. + * + * DESCRIPTION: Translate a mutex ID into a name string (Debug only) + * + ******************************************************************************/ + +char *acpi_ut_get_mutex_name(u32 mutex_id) +{ + + if (mutex_id > ACPI_MAX_MUTEX) { + return ("Invalid Mutex ID"); + } + + return (acpi_gbl_mutex_names[mutex_id]); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_notify_name + * + * PARAMETERS: notify_value - Value from the Notify() request + * + * RETURN: String corresponding to the Notify Value. + * + * DESCRIPTION: Translate a Notify Value to a notify namestring. + * + ******************************************************************************/ + +/* Names for Notify() values, used for debug output */ + +static const char *acpi_gbl_notify_value_names[] = { + "Bus Check", + "Device Check", + "Device Wake", + "Eject Request", + "Device Check Light", + "Frequency Mismatch", + "Bus Mode Mismatch", + "Power Fault", + "Capabilities Check", + "Device PLD Check", + "Reserved", + "System Locality Update" +}; + +const char *acpi_ut_get_notify_name(u32 notify_value) +{ + + if (notify_value <= ACPI_NOTIFY_MAX) { + return (acpi_gbl_notify_value_names[notify_value]); + } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { + return ("Reserved"); + } else { /* Greater or equal to 0x80 */ + + return ("**Device Specific**"); + } +} +#endif + +/******************************************************************************* + * + * FUNCTION: acpi_ut_valid_object_type + * + * PARAMETERS: Type - Object type to be validated + * + * RETURN: TRUE if valid object type, FALSE otherwise + * + * DESCRIPTION: Validate an object type + * + ******************************************************************************/ + +u8 acpi_ut_valid_object_type(acpi_object_type type) +{ + + if (type > ACPI_TYPE_LOCAL_MAX) { + + /* Note: Assumes all TYPEs are contiguous (external/local) */ + + return (FALSE); + } + + return (TRUE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_init_globals + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Init library globals. All globals that require specific + * initialization should be initialized here! + * + ******************************************************************************/ + +void acpi_ut_init_globals(void) +{ +#if 0 + acpi_status status; +#endif + u32 i; + + ACPI_FUNCTION_TRACE(ut_init_globals); + +#if 0 + /* Create all memory caches */ + + status = acpi_ut_create_caches(); + if (ACPI_FAILURE(status)) { + return; + } +#endif + + /* Mutex locked flags */ + + for (i = 0; i < ACPI_NUM_MUTEX; i++) { + acpi_gbl_mutex_info[i].mutex = NULL; + acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[i].use_count = 0; + } + + for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { + acpi_gbl_owner_id_mask[i] = 0; + } + acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */ + + /* GPE support */ + + acpi_gbl_gpe_xrupt_list_head = NULL; + acpi_gbl_gpe_fadt_blocks[0] = NULL; + acpi_gbl_gpe_fadt_blocks[1] = NULL; + + /* Global handlers */ + + acpi_gbl_system_notify.handler = NULL; + acpi_gbl_device_notify.handler = NULL; + acpi_gbl_exception_handler = NULL; + acpi_gbl_init_handler = NULL; + /*acpi_gbl_table_handler = NULL;*/ + + /* Global Lock support */ + + acpi_gbl_global_lock_semaphore = NULL; + acpi_gbl_global_lock_mutex = NULL; + acpi_gbl_global_lock_acquired = FALSE; + acpi_gbl_global_lock_handle = 0; + + /* Miscellaneous variables */ + + acpi_gbl_cm_single_step = FALSE; + acpi_gbl_db_terminate_threads = FALSE; + acpi_gbl_shutdown = FALSE; + acpi_gbl_ns_lookup_count = 0; + acpi_gbl_ps_find_count = 0; + acpi_gbl_acpi_hardware_present = TRUE; + acpi_gbl_last_owner_id_index = 0; + acpi_gbl_next_owner_id_offset = 0; + acpi_gbl_trace_method_name = 0; + acpi_gbl_trace_dbg_level = 0; + acpi_gbl_trace_dbg_layer = 0; + acpi_gbl_debugger_configuration = DEBUGGER_THREADING; + acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; + + /* Hardware oriented */ + + acpi_gbl_events_initialized = FALSE; + acpi_gbl_system_awake_and_running = TRUE; + + /* Namespace */ + + acpi_gbl_root_node = NULL; + acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; + acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; + acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; + acpi_gbl_root_node_struct.child = NULL; + acpi_gbl_root_node_struct.peer = NULL; + acpi_gbl_root_node_struct.object = NULL; + acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; + +#ifdef ACPI_DEBUG_OUTPUT + acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); +#endif + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + acpi_gbl_display_final_mem_stats = FALSE; +#endif + + return_VOID; +} + +ACPI_EXPORT_SYMBOL(acpi_dbg_level) + ACPI_EXPORT_SYMBOL(acpi_dbg_layer) diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/acpi/utilities/utmisc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/acpi/utilities/utmisc.c Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,229 @@ +/******************************************************************************* + * + * Module Name: utmisc - common utility procedures + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <xen/config.h> +#include <xen/init.h> +#include <acpi/acpi.h> + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utmisc") + +/******************************************************************************* + * + * FUNCTION: acpi_ut_validate_exception + * + * PARAMETERS: Status - The acpi_status code to be formatted + * + * RETURN: A string containing the exception text. NULL if exception is + * not valid. + * + * DESCRIPTION: This function validates and translates an ACPI exception into + * an ASCII string. + * + ******************************************************************************/ +const char *acpi_ut_validate_exception(acpi_status status) +{ + acpi_status sub_status; + const char *exception = NULL; + + ACPI_FUNCTION_ENTRY(); + + /* + * Status is composed of two parts, a "type" and an actual code + */ + sub_status = (status & ~AE_CODE_MASK); + + switch (status & AE_CODE_MASK) { + case AE_CODE_ENVIRONMENTAL: + + if (sub_status <= AE_CODE_ENV_MAX) { + exception = acpi_gbl_exception_names_env[sub_status]; + } + break; + + case AE_CODE_PROGRAMMER: + + if (sub_status <= AE_CODE_PGM_MAX) { + exception = + acpi_gbl_exception_names_pgm[sub_status - 1]; + } + break; + + case AE_CODE_ACPI_TABLES: + + if (sub_status <= AE_CODE_TBL_MAX) { + exception = + acpi_gbl_exception_names_tbl[sub_status - 1]; + } + break; + + case AE_CODE_AML: + + if (sub_status <= AE_CODE_AML_MAX) { + exception = + acpi_gbl_exception_names_aml[sub_status - 1]; + } + break; + + case AE_CODE_CONTROL: + + if (sub_status <= AE_CODE_CTRL_MAX) { + exception = + acpi_gbl_exception_names_ctrl[sub_status - 1]; + } + break; + + default: + break; + } + + return (ACPI_CAST_PTR(const char, exception)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_set_integer_width + * + * PARAMETERS: Revision From DSDT header + * + * RETURN: None + * + * DESCRIPTION: Set the global integer bit width based upon the revision + * of the DSDT. For Revision 1 and 0, Integers are 32 bits. + * For Revision 2 and above, Integers are 64 bits. Yes, this + * makes a difference. + * + ******************************************************************************/ + +void acpi_ut_set_integer_width(u8 revision) +{ + + if (revision < 2) { + + /* 32-bit case */ + + acpi_gbl_integer_bit_width = 32; + acpi_gbl_integer_nybble_width = 8; + acpi_gbl_integer_byte_width = 4; + } else { + /* 64-bit case (ACPI 2.0+) */ + + acpi_gbl_integer_bit_width = 64; + acpi_gbl_integer_nybble_width = 16; + acpi_gbl_integer_byte_width = 8; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_error, acpi_ut_warning, acpi_ut_info + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print message with module/line/version info + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_error(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); + va_end(args); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_exception(char *module_name, + u32 line_number, acpi_status status, char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, + line_number, acpi_format_exception(status)); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} + +EXPORT_SYMBOL(acpi_ut_exception); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); + va_end(args); + va_end(args); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_info(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; + + /* + * Removed module_name, line_number, and acpica version, not needed + * for info output + */ + acpi_os_printf("ACPI: "); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf("\n"); + va_end(args); +} diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/passthrough/amd/iommu_acpi.c --- a/xen/drivers/passthrough/amd/iommu_acpi.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/drivers/passthrough/amd/iommu_acpi.c Tue Jun 10 13:45:29 2008 +0100 @@ -794,14 +794,13 @@ static void __init dump_acpi_table_heade } -int __init parse_ivrs_table(unsigned long phys_addr, unsigned long size) +int __init parse_ivrs_table(struct acpi_table_header *_table) { struct acpi_ivrs_block_header *ivrs_block; unsigned long length, i; u8 checksum, *raw_table; int error = 0; - struct acpi_table_header *table = - (struct acpi_table_header *) __acpi_map_table(phys_addr, size); + struct acpi_table_header *table = (struct acpi_table_header *)_table; BUG_ON(!table); diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/passthrough/amd/pci_amd_iommu.c --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Tue Jun 10 13:45:29 2008 +0100 @@ -212,7 +212,7 @@ static int __init amd_iommu_init(void) IOMMU_CONTROL_DISABLED; } - if ( acpi_table_parse(ACPI_IVRS, parse_ivrs_table) != 0 ) + if ( acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, parse_ivrs_table) != 0 ) amd_iov_error("Did not find IVRS table!\n"); for_each_amd_iommu ( iommu ) diff -r 7a0f1bf86516 -r 9af7a535225f xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/drivers/passthrough/vtd/dmar.c Tue Jun 10 13:45:29 2008 +0100 @@ -477,22 +477,13 @@ acpi_parse_one_atsr(struct acpi_dmar_ent return ret; } -static int __init acpi_parse_dmar(unsigned long phys_addr, - unsigned long size) -{ - struct acpi_table_dmar *dmar = NULL; +static int __init acpi_parse_dmar(struct acpi_table_header *table) +{ + struct acpi_table_dmar *dmar; struct acpi_dmar_entry_header *entry_header; int ret = 0; - if ( !phys_addr || !size ) - return -EINVAL; - - dmar = (struct acpi_table_dmar *)__acpi_map_table(phys_addr, size); - if ( !dmar ) - { - dprintk(XENLOG_WARNING VTDPREFIX, "Unable to map DMAR\n"); - return -ENODEV; - } + dmar = (struct acpi_table_dmar *)table; if ( !dmar->width ) { @@ -506,7 +497,7 @@ static int __init acpi_parse_dmar(unsign entry_header = (struct acpi_dmar_entry_header *)(dmar + 1); while ( ((unsigned long)entry_header) < - (((unsigned long)dmar) + size) ) + (((unsigned long)dmar) + table->length) ) { switch ( entry_header->type ) { @@ -550,7 +541,7 @@ int acpi_dmar_init(void) if ( (rc = vtd_hw_check()) != 0 ) goto fail; - acpi_table_parse(ACPI_DMAR, acpi_parse_dmar); + acpi_table_parse(ACPI_SIG_DMAR, acpi_parse_dmar); rc = -ENODEV; if ( list_empty(&acpi_drhd_units) ) diff -r 7a0f1bf86516 -r 9af7a535225f xen/include/acpi/acnamesp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/acpi/acnamesp.h Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,305 @@ +/****************************************************************************** + * + * Name: acnamesp.h - Namespace subcomponent prototypes and defines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef __ACNAMESP_H__ +#define __ACNAMESP_H__ + +/* To search the entire name space, pass this as search_base */ + +#define ACPI_NS_ALL ((acpi_handle)0) + +/* + * Elements of acpi_ns_properties are bit significant + * and should be one-to-one with values of acpi_object_type + */ +#define ACPI_NS_NORMAL 0 +#define ACPI_NS_NEWSCOPE 1 /* a definition of this type opens a name scope */ +#define ACPI_NS_LOCAL 2 /* suppress search of enclosing scopes */ + +/* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */ + +#define ACPI_NS_NO_UPSEARCH 0 +#define ACPI_NS_SEARCH_PARENT 0x01 +#define ACPI_NS_DONT_OPEN_SCOPE 0x02 +#define ACPI_NS_NO_PEER_SEARCH 0x04 +#define ACPI_NS_ERROR_IF_FOUND 0x08 +#define ACPI_NS_PREFIX_IS_SCOPE 0x10 +#define ACPI_NS_EXTERNAL 0x20 +#define ACPI_NS_TEMPORARY 0x40 + +/* Flags for acpi_ns_walk_namespace */ + +#define ACPI_NS_WALK_NO_UNLOCK 0 +#define ACPI_NS_WALK_UNLOCK 0x01 +#define ACPI_NS_WALK_TEMP_NODES 0x02 + +/* + * nsinit - Namespace initialization + */ +acpi_status acpi_ns_initialize_objects(void); + +acpi_status acpi_ns_initialize_devices(void); + +/* + * nsload - Namespace loading + */ +acpi_status acpi_ns_load_namespace(void); + +acpi_status +acpi_ns_load_table(acpi_native_uint table_index, + struct acpi_namespace_node *node); + +/* + * nswalk - walk the namespace + */ +acpi_status +acpi_ns_walk_namespace(acpi_object_type type, + acpi_handle start_object, + u32 max_depth, + u32 flags, + acpi_walk_callback user_function, + void *context, void **return_value); + +struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node + *parent, struct acpi_namespace_node + *child); + +/* + * nsparse - table parsing + */ +acpi_status +acpi_ns_parse_table(acpi_native_uint table_index, + struct acpi_namespace_node *start_node); + +acpi_status +acpi_ns_one_complete_parse(acpi_native_uint pass_number, + acpi_native_uint table_index, + struct acpi_namespace_node *start_node); + +/* + * nsaccess - Top-level namespace access + */ +acpi_status acpi_ns_root_initialize(void); + +acpi_status +acpi_ns_lookup(union acpi_generic_state *scope_info, + char *name, + acpi_object_type type, + acpi_interpreter_mode interpreter_mode, + u32 flags, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node **ret_node); + +/* + * nsalloc - Named object allocation/deallocation + */ +struct acpi_namespace_node *acpi_ns_create_node(u32 name); + +void acpi_ns_delete_node(struct acpi_namespace_node *node); + +void +acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); + +void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id); + +void acpi_ns_detach_object(struct acpi_namespace_node *node); + +void acpi_ns_delete_children(struct acpi_namespace_node *parent); + +int acpi_ns_compare_names(char *name1, char *name2); + +/* + * nsdump - Namespace dump/print utilities + */ +#ifdef ACPI_FUTURE_USAGE +void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth); +#endif /* ACPI_FUTURE_USAGE */ + +void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level); + +void +acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component); + +void acpi_ns_print_pathname(u32 num_segments, char *pathname); + +acpi_status +acpi_ns_dump_one_object(acpi_handle obj_handle, + u32 level, void *context, void **return_value); + +#ifdef ACPI_FUTURE_USAGE +void +acpi_ns_dump_objects(acpi_object_type type, + u8 display_type, + u32 max_depth, + acpi_owner_id owner_id, acpi_handle start_handle); +#endif /* ACPI_FUTURE_USAGE */ + +/* + * nseval - Namespace evaluation functions + */ +acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); + +/* + * nsnames - Name and Scope manipulation + */ +u32 acpi_ns_opens_scope(acpi_object_type type); + +void +acpi_ns_build_external_path(struct acpi_namespace_node *node, + acpi_size size, char *name_buffer); + +char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node); + +char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state); + +acpi_status +acpi_ns_handle_to_pathname(acpi_handle target_handle, + struct acpi_buffer *buffer); + +u8 +acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for); + +acpi_status +acpi_ns_get_node(struct acpi_namespace_node *prefix_node, + char *external_pathname, + u32 flags, struct acpi_namespace_node **out_node); + +acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node); + +/* + * nsobject - Object management for namespace nodes + */ +acpi_status +acpi_ns_attach_object(struct acpi_namespace_node *node, + union acpi_operand_object *object, acpi_object_type type); + +union acpi_operand_object *acpi_ns_get_attached_object(struct + acpi_namespace_node + *node); + +union acpi_operand_object *acpi_ns_get_secondary_object(union + acpi_operand_object + *obj_desc); + +acpi_status +acpi_ns_attach_data(struct acpi_namespace_node *node, + acpi_object_handler handler, void *data); + +acpi_status +acpi_ns_detach_data(struct acpi_namespace_node *node, + acpi_object_handler handler); + +acpi_status +acpi_ns_get_attached_data(struct acpi_namespace_node *node, + acpi_object_handler handler, void **data); + +/* + * nssearch - Namespace searching and entry + */ +acpi_status +acpi_ns_search_and_enter(u32 entry_name, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node *node, + acpi_interpreter_mode interpreter_mode, + acpi_object_type type, + u32 flags, struct acpi_namespace_node **ret_node); + +acpi_status +acpi_ns_search_one_scope(u32 entry_name, + struct acpi_namespace_node *node, + acpi_object_type type, + struct acpi_namespace_node **ret_node); + +void +acpi_ns_install_node(struct acpi_walk_state *walk_state, + struct acpi_namespace_node *parent_node, + struct acpi_namespace_node *node, acpi_object_type type); + +/* + * nsutils - Utility functions + */ +u8 acpi_ns_valid_root_prefix(char prefix); + +acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node); + +u32 acpi_ns_local(acpi_object_type type); + +void +acpi_ns_report_error(char *module_name, + u32 line_number, + char *internal_name, acpi_status lookup_status); + +void +acpi_ns_report_method_error(char *module_name, + u32 line_number, + char *message, + struct acpi_namespace_node *node, + char *path, acpi_status lookup_status); + +void acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *msg); + +acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info); + +void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info); + +acpi_status acpi_ns_internalize_name(char *dotted_name, char **converted_name); + +acpi_status +acpi_ns_externalize_name(u32 internal_name_length, + char *internal_name, + u32 * converted_name_length, char **converted_name); + +struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle); + +acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node); + +void acpi_ns_terminate(void); + +struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node + *node); + +struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct + acpi_namespace_node + *node); + +#endif /* __ACNAMESP_H__ */ diff -r 7a0f1bf86516 -r 9af7a535225f xen/include/acpi/actables.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/acpi/actables.h Tue Jun 10 13:45:29 2008 +0100 @@ -0,0 +1,118 @@ +/****************************************************************************** + * + * Name: actables.h - ACPI table management + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef __ACTABLES_H__ +#define __ACTABLES_H__ + +acpi_status acpi_allocate_root_table(u32 initial_table_count); + +/* + * tbfadt - FADT parse/convert/validate + */ +void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags); + +void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); + +/* + * tbfind - find ACPI table + */ +acpi_status +acpi_tb_find_table(char *signature, + char *oem_id, + char *oem_table_id, acpi_native_uint * table_index); + +/* + * tbinstal - Table removal and deletion + */ +acpi_status acpi_tb_resize_root_table_list(void); + +acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); + +acpi_status +acpi_tb_add_table(struct acpi_table_desc *table_desc, + acpi_native_uint * table_index); + +acpi_status +acpi_tb_store_table(acpi_physical_address address, + struct acpi_table_header *table, + u32 length, u8 flags, acpi_native_uint * table_index); + +void acpi_tb_delete_table(struct acpi_table_desc *table_desc); + +void acpi_tb_terminate(void); + +void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index); + +acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index); + +acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index); + +acpi_status +acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id); + +u8 acpi_tb_is_table_loaded(acpi_native_uint table_index); + +void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded); + +/* + * tbutils - table manager utilities + */ +u8 acpi_tb_tables_loaded(void); + +void +acpi_tb_print_table_header(acpi_physical_address address, + struct acpi_table_header *header); + +u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length); + +acpi_status +acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length); + +void +acpi_tb_install_table(acpi_physical_address address, + u8 flags, char *signature, acpi_native_uint table_index); + +acpi_status +acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags); + +#endif /* __ACTABLES_H__ */ diff -r 7a0f1bf86516 -r 9af7a535225f xen/include/acpi/platform/aclinux.h --- a/xen/include/acpi/platform/aclinux.h Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/include/acpi/platform/aclinux.h Tue Jun 10 13:45:29 2008 +0100 @@ -47,9 +47,8 @@ #define ACPI_USE_SYSTEM_CLIBRARY #define ACPI_USE_DO_WHILE_0 -#ifdef __XEN__ - #include <xen/config.h> +#include <xen/cache.h> #include <xen/string.h> #include <xen/kernel.h> #include <xen/ctype.h> @@ -71,34 +70,6 @@ /* Full namespace pathname length limit - arbitrary */ #define ACPI_PATHNAME_MAX 256 -#else /* !__XEN__ */ - -#include <stdarg.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> -#include <unistd.h> - -#if defined(__ia64__) || defined(__x86_64__) -#define ACPI_MACHINE_WIDTH 64 -#define COMPILER_DEPENDENT_INT64 long -#define COMPILER_DEPENDENT_UINT64 unsigned long -#else -#define ACPI_MACHINE_WIDTH 32 -#define COMPILER_DEPENDENT_INT64 long long -#define COMPILER_DEPENDENT_UINT64 unsigned long long -#define ACPI_USE_NATIVE_DIVIDE -#endif - -#ifndef __cdecl -#define __cdecl -#endif - -#define ACPI_FLUSH_CPU_CACHE() -#endif /* __XEN__ */ - -/* Linux uses GCC */ - #include "acgcc.h" #define acpi_cpu_flags unsigned long @@ -110,32 +81,11 @@ static inline acpi_thread_id acpi_os_get return current; } -#if 0 -/* - * The irqs_disabled() check is for resume from RAM. - * Interrupts are off during resume, just like they are for boot. - * However, boot has (system_state != SYSTEM_RUNNING) - * to quiet __might_sleep() in kmalloc() and resume does not. - */ -#include <acpi/actypes.h> -static inline void *acpi_os_allocate(acpi_size size) -{ - return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); -} -static inline void *acpi_os_allocate_zeroed(acpi_size size) -{ - return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); -} - -static inline void *acpi_os_acquire_object(acpi_cache_t * cache) -{ - return kmem_cache_zalloc(cache, - irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); -} - -#define ACPI_ALLOCATE(a) acpi_os_allocate(a) -#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) -#define ACPI_FREE(a) kfree(a) -#endif /* 0 */ +#define ACPI_ALLOCATE(a) xmalloc_bytes(a) +#define ACPI_ALLOCATE_ZEROED(a) ({ \ + void *p = xmalloc_bytes(a); \ + if ( p ) memset(p, 0, a); \ + p; }) +#define ACPI_FREE(a) xfree(a) #endif /* __ACLINUX_H__ */ diff -r 7a0f1bf86516 -r 9af7a535225f xen/include/asm-x86/hvm/svm/amd-iommu-proto.h --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Tue Jun 10 13:45:29 2008 +0100 @@ -88,7 +88,7 @@ struct amd_iommu *find_iommu_for_device( struct amd_iommu *find_iommu_for_device(int bus, int devfn); /* amd-iommu-acpi functions */ -int __init parse_ivrs_table(unsigned long phys_addr, unsigned long size); +int __init parse_ivrs_table(struct acpi_table_header *table); static inline u32 get_field_from_reg_u32(u32 reg_value, u32 mask, u32 shift) { diff -r 7a0f1bf86516 -r 9af7a535225f xen/include/xen/acpi.h --- a/xen/include/xen/acpi.h Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/include/xen/acpi.h Tue Jun 10 13:45:29 2008 +0100 @@ -46,11 +46,6 @@ enum acpi_irq_model_id { }; extern enum acpi_irq_model_id acpi_irq_model; - -typedef struct { - u8 type; - u8 length; -} __attribute__ ((packed)) acpi_table_entry_header; enum acpi_madt_entry_id { ACPI_MADT_LAPIC = 0, @@ -72,7 +67,7 @@ typedef struct { } __attribute__ ((packed)) acpi_interrupt_flags; struct acpi_table_lapic { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 acpi_id; u8 id; struct { @@ -82,7 +77,7 @@ struct acpi_table_lapic { } __attribute__ ((packed)); struct acpi_table_ioapic { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 id; u8 reserved; u32 address; @@ -90,7 +85,7 @@ struct acpi_table_ioapic { } __attribute__ ((packed)); struct acpi_table_int_src_ovr { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 bus; u8 bus_irq; u32 global_irq; @@ -98,26 +93,26 @@ struct acpi_table_int_src_ovr { } __attribute__ ((packed)); struct acpi_table_nmi_src { - acpi_table_entry_header header; + struct acpi_subtable_header header; acpi_interrupt_flags flags; u32 global_irq; } __attribute__ ((packed)); struct acpi_table_lapic_nmi { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 acpi_id; acpi_interrupt_flags flags; u8 lint; } __attribute__ ((packed)); struct acpi_table_lapic_addr_ovr { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 reserved[2]; u64 address; } __attribute__ ((packed)); struct acpi_table_iosapic { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 id; u8 reserved; u32 global_irq_base; @@ -125,7 +120,7 @@ struct acpi_table_iosapic { } __attribute__ ((packed)); struct acpi_table_lsapic { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 acpi_id; u8 id; u8 eid; @@ -137,7 +132,7 @@ struct acpi_table_lsapic { } __attribute__ ((packed)); struct acpi_table_plat_int_src { - acpi_table_entry_header header; + struct acpi_subtable_header header; acpi_interrupt_flags flags; u8 type; /* See acpi_interrupt_type */ u8 id; @@ -182,7 +177,7 @@ enum acpi_srat_entry_id { }; struct acpi_table_processor_affinity { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 proximity_domain; u8 apic_id; struct { @@ -194,7 +189,7 @@ struct acpi_table_processor_affinity { } __attribute__ ((packed)); struct acpi_table_memory_affinity { - acpi_table_entry_header header; + struct acpi_subtable_header header; u8 proximity_domain; u8 reserved1[5]; u32 base_addr_lo; @@ -218,33 +213,6 @@ enum acpi_address_range_id { ACPI_ADDRESS_RANGE_COUNT }; -/* Table Handlers */ - -enum acpi_table_id { - ACPI_TABLE_UNKNOWN = 0, - ACPI_APIC, - ACPI_BOOT, - ACPI_DBGP, - ACPI_DSDT, - ACPI_ECDT, - ACPI_ETDT, - ACPI_FADT, - ACPI_FACS, - ACPI_OEMX, - ACPI_PSDT, - ACPI_SBST, - ACPI_SLIT, - ACPI_SPCR, - ACPI_SRAT, - ACPI_SSDT, - ACPI_SPMI, - ACPI_HPET, - ACPI_MCFG, - ACPI_DMAR, - ACPI_IVRS, - ACPI_TABLE_COUNT -}; - /* DMA Remapping Reporting Table (DMAR) */ #define DMAR_FLAGS_INTR_REMAP 0x1 /* intr remap supported */ @@ -306,13 +274,11 @@ struct acpi_pci_path { u8 fn; } __attribute__((packed)); -typedef int (*acpi_dmar_entry_handler) (struct acpi_dmar_entry_header *header, const unsigned long end); - -typedef int (*acpi_table_handler) (unsigned long phys_addr, unsigned long size); - -extern acpi_table_handler acpi_table_ops[ACPI_TABLE_COUNT]; - -typedef int (*acpi_madt_entry_handler) (acpi_table_entry_header *header, const unsigned long end); +typedef int (*acpi_madt_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); + +typedef int (*acpi_table_handler) (struct acpi_table_header *table); + +typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); unsigned int acpi_get_processor_id (unsigned int cpu); char * __acpi_map_table (unsigned long phys_addr, unsigned long size); @@ -322,14 +288,13 @@ 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); -int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); +int acpi_table_parse(char *id, acpi_table_handler handler); +int acpi_table_parse_entries(char *id, unsigned long table_size, + int entry_id, acpi_table_entry_handler handler, unsigned int max_entries); +int acpi_table_parse_madt(enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries); void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); -void acpi_table_print_madt_entry (acpi_table_entry_header *madt); -void acpi_table_print_srat_entry (acpi_table_entry_header *srat); +void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); +void acpi_table_print_srat_entry (struct acpi_subtable_header *srat); uint8_t generate_acpi_checksum(void *tbl, unsigned long len); /* the following four functions are architecture-dependent */ diff -r 7a0f1bf86516 -r 9af7a535225f xen/include/xen/compiler.h --- a/xen/include/xen/compiler.h Tue Jun 10 09:27:01 2008 +0100 +++ b/xen/include/xen/compiler.h Tue Jun 10 13:45:29 2008 +0100 @@ -53,4 +53,10 @@ __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ (typeof(ptr)) (__ptr + (off)); }) +/* + * A trick to suppress uninitialized variable warning without generating any + * code + */ +#define uninitialized_var(x) x = x + #endif /* __LINUX_COMPILER_H */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |