diff --git a/[refs] b/[refs] index 49550d8c86fe..c653cb800548 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e8bdc5a9c56c140c732246a298922c3cf3777460 +refs/heads/master: fe9a2f77e5ad508b18671571c0b3f6f79ea709a8 diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index e94aff6888ca..cbcb2c27f48b 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -66,7 +66,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) + ((acpi_table_entry_header *)entry)->length < sizeof(*entry)) #define PREFIX "ACPI: " @@ -79,7 +79,7 @@ int acpi_ioapic; int acpi_strict; EXPORT_SYMBOL(acpi_strict); -u8 acpi_sci_flags __initdata; +acpi_interrupt_flags acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; int acpi_skip_timer_override __initdata; int acpi_use_timer_override __initdata; @@ -92,6 +92,11 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; #warning ACPI uses CMPXCHG, i486 and later hardware #endif +#define MAX_MADT_ENTRIES 256 +u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = + {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; +EXPORT_SYMBOL(x86_acpiid_to_apicid); + /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ @@ -161,26 +166,30 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #ifdef CONFIG_PCI_MMCONFIG /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -struct acpi_mcfg_allocation *pci_mmcfg_config; +struct acpi_table_mcfg_config *pci_mmcfg_config; int pci_mmcfg_config_num; -int __init acpi_parse_mcfg(struct acpi_table_header *header) +int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; unsigned long i; int config_size; - if (!header) + if (!phys_addr || !size) return -EINVAL; - mcfg = (struct acpi_table_mcfg *)header; + mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); + if (!mcfg) { + printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); + return -ENODEV; + } /* how many config structures do we have */ pci_mmcfg_config_num = 0; - i = header->length - sizeof(struct acpi_table_mcfg); - while (i >= sizeof(struct acpi_mcfg_allocation)) { + i = size - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_table_mcfg_config)) { ++pci_mmcfg_config_num; - i -= sizeof(struct acpi_mcfg_allocation); + i -= sizeof(struct acpi_table_mcfg_config); }; if (pci_mmcfg_config_num == 0) { printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); @@ -195,9 +204,9 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header) return -ENOMEM; } - memcpy(pci_mmcfg_config, &mcfg[1], config_size); + memcpy(pci_mmcfg_config, &mcfg->config, config_size); for (i = 0; i < pci_mmcfg_config_num; ++i) { - if (pci_mmcfg_config[i].address > 0xFFFFFFFF) { + if (mcfg->config[i].base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); kfree(pci_mmcfg_config); @@ -211,24 +220,24 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header) #endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC -static int __init acpi_parse_madt(struct acpi_table_header *table) +static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) { struct acpi_table_madt *madt = NULL; - if (!cpu_has_apic) + if (!phys_addr || !size || !cpu_has_apic) return -EINVAL; - madt = (struct acpi_table_madt *)table; + madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); if (!madt) { printk(KERN_WARNING PREFIX "Unable to map MADT\n"); return -ENODEV; } - if (madt->address) { - acpi_lapic_addr = (u64) madt->address; + if (madt->lapic_address) { + acpi_lapic_addr = (u64) madt->lapic_address; printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", - madt->address); + madt->lapic_address); } acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); @@ -237,17 +246,21 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) } static int __init -acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic *processor = NULL; + struct acpi_table_lapic *processor = NULL; - processor = (struct acpi_madt_local_apic *)header; + processor = (struct acpi_table_lapic *)header; if (BAD_MADT_ENTRY(processor, end)) return -EINVAL; acpi_table_print_madt_entry(header); + /* Record local apic id only when enabled */ + if (processor->flags.enabled) + x86_acpiid_to_apicid[processor->acpi_id] = processor->id; + /* * We need to register disabled CPU as well to permit * counting disabled CPUs. This allows us to size @@ -256,18 +269,18 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) * when we use CPU hotplug. */ mp_register_lapic(processor->id, /* APIC ID */ - processor->lapic_flags & ACPI_MADT_ENABLED); /* Enabled? */ + processor->flags.enabled); /* Enabled? */ return 0; } static int __init -acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, +acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_override *lapic_addr_ovr = NULL; + struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; - lapic_addr_ovr = (struct acpi_madt_local_apic_override *)header; + lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header; if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) return -EINVAL; @@ -278,11 +291,11 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; + struct acpi_table_lapic_nmi *lapic_nmi = NULL; - lapic_nmi = (struct acpi_madt_local_apic_nmi *)header; + lapic_nmi = (struct acpi_table_lapic_nmi *)header; if (BAD_MADT_ENTRY(lapic_nmi, end)) return -EINVAL; @@ -300,11 +313,11 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e #ifdef CONFIG_X86_IO_APIC static int __init -acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_io_apic *ioapic = NULL; + struct acpi_table_ioapic *ioapic = NULL; - ioapic = (struct acpi_madt_io_apic *)header; + ioapic = (struct acpi_table_ioapic *)header; if (BAD_MADT_ENTRY(ioapic, end)) return -EINVAL; @@ -329,11 +342,11 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) polarity = 3; /* Command-line over-ride via acpi_sci= */ - if (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) - trigger = (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2; + if (acpi_sci_flags.trigger) + trigger = acpi_sci_flags.trigger; - if (acpi_sci_flags & ACPI_MADT_POLARITY_MASK) - polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK; + if (acpi_sci_flags.polarity) + polarity = acpi_sci_flags.polarity; /* * mp_config_acpi_legacy_irqs() already setup IRQs < 16 @@ -344,52 +357,51 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) /* * stash over-ride to indicate we've been here - * and for later update of acpi_gbl_FADT + * and for later update of acpi_fadt */ acpi_sci_override_gsi = gsi; return; } static int __init -acpi_parse_int_src_ovr(struct acpi_subtable_header * header, +acpi_parse_int_src_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_interrupt_override *intsrc = NULL; + struct acpi_table_int_src_ovr *intsrc = NULL; - intsrc = (struct acpi_madt_interrupt_override *)header; + intsrc = (struct acpi_table_int_src_ovr *)header; if (BAD_MADT_ENTRY(intsrc, end)) return -EINVAL; acpi_table_print_madt_entry(header); - if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) { + if (intsrc->bus_irq == acpi_fadt.sci_int) { acpi_sci_ioapic_setup(intsrc->global_irq, - intsrc->inti_flags & ACPI_MADT_POLARITY_MASK, - (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2); + intsrc->flags.polarity, + intsrc->flags.trigger); return 0; } if (acpi_skip_timer_override && - intsrc->source_irq == 0 && intsrc->global_irq == 2) { + intsrc->bus_irq == 0 && intsrc->global_irq == 2) { printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); return 0; } - mp_override_legacy_irq(intsrc->source_irq, - intsrc->inti_flags & ACPI_MADT_POLARITY_MASK, - (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2, - intsrc->global_irq); + mp_override_legacy_irq(intsrc->bus_irq, + intsrc->flags.polarity, + intsrc->flags.trigger, intsrc->global_irq); return 0; } static int __init -acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_nmi_source *nmi_src = NULL; + struct acpi_table_nmi_src *nmi_src = NULL; - nmi_src = (struct acpi_madt_nmi_source *)header; + nmi_src = (struct acpi_table_nmi_src *)header; if (BAD_MADT_ENTRY(nmi_src, end)) return -EINVAL; @@ -405,7 +417,7 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end /* * acpi_pic_sci_set_trigger() - * + * * use ELCR to set PIC-mode trigger type for SCI * * If a PIC-mode SCI is not recognized or gives spurious IRQ7's @@ -499,7 +511,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_madt_local_apic *lapic; + struct acpi_table_lapic *lapic; cpumask_t tmp_map, new_map; u8 physid; int cpu; @@ -517,10 +529,10 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) return -EINVAL; } - lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; + lapic = (struct acpi_table_lapic *)obj->buffer.pointer; - if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || - !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { + if ((lapic->header.type != ACPI_MADT_LAPIC) || + (!lapic->flags.enabled)) { kfree(buffer.pointer); return -EINVAL; } @@ -532,7 +544,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) buffer.pointer = NULL; tmp_map = cpu_present_map; - mp_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); + mp_register_lapic(physid, lapic->flags.enabled); /* * If mp_register_lapic successfully generates a new logical cpu @@ -554,6 +566,14 @@ EXPORT_SYMBOL(acpi_map_lsapic); int acpi_unmap_lsapic(int cpu) { + int i; + + for_each_possible_cpu(i) { + if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu]) { + x86_acpiid_to_apicid[i] = -1; + break; + } + } x86_cpu_to_apicid[cpu] = -1; cpu_clear(cpu, cpu_present_map); num_processors--; @@ -599,36 +619,42 @@ acpi_scan_rsdp(unsigned long start, unsigned long length) return 0; } -static int __init acpi_parse_sbf(struct acpi_table_header *table) +static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) { - struct acpi_table_boot *sb; + struct acpi_table_sbf *sb; + + if (!phys_addr || !size) + return -EINVAL; - sb = (struct acpi_table_boot *)table; + sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); if (!sb) { printk(KERN_WARNING PREFIX "Unable to map SBF\n"); return -ENODEV; } - sbf_port = sb->cmos_index; /* Save CMOS port */ + sbf_port = sb->sbf_cmos; /* Save CMOS port */ return 0; } #ifdef CONFIG_HPET_TIMER -static int __init acpi_parse_hpet(struct acpi_table_header *table) +static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) { struct acpi_table_hpet *hpet_tbl; struct resource *hpet_res; resource_size_t res_start; - hpet_tbl = (struct acpi_table_hpet *)table; + 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; } - if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { + if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { printk(KERN_WARNING PREFIX "HPET timers must be located in " "memory.\n"); return -1; @@ -641,28 +667,29 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table) hpet_res->name = (void *)&hpet_res[1]; hpet_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, - "HPET %u", hpet_tbl->sequence); + "HPET %u", hpet_tbl->number); hpet_res->end = (1 * 1024) - 1; } -#ifdef CONFIG_X86_64 - vxtime.hpet_address = hpet_tbl->address.address; +#ifdef CONFIG_X86_64 + vxtime.hpet_address = hpet_tbl->addr.addrl | + ((long)hpet_tbl->addr.addrh << 32); printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", - hpet_tbl->id, vxtime.hpet_address); + hpet_tbl->id, vxtime.hpet_address); res_start = vxtime.hpet_address; -#else /* X86 */ +#else /* X86 */ { extern unsigned long hpet_address; - hpet_address = hpet_tbl->address.address; + hpet_address = hpet_tbl->addr.addrl; printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", - hpet_tbl->id, hpet_address); + hpet_tbl->id, hpet_address); res_start = hpet_address; } -#endif /* X86 */ +#endif /* X86 */ if (hpet_res) { hpet_res->start = res_start; @@ -680,28 +707,42 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table) extern u32 pmtmr_ioport; #endif -static int __init acpi_parse_fadt(struct acpi_table_header *table) +static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) { + struct fadt_descriptor *fadt = NULL; + + fadt = (struct fadt_descriptor *)__acpi_map_table(phys, size); + if (!fadt) { + printk(KERN_WARNING PREFIX "Unable to map FADT\n"); + return 0; + } + /* initialize sci_int early for INT_SRC_OVR MADT parsing */ + acpi_fadt.sci_int = fadt->sci_int; + + /* initialize rev and apic_phys_dest_mode for x86_64 genapic */ + acpi_fadt.revision = fadt->revision; + acpi_fadt.force_apic_physical_destination_mode = + fadt->force_apic_physical_destination_mode; #ifdef CONFIG_X86_PM_TIMER /* detect the location of the ACPI PM Timer */ - if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) { + if (fadt->revision >= FADT2_REVISION_ID) { /* FADT rev. 2 */ - if (acpi_gbl_FADT.xpm_timer_block.space_id != + if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO) return 0; - pmtmr_ioport = acpi_gbl_FADT.xpm_timer_block.address; + pmtmr_ioport = fadt->xpm_tmr_blk.address; /* * "X" fields are optional extensions to the original V1.0 * fields, so we must selectively expand V1.0 fields if the * corresponding X field is zero. */ if (!pmtmr_ioport) - pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; + pmtmr_ioport = fadt->V1_pm_tmr_blk; } else { /* FADT rev. 1 */ - pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; + pmtmr_ioport = fadt->V1_pm_tmr_blk; } if (pmtmr_ioport) printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", @@ -743,13 +784,13 @@ static int __init acpi_parse_madt_lapic_entries(void) if (!cpu_has_apic) return -ENODEV; - /* + /* * Note that the LAPIC address is obtained from the MADT (32-bit value) * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). */ count = - acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, + acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); if (count < 0) { printk(KERN_ERR PREFIX @@ -759,7 +800,7 @@ static int __init acpi_parse_madt_lapic_entries(void) mp_register_lapic_address(acpi_lapic_addr); - count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, acpi_parse_lapic, + count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, MAX_APICS); if (!count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); @@ -772,7 +813,7 @@ static int __init acpi_parse_madt_lapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0); + acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* TBD: Cleanup to allow fallback to MPS */ @@ -801,7 +842,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) return -ENODEV; } - if (!cpu_has_apic) + if (!cpu_has_apic) return -ENODEV; /* @@ -814,7 +855,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic, + acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); if (!count) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); @@ -825,7 +866,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, + acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); if (count < 0) { printk(KERN_ERR PREFIX @@ -839,13 +880,13 @@ static int __init acpi_parse_madt_ioapic_entries(void) * pretend we got one so we can set the SCI flags. */ if (!acpi_sci_override_gsi) - acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0); + acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); count = - acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, + acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); @@ -867,7 +908,7 @@ static void __init acpi_process_madt(void) #ifdef CONFIG_X86_LOCAL_APIC int count, error; - count = acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt); + count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); if (count >= 1) { /* @@ -1154,7 +1195,7 @@ int __init acpi_boot_table_init(void) if (acpi_disabled && !acpi_ht) return 1; - /* + /* * Initialize the ACPI boot-time table parser. */ error = acpi_table_init(); @@ -1163,7 +1204,7 @@ int __init acpi_boot_table_init(void) return error; } - acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); /* * blacklist may disable ACPI entirely @@ -1191,19 +1232,19 @@ int __init acpi_boot_init(void) if (acpi_disabled && !acpi_ht) return 1; - acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); /* * set sci_int and PM timer address */ - acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt); + acpi_table_parse(ACPI_FADT, acpi_parse_fadt); /* * Process the Multiple APIC Description Table (MADT), if present */ acpi_process_madt(); - acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); + acpi_table_parse(ACPI_HPET, acpi_parse_hpet); return 0; } @@ -1274,17 +1315,13 @@ static int __init setup_acpi_sci(char *s) if (!s) return -EINVAL; if (!strcmp(s, "edge")) - acpi_sci_flags = ACPI_MADT_TRIGGER_EDGE | - (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK); + acpi_sci_flags.trigger = 1; else if (!strcmp(s, "level")) - acpi_sci_flags = ACPI_MADT_TRIGGER_LEVEL | - (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK); + acpi_sci_flags.trigger = 3; else if (!strcmp(s, "high")) - acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_HIGH | - (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK); + acpi_sci_flags.polarity = 1; else if (!strcmp(s, "low")) - acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_LOW | - (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK); + acpi_sci_flags.polarity = 3; else return -EINVAL; return 0; diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index bf86f7662d8b..4b60af7f91dd 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -16,7 +16,7 @@ static int nvidia_hpet_detected __initdata; -static int __init nvidia_hpet_check(struct acpi_table_header *header) +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) { nvidia_hpet_detected = 1; return 0; @@ -30,7 +30,7 @@ static int __init check_bridge(int vendor, int device) is enabled. */ if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); + acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c index a3db9332d652..e940e00b96c9 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -190,7 +190,7 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index) /* Invoke C3 */ inb(cx_address); /* Dummy op - must do something useless after P_LVL3 read */ - t = inl(acpi_gbl_FADT.xpm_timer_block.address); + t = inl(acpi_fadt.xpm_tmr_blk.address); } /* Disable bus ratio bit */ local_irq_disable(); @@ -250,7 +250,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index) outb(3, 0x22); } else if ((pr != NULL) && pr->flags.bm_control) { /* Disable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, + ACPI_MTX_DO_NOT_LOCK); } switch (longhaul_version) { @@ -280,7 +281,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index) case TYPE_POWERSAVER: if (longhaul_flags & USE_ACPI_C3) { /* Don't allow wakeup */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, + ACPI_MTX_DO_NOT_LOCK); do_powersaver(cx->address, clock_ratio_index); } else { do_powersaver(0, clock_ratio_index); @@ -293,7 +295,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index) outb(0, 0x22); } else if ((pr != NULL) && pr->flags.bm_control) { /* Enable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, + ACPI_MTX_DO_NOT_LOCK); } outb(pic2_mask,0xA1); /* restore mask */ outb(pic1_mask,0x21); @@ -411,7 +414,7 @@ static int __init longhaul_get_ranges(void) highest_speed = calc_speed(maxmult); lowest_speed = calc_speed(minmult); dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, - print_speed(lowest_speed/1000), + print_speed(lowest_speed/1000), print_speed(highest_speed/1000)); if (lowest_speed == highest_speed) { @@ -495,7 +498,7 @@ static void __init longhaul_setup_voltagescaling(void) maxvid.mV/1000, maxvid.mV%1000, minvid.mV/1000, minvid.mV%1000, numvscales); - + j = 0; while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) { speed = longhaul_table[j].frequency; diff --git a/trunk/arch/i386/kernel/mpparse.c b/trunk/arch/i386/kernel/mpparse.c index 4f5983c98669..49bff3596bff 100644 --- a/trunk/arch/i386/kernel/mpparse.c +++ b/trunk/arch/i386/kernel/mpparse.c @@ -1057,7 +1057,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) static int gsi_to_irq[MAX_GSI_NUM]; /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_gbl_FADT.sci_interrupt == gsi) + if (acpi_fadt.sci_int == gsi) return gsi; ioapic = mp_find_ioapic(gsi); @@ -1114,7 +1114,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) /* * Don't assign IRQ used by ACPI SCI */ - if (gsi == acpi_gbl_FADT.sci_interrupt) + if (gsi == acpi_fadt.sci_int) gsi = pci_irq++; gsi_to_irq[irq] = gsi; } else { diff --git a/trunk/arch/i386/kernel/srat.c b/trunk/arch/i386/kernel/srat.c index 2a8713ec0f9a..f7e735c077c3 100644 --- a/trunk/arch/i386/kernel/srat.c +++ b/trunk/arch/i386/kernel/srat.c @@ -62,19 +62,19 @@ extern void * boot_ioremap(unsigned long, unsigned long); /* Identify CPU proximity domains */ static void __init parse_cpu_affinity_structure(char *p) { - struct acpi_srat_cpu_affinity *cpu_affinity = - (struct acpi_srat_cpu_affinity *) p; + struct acpi_table_processor_affinity *cpu_affinity = + (struct acpi_table_processor_affinity *) p; - if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0) + if (!cpu_affinity->flags.enabled) return; /* empty entry */ /* mark this node as "seen" in node bitmap */ - BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo); + BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain); - apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo; + apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain; printk("CPU 0x%02X in proximity domain 0x%02X\n", - cpu_affinity->apic_id, cpu_affinity->proximity_domain_lo); + cpu_affinity->apic_id, cpu_affinity->proximity_domain); } /* @@ -84,27 +84,28 @@ static void __init parse_cpu_affinity_structure(char *p) static void __init parse_memory_affinity_structure (char *sratp) { unsigned long long paddr, size; - unsigned long start_pfn, end_pfn; + unsigned long start_pfn, end_pfn; u8 pxm; struct node_memory_chunk_s *p, *q, *pend; - struct acpi_srat_mem_affinity *memory_affinity = - (struct acpi_srat_mem_affinity *) sratp; + struct acpi_table_memory_affinity *memory_affinity = + (struct acpi_table_memory_affinity *) sratp; - if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0) + if (!memory_affinity->flags.enabled) return; /* empty entry */ - pxm = memory_affinity->proximity_domain & 0xff; - /* mark this node as "seen" in node bitmap */ - BMAP_SET(pxm_bitmap, pxm); + BMAP_SET(pxm_bitmap, memory_affinity->proximity_domain); /* calculate info for memory chunk structure */ - paddr = memory_affinity->base_address; - size = memory_affinity->length; - + paddr = memory_affinity->base_addr_hi; + paddr = (paddr << 32) | memory_affinity->base_addr_lo; + size = memory_affinity->length_hi; + size = (size << 32) | memory_affinity->length_lo; + start_pfn = paddr >> PAGE_SHIFT; end_pfn = (paddr + size) >> PAGE_SHIFT; - + + pxm = memory_affinity->proximity_domain; if (num_memory_chunks >= MAXCHUNKS) { printk("Too many mem chunks in SRAT. Ignoring %lld MBytes at %llx\n", @@ -131,8 +132,8 @@ static void __init parse_memory_affinity_structure (char *sratp) printk("Memory range 0x%lX to 0x%lX (type 0x%X) in proximity domain 0x%02X %s\n", start_pfn, end_pfn, memory_affinity->memory_type, - pxm, - ((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ? + memory_affinity->proximity_domain, + (memory_affinity->flags.hot_pluggable ? "enabled and removable" : "enabled" ) ); } @@ -184,10 +185,10 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) num_memory_chunks = 0; while (p < end) { switch (*p) { - case ACPI_SRAT_TYPE_CPU_AFFINITY: + case ACPI_SRAT_PROCESSOR_AFFINITY: parse_cpu_affinity_structure(p); break; - case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + case ACPI_SRAT_MEMORY_AFFINITY: parse_memory_affinity_structure(p); break; default: @@ -261,30 +262,31 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) return 0; } -struct acpi_static_rsdt { - struct acpi_table_rsdt table; - u32 padding[7]; /* Allow for 7 more table entries */ -}; - int __init get_memcfg_from_srat(void) { struct acpi_table_header *header = NULL; struct acpi_table_rsdp *rsdp = NULL; struct acpi_table_rsdt *rsdt = NULL; - acpi_native_uint rsdp_address = 0; - struct acpi_static_rsdt saved_rsdt; + struct acpi_pointer *rsdp_address = NULL; + struct acpi_table_rsdt saved_rsdt; int tables = 0; int i = 0; - rsdp_address = acpi_find_rsdp(); - if (!rsdp_address) { + if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, + rsdp_address))) { printk("%s: System description tables not found\n", __FUNCTION__); goto out_err; } - printk("%s: assigning address to rsdp\n", __FUNCTION__); - rsdp = (struct acpi_table_rsdp *)(u32)rsdp_address; + if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) { + printk("%s: assigning address to rsdp\n", __FUNCTION__); + rsdp = (struct acpi_table_rsdp *) + (u32)rsdp_address->pointer.physical; + } else { + printk("%s: rsdp_address is not a physical pointer\n", __FUNCTION__); + goto out_err; + } if (!rsdp) { printk("%s: Didn't find ACPI root!\n", __FUNCTION__); goto out_err; @@ -293,13 +295,13 @@ int __init get_memcfg_from_srat(void) printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision, rsdp->oem_id); - if (strncmp(rsdp->signature, ACPI_SIG_RSDP,strlen(ACPI_SIG_RSDP))) { + if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) { printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __FUNCTION__); goto out_err; } rsdt = (struct acpi_table_rsdt *) - boot_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt)); + boot_ioremap(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt)); if (!rsdt) { printk(KERN_WARNING @@ -308,9 +310,9 @@ int __init get_memcfg_from_srat(void) goto out_err; } - header = &rsdt->header; + header = & rsdt->header; - if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) { + if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) { printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); goto out_err; } @@ -328,9 +330,9 @@ int __init get_memcfg_from_srat(void) memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); - if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) { + if (saved_rsdt.header.length > sizeof(saved_rsdt)) { printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", - saved_rsdt.table.header.length); + saved_rsdt.header.length); goto out_err; } @@ -339,15 +341,15 @@ int __init get_memcfg_from_srat(void) for (i = 0; i < tables; i++) { /* Map in header, then map in full table length. */ header = (struct acpi_table_header *) - boot_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header)); + boot_ioremap(saved_rsdt.entry[i], sizeof(struct acpi_table_header)); if (!header) break; header = (struct acpi_table_header *) - boot_ioremap(saved_rsdt.table.table_offset_entry[i], header->length); + boot_ioremap(saved_rsdt.entry[i], header->length); if (!header) break; - if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4)) + if (strncmp((char *) &header->signature, "SRAT", 4)) continue; /* we've found the srat table. don't need to look at any more tables */ diff --git a/trunk/arch/i386/mach-es7000/es7000.h b/trunk/arch/i386/mach-es7000/es7000.h index c8d5aa132fa0..80566ca4a80a 100644 --- a/trunk/arch/i386/mach-es7000/es7000.h +++ b/trunk/arch/i386/mach-es7000/es7000.h @@ -84,6 +84,15 @@ struct es7000_oem_table { }; #ifdef CONFIG_ACPI +struct acpi_table_sdt { + unsigned long pa; + unsigned long count; + struct { + unsigned long pa; + enum acpi_table_id id; + unsigned long size; + } entry[50]; +}; struct oem_table { struct acpi_table_header Header; diff --git a/trunk/arch/i386/mach-es7000/es7000plat.c b/trunk/arch/i386/mach-es7000/es7000plat.c index 9be6ceabf042..3d0fc853516d 100644 --- a/trunk/arch/i386/mach-es7000/es7000plat.c +++ b/trunk/arch/i386/mach-es7000/es7000plat.c @@ -160,14 +160,51 @@ parse_unisys_oem (char *oemptr) int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { - struct acpi_table_header *header = NULL; - int i = 0; - while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) { - if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { - struct oem_table *t = (struct oem_table *)header; - *oem_addr = (unsigned long)__acpi_map_table(t->OEMTableAddr, - t->OEMTableSize); - return 0; + struct acpi_table_rsdp *rsdp = NULL; + unsigned long rsdp_phys = 0; + struct acpi_table_header *header = NULL; + int i; + struct acpi_table_sdt sdt; + + rsdp_phys = acpi_find_rsdp(); + rsdp = __va(rsdp_phys); + if (rsdp->rsdt_address) { + struct acpi_table_rsdt *mapped_rsdt = NULL; + sdt.pa = rsdp->rsdt_address; + + header = (struct acpi_table_header *) + __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); + if (!header) + return -ENODEV; + + sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3; + mapped_rsdt = (struct acpi_table_rsdt *) + __acpi_map_table(sdt.pa, header->length); + if (!mapped_rsdt) + return -ENODEV; + + header = &mapped_rsdt->header; + + for (i = 0; i < sdt.count; i++) + sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; + }; + for (i = 0; i < sdt.count; i++) { + + header = (struct acpi_table_header *) + __acpi_map_table(sdt.entry[i].pa, + sizeof(struct acpi_table_header)); + if (!header) + continue; + if (!strncmp((char *) &header->signature, "OEM1", 4)) { + if (!strncmp((char *) &header->oem_id, "UNISYS", 6)) { + void *addr; + struct oem_table *t; + acpi_table_print(header, sdt.entry[i].pa); + t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length); + addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize); + *oem_addr = (unsigned long) addr; + return 0; + } } } return -1; diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index 5700220dcf5f..e2616a266e13 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -36,7 +36,7 @@ static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) { int cfg_num = -1; - struct acpi_mcfg_allocation *cfg; + struct acpi_table_mcfg_config *cfg; if (seg == 0 && bus < MAX_CHECK_BUS && test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) @@ -48,11 +48,11 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) break; } cfg = &pci_mmcfg_config[cfg_num]; - if (cfg->pci_segment != seg) + if (cfg->pci_segment_group_number != seg) continue; if ((cfg->start_bus_number <= bus) && (cfg->end_bus_number >= bus)) - return cfg->address; + return cfg->base_address; } /* Handle more broken MCFG tables on Asus etc. @@ -60,9 +60,9 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) this applies to all busses. */ cfg = &pci_mmcfg_config[0]; if (pci_mmcfg_config_num == 1 && - cfg->pci_segment == 0 && + cfg->pci_segment_group_number == 0 && (cfg->start_bus_number | cfg->end_bus_number) == 0) - return cfg->address; + return cfg->base_address; /* Fall back to type 0 */ return 0; @@ -125,7 +125,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned long flags; u32 base; - if ((bus > 255) || (devfn > 255) || (reg > 4095)) + if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; base = get_base_addr(seg, bus, devfn); @@ -199,19 +199,19 @@ void __init pci_mmcfg_init(int type) if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; - acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); if ((pci_mmcfg_config_num == 0) || (pci_mmcfg_config == NULL) || - (pci_mmcfg_config[0].address == 0)) + (pci_mmcfg_config[0].base_address == 0)) return; /* Only do this check when type 1 works. If it doesn't work assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].address, - pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, + if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %lx is not E820-reserved\n", - (unsigned long)pci_mmcfg_config[0].address); + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", + pci_mmcfg_config[0].base_address); printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); return; } diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index a99b0cc92881..ef2fe474f107 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -55,7 +55,7 @@ #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) + ((acpi_table_entry_header *)entry)->length < sizeof(*entry)) #define PREFIX "ACPI: " @@ -67,11 +67,16 @@ EXPORT_SYMBOL(pm_power_off); unsigned int acpi_cpei_override; unsigned int acpi_cpei_phys_cpuid; +#define MAX_SAPICS 256 +u16 ia64_acpiid_to_sapicid[MAX_SAPICS] = {[0 ... MAX_SAPICS - 1] = -1 }; + +EXPORT_SYMBOL(ia64_acpiid_to_sapicid); + const char *acpi_get_sysname(void) { #ifdef CONFIG_IA64_GENERIC unsigned long rsdp_phys; - struct acpi_table_rsdp *rsdp; + struct acpi20_table_rsdp *rsdp; struct acpi_table_xsdt *xsdt; struct acpi_table_header *hdr; @@ -82,16 +87,16 @@ const char *acpi_get_sysname(void) return "dig"; } - rsdp = (struct acpi_table_rsdp *)__va(rsdp_phys); - if (strncmp(rsdp->signature, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)) { + rsdp = (struct acpi20_table_rsdp *)__va(rsdp_phys); + if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) { printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n"); return "dig"; } - xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_physical_address); + xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_address); hdr = &xsdt->header; - if (strncmp(hdr->signature, ACPI_SIG_XSDT, sizeof(ACPI_SIG_XSDT) - 1)) { + if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) { printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n"); return "dig"; @@ -164,12 +169,12 @@ struct acpi_table_madt *acpi_madt __initdata; static u8 has_8259; static int __init -acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, +acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_override *lapic; + struct acpi_table_lapic_addr_ovr *lapic; - lapic = (struct acpi_madt_local_apic_override *)header; + lapic = (struct acpi_table_lapic_addr_ovr *)header; if (BAD_MADT_ENTRY(lapic, end)) return -EINVAL; @@ -182,19 +187,22 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lsapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_sapic *lsapic; + struct acpi_table_lsapic *lsapic; - lsapic = (struct acpi_madt_local_sapic *)header; + lsapic = (struct acpi_table_lsapic *)header; - /*Skip BAD_MADT_ENTRY check, as lsapic size could vary */ + if (BAD_MADT_ENTRY(lsapic, end)) + return -EINVAL; - if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { + if (lsapic->flags.enabled) { #ifdef CONFIG_SMP smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid; #endif + ia64_acpiid_to_sapicid[lsapic->acpi_id] = + (lsapic->id << 8) | lsapic->eid; ++available_cpus; } @@ -203,11 +211,11 @@ acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end) } static int __init -acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_local_apic_nmi *lacpi_nmi; + struct acpi_table_lapic_nmi *lacpi_nmi; - lacpi_nmi = (struct acpi_madt_local_apic_nmi *)header; + lacpi_nmi = (struct acpi_table_lapic_nmi *)header; if (BAD_MADT_ENTRY(lacpi_nmi, end)) return -EINVAL; @@ -217,11 +225,11 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e } static int __init -acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_iosapic(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_io_sapic *iosapic; + struct acpi_table_iosapic *iosapic; - iosapic = (struct acpi_madt_io_sapic *)header; + iosapic = (struct acpi_table_iosapic *)header; if (BAD_MADT_ENTRY(iosapic, end)) return -EINVAL; @@ -232,13 +240,13 @@ acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end static unsigned int __initdata acpi_madt_rev; static int __init -acpi_parse_plat_int_src(struct acpi_subtable_header * header, +acpi_parse_plat_int_src(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_interrupt_source *plintsrc; + struct acpi_table_plat_int_src *plintsrc; int vector; - plintsrc = (struct acpi_madt_interrupt_source *)header; + plintsrc = (struct acpi_table_plat_int_src *)header; if (BAD_MADT_ENTRY(plintsrc, end)) return -EINVAL; @@ -249,19 +257,19 @@ acpi_parse_plat_int_src(struct acpi_subtable_header * header, */ vector = iosapic_register_platform_intr(plintsrc->type, plintsrc->global_irq, - plintsrc->io_sapic_vector, + plintsrc->iosapic_vector, plintsrc->eid, plintsrc->id, - ((plintsrc->inti_flags & ACPI_MADT_POLARITY_MASK) == - ACPI_MADT_POLARITY_ACTIVE_HIGH) ? - IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - ((plintsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) == - ACPI_MADT_TRIGGER_EDGE) ? - IOSAPIC_EDGE : IOSAPIC_LEVEL); + (plintsrc->flags.polarity == + 1) ? IOSAPIC_POL_HIGH : + IOSAPIC_POL_LOW, + (plintsrc->flags.trigger == + 1) ? IOSAPIC_EDGE : + IOSAPIC_LEVEL); platform_intr_list[plintsrc->type] = vector; if (acpi_madt_rev > 1) { - acpi_cpei_override = plintsrc->flags & ACPI_MADT_CPEI_OVERRIDE; + acpi_cpei_override = plintsrc->plint_flags.cpei_override_flag; } /* @@ -316,32 +324,30 @@ unsigned int get_cpei_target_cpu(void) } static int __init -acpi_parse_int_src_ovr(struct acpi_subtable_header * header, +acpi_parse_int_src_ovr(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_interrupt_override *p; + struct acpi_table_int_src_ovr *p; - p = (struct acpi_madt_interrupt_override *)header; + p = (struct acpi_table_int_src_ovr *)header; if (BAD_MADT_ENTRY(p, end)) return -EINVAL; - iosapic_override_isa_irq(p->source_irq, p->global_irq, - ((p->inti_flags & ACPI_MADT_POLARITY_MASK) == - ACPI_MADT_POLARITY_ACTIVE_HIGH) ? - IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - ((p->inti_flags & ACPI_MADT_TRIGGER_MASK) == - ACPI_MADT_TRIGGER_EDGE) ? - IOSAPIC_EDGE : IOSAPIC_LEVEL); + iosapic_override_isa_irq(p->bus_irq, p->global_irq, + (p->flags.polarity == + 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (p->flags.trigger == + 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); return 0; } static int __init -acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_madt_nmi_source *nmi_src; + struct acpi_table_nmi_src *nmi_src; - nmi_src = (struct acpi_madt_nmi_source *)header; + nmi_src = (struct acpi_table_nmi_src *)header; if (BAD_MADT_ENTRY(nmi_src, end)) return -EINVAL; @@ -365,12 +371,12 @@ static void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) } } -static int __init acpi_parse_madt(struct acpi_table_header *table) +static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) { - if (!table) + if (!phys_addr || !size) return -EINVAL; - acpi_madt = (struct acpi_table_madt *)table; + acpi_madt = (struct acpi_table_madt *)__va(phys_addr); acpi_madt_rev = acpi_madt->header.revision; @@ -378,14 +384,14 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) #ifdef CONFIG_ITANIUM has_8259 = 1; /* Firmware on old Itanium systems is broken */ #else - has_8259 = acpi_madt->flags & ACPI_MADT_PCAT_COMPAT; + has_8259 = acpi_madt->flags.pcat_compat; #endif iosapic_system_init(has_8259); /* Get base address of IPI Message Block */ - if (acpi_madt->address) - ipi_base_addr = ioremap(acpi_madt->address, 0); + if (acpi_madt->lapic_address) + ipi_base_addr = ioremap(acpi_madt->lapic_address, 0); printk(KERN_INFO PREFIX "Local APIC address %p\n", ipi_base_addr); @@ -407,24 +413,23 @@ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN]; #define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag)) static struct acpi_table_slit __initdata *slit_table; -static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa) +static int get_processor_proximity_domain(struct acpi_table_processor_affinity *pa) { int pxm; - pxm = pa->proximity_domain_lo; + pxm = pa->proximity_domain; if (ia64_platform_is("sn2")) - pxm += pa->proximity_domain_hi[0] << 8; + pxm += pa->reserved[0] << 8; return pxm; } -static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma) +static int get_memory_proximity_domain(struct acpi_table_memory_affinity *ma) { int pxm; pxm = ma->proximity_domain; - if (!ia64_platform_is("sn2")) - pxm &= 0xff; - + if (ia64_platform_is("sn2")) + pxm += ma->reserved1[0] << 8; return pxm; } @@ -437,7 +442,7 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) u32 len; len = sizeof(struct acpi_table_header) + 8 - + slit->locality_count * slit->locality_count; + + slit->localities * slit->localities; if (slit->header.length != len) { printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", @@ -449,11 +454,11 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) } void __init -acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) +acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) { int pxm; - if (!(pa->flags & ACPI_SRAT_CPU_ENABLED)) + if (!pa->flags.enabled) return; pxm = get_processor_proximity_domain(pa); @@ -462,14 +467,14 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) pxm_bit_set(pxm); node_cpuid[srat_num_cpus].phys_id = - (pa->apic_id << 8) | (pa->local_sapic_eid); + (pa->apic_id << 8) | (pa->lsapic_eid); /* nid should be overridden as logical node id later */ node_cpuid[srat_num_cpus].nid = pxm; srat_num_cpus++; } void __init -acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) +acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) { unsigned long paddr, size; int pxm; @@ -478,11 +483,13 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) pxm = get_memory_proximity_domain(ma); /* fill node memory chunk structure */ - paddr = ma->base_address; - size = ma->length; + paddr = ma->base_addr_hi; + paddr = (paddr << 32) | ma->base_addr_lo; + size = ma->length_hi; + size = (size << 32) | ma->length_lo; /* Ignore disabled entries */ - if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) + if (!ma->flags.enabled) return; /* record this node in proximity bitmap */ @@ -553,16 +560,16 @@ void __init acpi_numa_arch_fixup(void) if (!slit_table) return; memset(numa_slit, -1, sizeof(numa_slit)); - for (i = 0; i < slit_table->locality_count; i++) { + for (i = 0; i < slit_table->localities; i++) { if (!pxm_bit_test(i)) continue; node_from = pxm_to_node(i); - for (j = 0; j < slit_table->locality_count; j++) { + for (j = 0; j < slit_table->localities; j++) { if (!pxm_bit_test(j)) continue; node_to = pxm_to_node(j); node_distance(node_from, node_to) = - slit_table->entry[i * slit_table->locality_count + j]; + slit_table->entry[i * slit_table->localities + j]; } } @@ -607,21 +614,21 @@ void acpi_unregister_gsi(u32 gsi) EXPORT_SYMBOL(acpi_unregister_gsi); -static int __init acpi_parse_fadt(struct acpi_table_header *table) +static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size) { struct acpi_table_header *fadt_header; - struct acpi_table_fadt *fadt; + struct fadt_descriptor *fadt; - if (!table) + if (!phys_addr || !size) return -EINVAL; - fadt_header = (struct acpi_table_header *)table; + fadt_header = (struct acpi_table_header *)__va(phys_addr); if (fadt_header->revision != 3) return -ENODEV; /* Only deal with ACPI 2.0 FADT */ - fadt = (struct acpi_table_fadt *)fadt_header; + fadt = (struct fadt_descriptor *)fadt_header; - acpi_register_gsi(fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); + acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return 0; } @@ -648,7 +655,7 @@ int __init acpi_boot_init(void) * information -- the successor to MPS tables. */ - if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt) < 1) { + if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) { printk(KERN_ERR PREFIX "Can't find MADT\n"); goto skip_madt; } @@ -656,40 +663,40 @@ int __init acpi_boot_init(void) /* Local APIC */ if (acpi_table_parse_madt - (ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, acpi_parse_lapic_addr_ovr, 0) < 0) + (ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, acpi_parse_lsapic, NR_CPUS) + if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); - if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0) + if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* I/O APIC */ if (acpi_table_parse_madt - (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) + (ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n"); /* System-Level Interrupt Routing */ if (acpi_table_parse_madt - (ACPI_MADT_TYPE_INTERRUPT_SOURCE, acpi_parse_plat_int_src, + (ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0) printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n"); if (acpi_table_parse_madt - (ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, 0) < 0) + (ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0) printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, 0) < 0) + if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, 0) < 0) printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); skip_madt: @@ -699,7 +706,7 @@ int __init 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_SIG_FADT, acpi_parse_fadt) < 1) + if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1) printk(KERN_ERR PREFIX "Can't find FADT\n"); #ifdef CONFIG_SMP @@ -832,7 +839,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_madt_local_sapic *lsapic; + struct acpi_table_lsapic *lsapic; cpumask_t tmp_map; long physid; int cpu; @@ -844,16 +851,16 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) return -EINVAL; obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER) - { + if (obj->type != ACPI_TYPE_BUFFER || + obj->buffer.length < sizeof(*lsapic)) { kfree(buffer.pointer); return -EINVAL; } - lsapic = (struct acpi_madt_local_sapic *)obj->buffer.pointer; + lsapic = (struct acpi_table_lsapic *)obj->buffer.pointer; - if ((lsapic->header.type != ACPI_MADT_TYPE_LOCAL_SAPIC) || - (!lsapic->lapic_flags & ACPI_MADT_ENABLED)) { + if ((lsapic->header.type != ACPI_MADT_LSAPIC) || + (!lsapic->flags.enabled)) { kfree(buffer.pointer); return -EINVAL; } @@ -873,6 +880,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) cpu_set(cpu, cpu_present_map); ia64_cpu_to_sapicid[cpu] = physid; + ia64_acpiid_to_sapicid[lsapic->acpi_id] = ia64_cpu_to_sapicid[cpu]; *pcpu = cpu; return (0); @@ -882,6 +890,14 @@ EXPORT_SYMBOL(acpi_map_lsapic); int acpi_unmap_lsapic(int cpu) { + int i; + + for (i = 0; i < MAX_SAPICS; i++) { + if (ia64_acpiid_to_sapicid[i] == ia64_cpu_to_sapicid[cpu]) { + ia64_acpiid_to_sapicid[i] = -1; + break; + } + } ia64_cpu_to_sapicid[cpu] = -1; cpu_clear(cpu, cpu_present_map); @@ -901,7 +917,7 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_madt_io_sapic *iosapic; + struct acpi_table_iosapic *iosapic; unsigned int gsi_base; int pxm, node; @@ -919,9 +935,9 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) return AE_OK; } - iosapic = (struct acpi_madt_io_sapic *)obj->buffer.pointer; + iosapic = (struct acpi_table_iosapic *)obj->buffer.pointer; - if (iosapic->header.type != ACPI_MADT_TYPE_IO_SAPIC) { + if (iosapic->header.type != ACPI_MADT_IOSAPIC) { kfree(buffer.pointer); return AE_OK; } diff --git a/trunk/arch/ia64/sn/kernel/io_acpi_init.c b/trunk/arch/ia64/sn/kernel/io_acpi_init.c index 8c331ca6e5c9..cb96b4ea7df6 100644 --- a/trunk/arch/ia64/sn/kernel/io_acpi_init.c +++ b/trunk/arch/ia64/sn/kernel/io_acpi_init.c @@ -13,7 +13,6 @@ #include #include "xtalk/hubdev.h" #include -#include /* @@ -32,12 +31,6 @@ struct acpi_vendor_uuid sn_uuid = { 0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 }, }; -struct sn_pcidev_match { - u8 bus; - unsigned int devfn; - acpi_handle handle; -}; - /* * Perform the early IO init in PROM. */ @@ -126,11 +119,9 @@ sn_get_bussoft_ptr(struct pci_bus *bus) status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, &sn_uuid, &buffer); if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: " - "acpi_get_vendor_resource() failed (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); + printk(KERN_ERR "get_acpi_pcibus_ptr: " + "get_acpi_bussoft_info() failed: %d\n", + status); return NULL; } resource = buffer.pointer; @@ -139,8 +130,8 @@ sn_get_bussoft_ptr(struct pci_bus *bus) if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != sizeof(struct pcibus_bussoft *)) { printk(KERN_ERR - "%s: Invalid vendor data length %d\n", - __FUNCTION__, vendor->byte_length); + "get_acpi_bussoft_ptr: Invalid vendor data " + "length %d\n", vendor->byte_length); kfree(buffer.pointer); return NULL; } @@ -152,254 +143,34 @@ sn_get_bussoft_ptr(struct pci_bus *bus) } /* - * sn_extract_device_info - Extract the pcidev_info and the sn_irq_info - * pointers from the vendor resource using the - * provided acpi handle, and copy the structures - * into the argument buffers. - */ -static int -sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, - struct sn_irq_info **sn_irq_info) -{ - u64 addr; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct sn_irq_info *irq_info, *irq_info_prom; - struct pcidev_info *pcidev_ptr, *pcidev_prom_ptr; - struct acpi_resource *resource; - int ret = 0; - acpi_status status; - struct acpi_resource_vendor_typed *vendor; - - /* - * The pointer to this device's pcidev_info structure in - * the PROM, is in the vendor resource. - */ - status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, - &sn_uuid, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR - "%s: acpi_get_vendor_resource() failed (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - return 1; - } - - resource = buffer.pointer; - vendor = &resource->data.vendor_typed; - if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != - sizeof(struct pci_devdev_info *)) { - printk(KERN_ERR - "%s: Invalid vendor data length: %d for: ", - __FUNCTION__, vendor->byte_length); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - ret = 1; - goto exit; - } - - pcidev_ptr = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (!pcidev_ptr) - panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__); - - memcpy(&addr, vendor->byte_data, sizeof(struct pcidev_info *)); - pcidev_prom_ptr = __va(addr); - memcpy(pcidev_ptr, pcidev_prom_ptr, sizeof(struct pcidev_info)); - - /* Get the IRQ info */ - irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (!irq_info) - panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__); - - if (pcidev_ptr->pdi_sn_irq_info) { - irq_info_prom = __va(pcidev_ptr->pdi_sn_irq_info); - memcpy(irq_info, irq_info_prom, sizeof(struct sn_irq_info)); - } - - *pcidev_info = pcidev_ptr; - *sn_irq_info = irq_info; - -exit: - kfree(buffer.pointer); - return ret; -} - -static unsigned int -get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) -{ - unsigned long adr; - acpi_handle child; - unsigned int devfn; - int function; - acpi_handle parent; - int slot; - acpi_status status; - - /* - * Do an upward search to find the root bus device, and - * obtain the host devfn from the previous child device. - */ - child = device_handle; - while (child) { - status = acpi_get_parent(child, &parent); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: acpi_get_parent() failed " - "(0x%x) for: ", __FUNCTION__, status); - acpi_ns_print_node_pathname(child, NULL); - printk("\n"); - panic("%s: Unable to find host devfn\n", __FUNCTION__); - } - if (parent == rootbus_handle) - break; - child = parent; - } - if (!child) { - printk(KERN_ERR "%s: Unable to find root bus for: ", - __FUNCTION__); - acpi_ns_print_node_pathname(device_handle, NULL); - printk("\n"); - BUG(); - } - - status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(child, NULL); - printk("\n"); - panic("%s: Unable to find host devfn\n", __FUNCTION__); - } - - slot = (adr >> 16) & 0xffff; - function = adr & 0xffff; - devfn = PCI_DEVFN(slot, function); - return devfn; -} - -/* - * find_matching_device - Callback routine to find the ACPI device - * that matches up with our pci_dev device. - * Matching is done on bus number and devfn. - * To find the bus number for a particular - * ACPI device, we must look at the _BBN method - * of its parent. - */ -static acpi_status -find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - unsigned long bbn = -1; - unsigned long adr; - acpi_handle parent = NULL; - acpi_status status; - unsigned int devfn; - int function; - int slot; - struct sn_pcidev_match *info = context; - - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, - &adr); - if (ACPI_SUCCESS(status)) { - status = acpi_get_parent(handle, &parent); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR - "%s: acpi_get_parent() failed (0x%x) for: ", - __FUNCTION__, status); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - return AE_OK; - } - status = acpi_evaluate_integer(parent, METHOD_NAME__BBN, - NULL, &bbn); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR - "%s: Failed to find _BBN in parent of: ", - __FUNCTION__); - acpi_ns_print_node_pathname(handle, NULL); - printk("\n"); - return AE_OK; - } - - slot = (adr >> 16) & 0xffff; - function = adr & 0xffff; - devfn = PCI_DEVFN(slot, function); - if ((info->devfn == devfn) && (info->bus == bbn)) { - /* We have a match! */ - info->handle = handle; - return 1; - } - } - return AE_OK; -} - -/* - * sn_acpi_get_pcidev_info - Search ACPI namespace for the acpi - * device matching the specified pci_dev, - * and return the pcidev info and irq info. + * sn_acpi_bus_fixup */ -int -sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, - struct sn_irq_info **sn_irq_info) +void +sn_acpi_bus_fixup(struct pci_bus *bus) { - unsigned int host_devfn; - struct sn_pcidev_match pcidev_match; - acpi_handle rootbus_handle; - unsigned long segment; - acpi_status status; + struct pci_dev *pci_dev = NULL; + struct pcibus_bussoft *prom_bussoft_ptr; + extern void sn_common_bus_fixup(struct pci_bus *, + struct pcibus_bussoft *); - rootbus_handle = PCI_CONTROLLER(dev)->acpi_handle; - status = acpi_evaluate_integer(rootbus_handle, METHOD_NAME__SEG, NULL, - &segment); - if (ACPI_SUCCESS(status)) { - if (segment != pci_domain_nr(dev)) { + if (!bus->parent) { /* If root bus */ + prom_bussoft_ptr = sn_get_bussoft_ptr(bus); + if (prom_bussoft_ptr == NULL) { printk(KERN_ERR - "%s: Segment number mismatch, 0x%lx vs 0x%x for: ", - __FUNCTION__, segment, pci_domain_nr(dev)); - acpi_ns_print_node_pathname(rootbus_handle, NULL); - printk("\n"); - return 1; + "sn_pci_fixup_bus: 0x%04x:0x%02x Unable to " + "obtain prom_bussoft_ptr\n", + pci_domain_nr(bus), bus->number); + return; } - } else { - printk(KERN_ERR "%s: Unable to get __SEG from: ", - __FUNCTION__); - acpi_ns_print_node_pathname(rootbus_handle, NULL); - printk("\n"); - return 1; + sn_common_bus_fixup(bus, prom_bussoft_ptr); } - - /* - * We want to search all devices in this segment/domain - * of the ACPI namespace for the matching ACPI device, - * which holds the pcidev_info pointer in its vendor resource. - */ - pcidev_match.bus = dev->bus->number; - pcidev_match.devfn = dev->devfn; - pcidev_match.handle = NULL; - - acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX, - find_matching_device, &pcidev_match, NULL); - - if (!pcidev_match.handle) { - printk(KERN_ERR - "%s: Could not find matching ACPI device for %s.\n", - __FUNCTION__, pci_name(dev)); - return 1; + list_for_each_entry(pci_dev, &bus->devices, bus_list) { + sn_pci_fixup_slot(pci_dev); } - - if (sn_extract_device_info(pcidev_match.handle, pcidev_info, sn_irq_info)) - return 1; - - /* Build up the pcidev_info.pdi_slot_host_handle */ - host_devfn = get_host_devfn(pcidev_match.handle, rootbus_handle); - (*pcidev_info)->pdi_slot_host_handle = - ((unsigned long) pci_domain_nr(dev) << 40) | - /* bus == 0 */ - host_devfn; - return 0; } /* - * sn_acpi_slot_fixup - Obtain the pcidev_info and sn_irq_info. - * Perform any SN specific slot fixup. + * sn_acpi_slot_fixup - Perform any SN specific slot fixup. * At present there does not appear to be * any generic way to handle a ROM image * that has been shadowed by the PROM, so @@ -408,18 +179,11 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, */ void -sn_acpi_slot_fixup(struct pci_dev *dev) +sn_acpi_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) { void __iomem *addr; - struct pcidev_info *pcidev_info = NULL; - struct sn_irq_info *sn_irq_info = NULL; size_t size; - if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) { - panic("%s: Failure obtaining pcidev_info for %s\n", - __FUNCTION__, pci_name(dev)); - } - if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) { /* * A valid ROM image exists and has been shadowed by the @@ -436,11 +200,8 @@ sn_acpi_slot_fixup(struct pci_dev *dev) (unsigned long) addr + size; dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY; } - sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); } -EXPORT_SYMBOL(sn_acpi_slot_fixup); - static struct acpi_driver acpi_sn_hubdev_driver = { .name = "SGI HUBDEV Driver", .ids = "SGIHUB,SGITIO", @@ -450,33 +211,6 @@ static struct acpi_driver acpi_sn_hubdev_driver = { }; -/* - * sn_acpi_bus_fixup - Perform SN specific setup of software structs - * (pcibus_bussoft, pcidev_info) and hardware - * registers, for the specified bus and devices under it. - */ -void -sn_acpi_bus_fixup(struct pci_bus *bus) -{ - struct pci_dev *pci_dev = NULL; - struct pcibus_bussoft *prom_bussoft_ptr; - - if (!bus->parent) { /* If root bus */ - prom_bussoft_ptr = sn_get_bussoft_ptr(bus); - if (prom_bussoft_ptr == NULL) { - printk(KERN_ERR - "%s: 0x%04x:0x%02x Unable to " - "obtain prom_bussoft_ptr\n", - __FUNCTION__, pci_domain_nr(bus), bus->number); - return; - } - sn_common_bus_fixup(bus, prom_bussoft_ptr); - } - list_for_each_entry(pci_dev, &bus->devices, bus_list) { - sn_acpi_slot_fixup(pci_dev); - } -} - /* * sn_io_acpi_init - PROM has ACPI support for IO, defining at a minimum the * nodes and root buses in the DSDT. As a result, bus scanning diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index d48bcd83253c..d4dd8f4b6b8d 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -26,10 +26,14 @@ #include #include #include -#include "acpi/acglobal.h" extern void sn_init_cpei_timer(void); extern void register_sn_procfs(void); +extern void sn_acpi_bus_fixup(struct pci_bus *); +extern void sn_bus_fixup(struct pci_bus *); +extern void sn_acpi_slot_fixup(struct pci_dev *, struct pcidev_info *); +extern void sn_more_slot_fixup(struct pci_dev *, struct pcidev_info *); +extern void sn_legacy_pci_window_fixup(struct pci_controller *, u64, u64); extern void sn_io_acpi_init(void); extern void sn_io_init(void); @@ -44,9 +48,6 @@ struct sysdata_el { int sn_ioif_inited; /* SN I/O infrastructure initialized? */ -int sn_acpi_rev; /* SN ACPI revision */ -EXPORT_SYMBOL_GPL(sn_acpi_rev); - struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ /* @@ -97,6 +98,25 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, return ret_stuff.status; } +/* + * Retrieve the pci device information given the bus and device|function number. + */ +static inline u64 +sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, + u64 sn_irq_info) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, + (u64) segment, (u64) bus_number, (u64) devfn, + (u64) pci_dev, + sn_irq_info, 0, 0); + return ret_stuff.v0; +} + /* * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified * device. @@ -229,25 +249,50 @@ void sn_pci_unfixup_slot(struct pci_dev *dev) } /* - * sn_pci_fixup_slot() + * sn_pci_fixup_slot() - This routine sets up a slot's resources consistent + * with the Linux PCI abstraction layer. Resources + * acquired from our PCI provider include PIO maps + * to BAR space and interrupt objects. */ -void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info, - struct sn_irq_info *sn_irq_info) +void sn_pci_fixup_slot(struct pci_dev *dev) { int segment = pci_domain_nr(dev->bus); + int status = 0; struct pcibus_bussoft *bs; - struct pci_bus *host_pci_bus; - struct pci_dev *host_pci_dev; - unsigned int bus_no, devfn; + struct pci_bus *host_pci_bus; + struct pci_dev *host_pci_dev; + struct pcidev_info *pcidev_info; + struct sn_irq_info *sn_irq_info; + unsigned int bus_no, devfn; pci_dev_get(dev); /* for the sysdata pointer */ + pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); + if (!pcidev_info) + BUG(); /* Cannot afford to run out of memory */ + + sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); + if (!sn_irq_info) + BUG(); /* Cannot afford to run out of memory */ + + /* Call to retrieve pci device information needed by kernel. */ + status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, + dev->devfn, + (u64) __pa(pcidev_info), + (u64) __pa(sn_irq_info)); + if (status) + BUG(); /* Cannot get platform pci device information */ /* Add pcidev_info to list in pci_controller.platform_data */ list_add_tail(&pcidev_info->pdi_list, &(SN_PLATFORM_DATA(dev->bus)->pcidev_info)); + + if (SN_ACPI_BASE_SUPPORT()) + sn_acpi_slot_fixup(dev, pcidev_info); + else + sn_more_slot_fixup(dev, pcidev_info); /* * Using the PROMs values for the PCI host bus, get the Linux - * PCI host_pci_dev struct and set up host bus linkages + * PCI host_pci_dev struct and set up host bus linkages */ bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff; @@ -444,6 +489,11 @@ void sn_generate_path(struct pci_bus *pci_bus, char *address) sprintf(address, "%s^%d", address, geo_slot(geoid)); } +/* + * sn_pci_fixup_bus() - Perform SN specific setup of software structs + * (pcibus_bussoft, pcidev_info) and hardware + * registers, for the specified bus and devices under it. + */ void __devinit sn_pci_fixup_bus(struct pci_bus *bus) { @@ -469,15 +519,6 @@ sn_io_early_init(void) if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; - /* we set the acpi revision to that of the DSDT table OEM rev. */ - { - struct acpi_table_header *header = NULL; - - acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); - BUG_ON(header == NULL); - sn_acpi_rev = header->oem_revision; - } - /* * prime sn_pci_provider[]. Individial provider init routines will * override their respective default entries. @@ -503,12 +544,8 @@ sn_io_early_init(void) register_sn_procfs(); #endif - { - struct acpi_table_header *header; - (void)acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); - printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", - header->oem_revision); - } + printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", + acpi_gbl_DSDT->oem_revision); if (SN_ACPI_BASE_SUPPORT()) sn_io_acpi_init(); else @@ -568,6 +605,7 @@ sn_io_late_init(void) fs_initcall(sn_io_late_init); +EXPORT_SYMBOL(sn_pci_fixup_slot); EXPORT_SYMBOL(sn_pci_unfixup_slot); EXPORT_SYMBOL(sn_bus_store_sysdata); EXPORT_SYMBOL(sn_bus_free_sysdata); diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index 600be3ebae05..9ad843e0383b 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -56,25 +56,6 @@ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) return ret_stuff.v0; } -/* - * Retrieve the pci device information given the bus and device|function number. - */ -static inline u64 -sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, - u64 sn_irq_info) -{ - struct ia64_sal_retval ret_stuff; - ret_stuff.status = 0; - ret_stuff.v0 = 0; - - SAL_CALL_NOLOCK(ret_stuff, - (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, - (u64) segment, (u64) bus_number, (u64) devfn, - (u64) pci_dev, - sn_irq_info, 0, 0); - return ret_stuff.v0; -} - /* * sn_fixup_ionodes() - This routine initializes the HUB data structure for @@ -191,40 +172,18 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, } /* - * sn_io_slot_fixup() - We are not running with an ACPI capable PROM, + * sn_more_slot_fixup() - We are not running with an ACPI capable PROM, * and need to convert the pci_dev->resource * 'start' and 'end' addresses to mapped addresses, * and setup the pci_controller->window array entries. */ void -sn_io_slot_fixup(struct pci_dev *dev) +sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) { unsigned int count = 0; int idx; s64 pci_addrs[PCI_ROM_RESOURCE + 1]; unsigned long addr, end, size, start; - struct pcidev_info *pcidev_info; - struct sn_irq_info *sn_irq_info; - int status; - - pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (!pcidev_info) - panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__); - - sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (!sn_irq_info) - panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__); - - /* Call to retrieve pci device information needed by kernel. */ - status = sal_get_pcidev_info((u64) pci_domain_nr(dev), - (u64) dev->bus->number, - dev->devfn, - (u64) __pa(pcidev_info), - (u64) __pa(sn_irq_info)); - - if (status) - BUG(); /* Cannot get platform pci device information */ - /* Copy over PIO Mapped Addresses */ for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { @@ -260,12 +219,8 @@ sn_io_slot_fixup(struct pci_dev *dev) */ if (count > 0) sn_pci_window_fixup(dev, count, pci_addrs); - - sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); } -EXPORT_SYMBOL(sn_io_slot_fixup); - /* * sn_pci_controller_fixup() - This routine sets up a bus's resources * consistent with the Linux PCI abstraction layer. @@ -317,6 +272,9 @@ sn_bus_fixup(struct pci_bus *bus) { struct pci_dev *pci_dev = NULL; struct pcibus_bussoft *prom_bussoft_ptr; + extern void sn_common_bus_fixup(struct pci_bus *, + struct pcibus_bussoft *); + if (!bus->parent) { /* If root bus */ prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data; @@ -333,7 +291,7 @@ sn_bus_fixup(struct pci_bus *bus) prom_bussoft_ptr->bs_legacy_mem); } list_for_each_entry(pci_dev, &bus->devices, bus_list) { - sn_io_slot_fixup(pci_dev); + sn_pci_fixup_slot(pci_dev); } } diff --git a/trunk/arch/ia64/sn/kernel/iomv.c b/trunk/arch/ia64/sn/kernel/iomv.c index ab7e2fd40798..4aa4f301d56d 100644 --- a/trunk/arch/ia64/sn/kernel/iomv.c +++ b/trunk/arch/ia64/sn/kernel/iomv.c @@ -1,4 +1,4 @@ -/* +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -26,10 +26,9 @@ * @port: port to convert * * Legacy in/out instructions are converted to ld/st instructions - * on IA64. This routine will convert a port number into a valid + * on IA64. This routine will convert a port number into a valid * SN i/o address. Used by sn_in*() and sn_out*(). */ - void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 04a8256017eb..6846dc9b432d 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -20,8 +20,7 @@ #include "xtalk/hubdev.h" int -sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp, - char **ssdt) +sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) { struct ia64_sal_retval ret_stuff; u64 busnum; @@ -33,8 +32,7 @@ sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp, segment = soft->pbi_buscommon.bs_persist_segment; busnum = soft->pbi_buscommon.bs_persist_busnum; SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment, - busnum, (u64) device, (u64) resp, (u64)ia64_tpa(ssdt), - 0, 0); + busnum, (u64) device, (u64) resp, 0, 0, 0); return (int)ret_stuff.v0; } diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c index bd30d138113f..49802f1bee94 100644 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ b/trunk/arch/x86_64/kernel/early-quirks.c @@ -32,7 +32,7 @@ static void via_bugs(void) static int nvidia_hpet_detected __initdata; -static int __init nvidia_hpet_check(struct acpi_table_header *header) +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) { nvidia_hpet_detected = 1; return 0; @@ -53,7 +53,7 @@ static void nvidia_bugs(void) return; nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); + acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " diff --git a/trunk/arch/x86_64/kernel/genapic.c b/trunk/arch/x86_64/kernel/genapic.c index 0b3603adf56d..b007433f96bb 100644 --- a/trunk/arch/x86_64/kernel/genapic.c +++ b/trunk/arch/x86_64/kernel/genapic.c @@ -58,8 +58,8 @@ void __init clustered_apic_check(void) * Some x86_64 machines use physical APIC mode regardless of how many * procs/clusters are present (x86_64 ES7000 is an example). */ - if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID) - if (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) { + if (acpi_fadt.revision > FADT2_REVISION_ID) + if (acpi_fadt.force_apic_physical_destination_mode) { genapic = &apic_cluster; goto print; } diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 50dd8bef850e..08072568847d 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -798,7 +798,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) return gsi; /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_gbl_FADT.sci_interrupt == gsi) + if (acpi_fadt.sci_int == gsi) return gsi; ioapic = mp_find_ioapic(gsi); diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 335cc91c49b7..5cc76d0d331f 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -498,7 +498,7 @@ static unsigned long get_cmos_time(void) { unsigned int year, mon, day, hour, min, sec; unsigned long flags; - unsigned century = 0; + unsigned extyear = 0; spin_lock_irqsave(&rtc_lock, flags); @@ -510,9 +510,9 @@ static unsigned long get_cmos_time(void) mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); #ifdef CONFIG_ACPI - if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && - acpi_gbl_FADT.century) - century = CMOS_READ(acpi_gbl_FADT.century); + if (acpi_fadt.revision >= FADT2_REVISION_ID && + acpi_fadt.century) + extyear = CMOS_READ(acpi_fadt.century); #endif } while (sec != CMOS_READ(RTC_SECONDS)); @@ -530,10 +530,10 @@ static unsigned long get_cmos_time(void) BCD_TO_BIN(mon); BCD_TO_BIN(year); - if (century) { - BCD_TO_BIN(century); - year += century * 100; - printk(KERN_INFO "Extended CMOS year: %d\n", century * 100); + if (extyear) { + BCD_TO_BIN(extyear); + year += extyear; + printk(KERN_INFO "Extended CMOS year: %d\n", extyear); } else { /* * x86-64 systems only exists since 2002. @@ -954,7 +954,7 @@ __cpuinit int unsynchronized_tsc(void) if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { #ifdef CONFIG_ACPI /* But TSC doesn't tick in C3 so don't use it there */ - if (acpi_gbl_FADT.header.length > 0 && acpi_gbl_FADT.C3latency < 1000) + if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000) return 1; #endif return 0; diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 2efe215fc76a..1087e150a218 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -101,7 +101,7 @@ static __init inline int srat_disabled(void) static __init int slit_valid(struct acpi_table_slit *slit) { int i, j; - int d = slit->locality_count; + int d = slit->localities; for (i = 0; i < d; i++) { for (j = 0; j < d; j++) { u8 val = slit->entry[d*i + j]; @@ -127,18 +127,18 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) /* Callback for Proximity Domain -> LAPIC mapping */ void __init -acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) +acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) { int pxm, node; if (srat_disabled()) return; - if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) { + if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) { bad_srat(); return; } - if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0) + if (pa->flags.enabled == 0) return; - pxm = pa->proximity_domain_lo; + pxm = pa->proximity_domain; node = setup_node(pxm); if (node < 0) { printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm); @@ -254,21 +254,21 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) /* Looks good */ if (nd->start == nd->end) { - nd->start = start; - nd->end = end; + nd->start = start; + nd->end = end; changed = 1; - } else { - if (nd->start == end) { - nd->start = start; + } else { + if (nd->start == end) { + nd->start = start; changed = 1; } - if (nd->end == start) { - nd->end = end; + if (nd->end == start) { + nd->end = end; changed = 1; } if (!changed) printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); - } + } ret = update_end_of_memory(nd->end); @@ -279,7 +279,7 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init -acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) +acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) { struct bootnode *nd, oldnode; unsigned long start, end; @@ -288,17 +288,16 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) if (srat_disabled()) return; - if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) { + if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) { bad_srat(); return; } - if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) + if (ma->flags.enabled == 0) return; - - if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info()) + if (ma->flags.hot_pluggable && !save_add_info()) return; - start = ma->base_address; - end = start + ma->length; + start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); + end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); pxm = ma->proximity_domain; node = setup_node(pxm); if (node < 0) { @@ -338,8 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) push_node_boundaries(node, nd->start >> PAGE_SHIFT, nd->end >> PAGE_SHIFT); - if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && - (reserve_hotadd(node, start, end) < 0)) { + if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) { /* Ignore hotadd region. Undo damage */ printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); *nd = oldnode; @@ -396,7 +394,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) /* First clean up the node list */ for (i = 0; i < MAX_NUMNODES; i++) { - cutoff_node(i, start, end); + cutoff_node(i, start, end); if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) { unparse_node(i); node_set_offline(i); @@ -428,7 +426,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) if (!node_online(i)) setup_node_bootmem(i, nodes[i].start, nodes[i].end); - for (i = 0; i < NR_CPUS; i++) { + for (i = 0; i < NR_CPUS; i++) { if (cpu_to_node[i] == NUMA_NO_NODE) continue; if (!node_isset(cpu_to_node[i], nodes_parsed)) @@ -463,7 +461,7 @@ int __node_distance(int a, int b) if (!acpi_slit) return a == b ? 10 : 20; - index = acpi_slit->locality_count * node_to_pxm(a); + index = acpi_slit->localities * node_to_pxm(a); return acpi_slit->entry[index + node_to_pxm(b)]; } diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c index faabb6e87f12..f8b6b2800a62 100644 --- a/trunk/arch/x86_64/pci/mmconfig.c +++ b/trunk/arch/x86_64/pci/mmconfig.c @@ -1,6 +1,6 @@ /* * mmconfig.c - Low-level direct PCI config space access via MMCONFIG - * + * * This is an 64bit optimized version that always keeps the full mmconfig * space mapped. This allows lockless config space operation. */ @@ -25,7 +25,7 @@ static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS); /* Static virtual mapping of the MMCONFIG aperture */ struct mmcfg_virt { - struct acpi_mcfg_allocation *cfg; + struct acpi_table_mcfg_config *cfg; char __iomem *virt; }; static struct mmcfg_virt *pci_mmcfg_virt; @@ -33,14 +33,14 @@ static struct mmcfg_virt *pci_mmcfg_virt; static char __iomem *get_virt(unsigned int seg, unsigned bus) { int cfg_num = -1; - struct acpi_mcfg_allocation *cfg; + struct acpi_table_mcfg_config *cfg; while (1) { ++cfg_num; if (cfg_num >= pci_mmcfg_config_num) break; cfg = pci_mmcfg_virt[cfg_num].cfg; - if (cfg->pci_segment != seg) + if (cfg->pci_segment_group_number != seg) continue; if ((cfg->start_bus_number <= bus) && (cfg->end_bus_number >= bus)) @@ -52,7 +52,7 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) this applies to all busses. */ cfg = &pci_mmcfg_config[0]; if (pci_mmcfg_config_num == 1 && - cfg->pci_segment == 0 && + cfg->pci_segment_group_number == 0 && (cfg->start_bus_number | cfg->end_bus_number) == 0) return pci_mmcfg_virt[0].virt; @@ -170,19 +170,19 @@ void __init pci_mmcfg_init(int type) if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; - acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); if ((pci_mmcfg_config_num == 0) || (pci_mmcfg_config == NULL) || - (pci_mmcfg_config[0].address == 0)) + (pci_mmcfg_config[0].base_address == 0)) return; /* Only do this check when type 1 works. If it doesn't work assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].address, - pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, + if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %lx is not E820-reserved\n", - (unsigned long)pci_mmcfg_config[0].address); + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", + pci_mmcfg_config[0].base_address); printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); return; } @@ -194,16 +194,15 @@ void __init pci_mmcfg_init(int type) } for (i = 0; i < pci_mmcfg_config_num; ++i) { pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; - pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].address, + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_MAX); if (!pci_mmcfg_virt[i].virt) { printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " "segment %d\n", - pci_mmcfg_config[i].pci_segment); + pci_mmcfg_config[i].pci_segment_group_number); return; } - printk(KERN_INFO "PCI: Using MMCONFIG at %lx\n", - (unsigned long)pci_mmcfg_config[i].address); + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); } unreachable_devices(); diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 50e295b08c94..f4f000abc4e9 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -107,7 +107,7 @@ config ACPI_BUTTON config ACPI_VIDEO tristate "Video" - depends on X86 && BACKLIGHT_CLASS_DEVICE + depends on X86 help This driver implement the ACPI Extensions For Display Adapters for integrated graphics devices on motherboard, as specified in diff --git a/trunk/drivers/acpi/asus_acpi.c b/trunk/drivers/acpi/asus_acpi.c index 31ad70a6e22e..396140bbbe57 100644 --- a/trunk/drivers/acpi/asus_acpi.c +++ b/trunk/drivers/acpi/asus_acpi.c @@ -26,7 +26,7 @@ * Pontus Fuchs - Helper functions, cleanup * Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. - * �ic Burghard - LED display support for W1N + * Éric Burghard - LED display support for W1N * */ @@ -1128,6 +1128,7 @@ static int asus_model_match(char *model) static int asus_hotk_get_info(void) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; int bsts_result; char *string = NULL; @@ -1141,9 +1142,11 @@ static int asus_hotk_get_info(void) * HID), this bit will be moved. A global variable asus_info contains * the DSDT header. */ - status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); + status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); if (ACPI_FAILURE(status)) printk(KERN_WARNING " Couldn't get the DSDT table header\n"); + else + asus_info = dsdt.pointer; /* We have to write 0 on init this far for all ASUS models */ if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { @@ -1355,6 +1358,8 @@ static void __exit asus_acpi_exit(void) acpi_bus_unregister_driver(&asus_hotk_driver); remove_proc_entry(PROC_ASUS, acpi_root_dir); + kfree(asus_info); + return; } diff --git a/trunk/drivers/acpi/blacklist.c b/trunk/drivers/acpi/blacklist.c index f289fd41e77d..f9c972b26f4f 100644 --- a/trunk/drivers/acpi/blacklist.c +++ b/trunk/drivers/acpi/blacklist.c @@ -44,7 +44,7 @@ struct acpi_blacklist_item { char oem_id[7]; char oem_table_id[9]; u32 oem_revision; - char *table; + acpi_table_type table; enum acpi_blacklist_predicates oem_revision_predicate; char *reason; u32 is_critical_error; @@ -56,18 +56,18 @@ struct acpi_blacklist_item { */ static struct acpi_blacklist_item acpi_blacklist[] __initdata = { /* Compaq Presario 1700 */ - {"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal, + {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal, "Multiple problems", 1}, /* Sony FX120, FX140, FX150? */ - {"SONY ", "U0 ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal, + {"SONY ", "U0 ", 0x20010313, ACPI_DSDT, less_than_or_equal, "ACPI driver problem", 1}, /* Compaq Presario 800, Insyde BIOS */ - {"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_DSDT, less_than_or_equal, + {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal, "Does not use _REG to protect EC OpRegions", 1}, /* IBM 600E - _ADR should return 7, but it returns 1 */ - {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, + {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT, less_than_or_equal, "Incorrect _ADR", 1}, - {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions, + {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions, "Bogus PCI routing", 1}, {""} @@ -79,7 +79,7 @@ static int __init blacklist_by_year(void) { int year = dmi_get_year(DMI_BIOS_DATE); /* Doesn't exist? Likely an old system */ - if (year == -1) + if (year == -1) return 1; /* 0? Likely a buggy new BIOS */ if (year == 0) @@ -103,21 +103,22 @@ int __init acpi_blacklisted(void) { int i = 0; int blacklisted = 0; - struct acpi_table_header table_header; + struct acpi_table_header *table_header; while (acpi_blacklist[i].oem_id[0] != '\0') { - if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) { + if (acpi_get_table_header_early + (acpi_blacklist[i].table, &table_header)) { i++; continue; } - if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) { + if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) { i++; continue; } if (strncmp - (acpi_blacklist[i].oem_table_id, table_header.oem_table_id, + (acpi_blacklist[i].oem_table_id, table_header->oem_table_id, 8)) { i++; continue; @@ -126,14 +127,14 @@ int __init acpi_blacklisted(void) if ((acpi_blacklist[i].oem_revision_predicate == all_versions) || (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal - && table_header.oem_revision <= + && table_header->oem_revision <= acpi_blacklist[i].oem_revision) || (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal - && table_header.oem_revision >= + && table_header->oem_revision >= acpi_blacklist[i].oem_revision) || (acpi_blacklist[i].oem_revision_predicate == equal - && table_header.oem_revision == + && table_header->oem_revision == acpi_blacklist[i].oem_revision)) { printk(KERN_ERR PREFIX diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index 15d677e6cee9..766332e45592 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -44,6 +44,9 @@ ACPI_MODULE_NAME("acpi_bus") extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); #endif +struct fadt_descriptor acpi_fadt; +EXPORT_SYMBOL(acpi_fadt); + struct acpi_device *acpi_root; struct proc_dir_entry *acpi_root_dir; EXPORT_SYMBOL(acpi_root_dir); @@ -579,12 +582,11 @@ static int __init acpi_bus_init_irq(void) return 0; } -acpi_native_uint acpi_gbl_permanent_mmap; - - void __init acpi_early_init(void) { acpi_status status = AE_OK; + struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt }; + if (acpi_disabled) return; @@ -595,15 +597,6 @@ void __init acpi_early_init(void) if (!acpi_strict) acpi_gbl_enable_interpreter_slack = TRUE; - acpi_gbl_permanent_mmap = 1; - - status = acpi_reallocate_root_table(); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX - "Unable to reallocate ACPI tables\n"); - goto error0; - } - status = acpi_initialize_subsystem(); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX @@ -618,25 +611,32 @@ void __init acpi_early_init(void) goto error0; } + /* + * Get a separate copy of the FADT for use by other drivers. + */ + status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to get the FADT\n"); + goto error0; + } #ifdef CONFIG_X86 if (!acpi_ioapic) { - extern u8 acpi_sci_flags; + extern acpi_interrupt_flags acpi_sci_flags; /* compatible (0) means level (3) */ - if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) { - acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK; - acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL; - } + if (acpi_sci_flags.trigger == 0) + acpi_sci_flags.trigger = 3; + /* Set PIC-mode SCI trigger type */ - acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt, - (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2); + acpi_pic_sci_set_trigger(acpi_fadt.sci_int, + acpi_sci_flags.trigger); } else { extern int acpi_sci_override_gsi; /* - * now that acpi_gbl_FADT is initialized, + * now that acpi_fadt is initialized, * update it with result from INT_SRC_OVR parsing */ - acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi; + acpi_fadt.sci_int = acpi_sci_override_gsi; } #endif diff --git a/trunk/drivers/acpi/dispatcher/dsfield.c b/trunk/drivers/acpi/dispatcher/dsfield.c index f049639bac35..a6d77efb41a0 100644 --- a/trunk/drivers/acpi/dispatcher/dsfield.c +++ b/trunk/drivers/acpi/dispatcher/dsfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -133,8 +133,7 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, } } - /* - * We could put the returned object (Node) on the object stack for later, + /* We could put the returned object (Node) on the object stack for later, * but for now, we will put it in the "op" object that the parser uses, * so we can get it again at the end of this scope */ @@ -515,33 +514,8 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, /* Third arg is the bank_value */ - /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ - arg = arg->common.next; - - /* Currently, only the following constants are supported */ - - switch (arg->common.aml_opcode) { - case AML_ZERO_OP: - info.bank_value = 0; - break; - - case AML_ONE_OP: - info.bank_value = 1; - break; - - case AML_BYTE_OP: - case AML_WORD_OP: - case AML_DWORD_OP: - case AML_QWORD_OP: - info.bank_value = (u32) arg->common.value.integer; - break; - - default: - info.bank_value = 0; - ACPI_ERROR((AE_INFO, - "Non-constant BankValue for BankField is not implemented")); - } + info.bank_value = (u32) arg->common.value.integer; /* Fourth arg is the field flags */ diff --git a/trunk/drivers/acpi/dispatcher/dsinit.c b/trunk/drivers/acpi/dispatcher/dsinit.c index af923c388520..1888c055d10f 100644 --- a/trunk/drivers/acpi/dispatcher/dsinit.c +++ b/trunk/drivers/acpi/dispatcher/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,6 @@ #include #include #include -#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsinit") @@ -91,7 +90,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, * We are only interested in NS nodes owned by the table that * was just loaded */ - if (node->owner_id != info->owner_id) { + if (node->owner_id != info->table_desc->owner_id) { return (AE_OK); } @@ -151,21 +150,14 @@ acpi_ds_init_one_object(acpi_handle obj_handle, ******************************************************************************/ acpi_status -acpi_ds_initialize_objects(acpi_native_uint table_index, +acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, struct acpi_namespace_node * start_node) { acpi_status status; struct acpi_init_walk_info info; - struct acpi_table_header *table; - acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(ds_initialize_objects); - status = acpi_tb_get_owner_id(table_index, &owner_id); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); @@ -174,8 +166,7 @@ acpi_ds_initialize_objects(acpi_native_uint table_index, info.op_region_count = 0; info.object_count = 0; info.device_count = 0; - info.table_index = table_index; - info.owner_id = owner_id; + info.table_desc = table_desc; /* Walk entire namespace from the supplied root */ @@ -185,14 +176,10 @@ acpi_ds_initialize_objects(acpi_native_uint table_index, ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); } - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", - table->signature, owner_id, info.object_count, + table_desc->pointer->signature, + table_desc->owner_id, info.object_count, info.device_count, info.method_count, info.op_region_count)); diff --git a/trunk/drivers/acpi/dispatcher/dsmethod.c b/trunk/drivers/acpi/dispatcher/dsmethod.c index 1cbe61905824..cf888add3191 100644 --- a/trunk/drivers/acpi/dispatcher/dsmethod.c +++ b/trunk/drivers/acpi/dispatcher/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -327,7 +327,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Calling method %p, currentstate=%p\n", + "Execute method %p, currentstate=%p\n", this_walk_state->prev_op, this_walk_state)); /* @@ -351,7 +351,49 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, return_ACPI_STATUS(status); } - /* Begin method parse/execution. Create a new walk state */ + /* + * 1) Parse the method. All "normal" methods are parsed for each execution. + * Internal methods (_OSI, etc.) do not require parsing. + */ + if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { + + /* Create a new walk state for the parse */ + + next_walk_state = + acpi_ds_create_walk_state(obj_desc->method.owner_id, op, + obj_desc, NULL); + if (!next_walk_state) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Create and init a parse tree root */ + + op = acpi_ps_create_scope_op(); + if (!op) { + status = AE_NO_MEMORY; + goto cleanup; + } + + status = acpi_ds_init_aml_walk(next_walk_state, op, method_node, + obj_desc->method.aml_start, + obj_desc->method.aml_length, + NULL, 1); + if (ACPI_FAILURE(status)) { + acpi_ps_delete_parse_tree(op); + goto cleanup; + } + + /* Begin AML parse (deletes next_walk_state) */ + + status = acpi_ps_parse_aml(next_walk_state); + acpi_ps_delete_parse_tree(op); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + } + + /* 2) Begin method execution. Create a new walk state */ next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, obj_desc, thread); @@ -382,8 +424,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, obj_desc->method.aml_start, - obj_desc->method.aml_length, info, - ACPI_IMODE_EXECUTE); + obj_desc->method.aml_length, info, 3); ACPI_FREE(info); if (ACPI_FAILURE(status)) { @@ -404,8 +445,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, this_walk_state->num_operands = 0; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "**** Begin nested execution of [%4.4s] **** WalkState=%p\n", - method_node->name.ascii, next_walk_state)); + "Starting nested execution, newstate=%p\n", + next_walk_state)); /* Invoke an internal method if necessary */ diff --git a/trunk/drivers/acpi/dispatcher/dsmthdat.c b/trunk/drivers/acpi/dispatcher/dsmthdat.c index ba4626e06a5e..459160ff9058 100644 --- a/trunk/drivers/acpi/dispatcher/dsmthdat.c +++ b/trunk/drivers/acpi/dispatcher/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dispatcher/dsobject.c b/trunk/drivers/acpi/dispatcher/dsobject.c index a474ca2334d5..72190abb1d59 100644 --- a/trunk/drivers/acpi/dispatcher/dsobject.c +++ b/trunk/drivers/acpi/dispatcher/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -260,7 +260,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, } obj_desc->buffer.flags |= AOPOBJ_DATA_VALID; - op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); + op->common.node = (struct acpi_namespace_node *)obj_desc; return_ACPI_STATUS(AE_OK); } @@ -270,8 +270,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, * * PARAMETERS: walk_state - Current walk state * Op - Parser object to be translated - * element_count - Number of elements in the package - this is - * the num_elements argument to Package() + * package_length - Number of elements in the package * obj_desc_ptr - Where the ACPI internal object is returned * * RETURN: Status @@ -279,29 +278,18 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, * DESCRIPTION: Translate a parser Op package object to the equivalent * namespace object * - * NOTE: The number of elements in the package will be always be the num_elements - * count, regardless of the number of elements in the package list. If - * num_elements is smaller, only that many package list elements are used. - * if num_elements is larger, the Package object is padded out with - * objects of type Uninitialized (as per ACPI spec.) - * - * Even though the ASL compilers do not allow num_elements to be smaller - * than the Package list length (for the fixed length package opcode), some - * BIOS code modifies the AML on the fly to adjust the num_elements, and - * this code compensates for that. This also provides compatibility with - * other AML interpreters. - * ******************************************************************************/ acpi_status acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, union acpi_parse_object *op, - u32 element_count, + u32 package_length, union acpi_operand_object **obj_desc_ptr) { union acpi_parse_object *arg; union acpi_parse_object *parent; union acpi_operand_object *obj_desc = NULL; + u32 package_list_length; acpi_status status = AE_OK; acpi_native_uint i; @@ -330,13 +318,32 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, obj_desc->package.node = parent->common.node; } + obj_desc->package.count = package_length; + + /* Count the number of items in the package list */ + + arg = op->common.value.arg; + arg = arg->common.next; + for (package_list_length = 0; arg; package_list_length++) { + arg = arg->common.next; + } + + /* + * The package length (number of elements) will be the greater + * of the specified length and the length of the initializer list + */ + if (package_list_length > package_length) { + obj_desc->package.count = package_list_length; + } + /* - * Allocate the element array (array of pointers to the individual - * objects) based on the num_elements parameter. Add an extra pointer slot - * so that the list is always null terminated. + * Allocate the pointer array (array of pointers to the + * individual objects). Add an extra pointer slot so + * that the list is always null terminated. */ obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) - element_count + + obj_desc->package. + count + 1) * sizeof(void *)); if (!obj_desc->package.elements) { @@ -344,20 +351,15 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, return_ACPI_STATUS(AE_NO_MEMORY); } - obj_desc->package.count = element_count; - /* - * Initialize the elements of the package, up to the num_elements count. - * Package is automatically padded with uninitialized (NULL) elements - * if num_elements is greater than the package list length. Likewise, - * Package is truncated if num_elements is less than the list length. + * Initialize all elements of the package */ arg = op->common.value.arg; arg = arg->common.next; - for (i = 0; arg && (i < element_count); i++) { + for (i = 0; arg; i++) { if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { - /* This package element is already built, just get it */ + /* Object (package or buffer) is already built */ obj_desc->package.elements[i] = ACPI_CAST_PTR(union acpi_operand_object, @@ -371,14 +373,8 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, arg = arg->common.next; } - if (!arg) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Package List length larger than NumElements count (%X), truncated\n", - element_count)); - } - obj_desc->package.flags |= AOPOBJ_DATA_VALID; - op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); + op->common.node = (struct acpi_namespace_node *)obj_desc; return_ACPI_STATUS(status); } @@ -492,9 +488,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, /* * Defer evaluation of Buffer term_arg operand */ - obj_desc->buffer.node = - ACPI_CAST_PTR(struct acpi_namespace_node, - walk_state->operands[0]); + obj_desc->buffer.node = (struct acpi_namespace_node *) + walk_state->operands[0]; obj_desc->buffer.aml_start = op->named.data; obj_desc->buffer.aml_length = op->named.length; break; @@ -504,9 +499,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, /* * Defer evaluation of Package term_arg operand */ - obj_desc->package.node = - ACPI_CAST_PTR(struct acpi_namespace_node, - walk_state->operands[0]); + obj_desc->package.node = (struct acpi_namespace_node *) + walk_state->operands[0]; obj_desc->package.aml_start = op->named.data; obj_desc->package.aml_length = op->named.length; break; diff --git a/trunk/drivers/acpi/dispatcher/dsopcode.c b/trunk/drivers/acpi/dispatcher/dsopcode.c index 6c6104a7a247..5b974a8fe614 100644 --- a/trunk/drivers/acpi/dispatcher/dsopcode.c +++ b/trunk/drivers/acpi/dispatcher/dsopcode.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -114,7 +114,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, } status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, - aml_length, NULL, ACPI_IMODE_LOAD_PASS1); + aml_length, NULL, 1); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; @@ -157,7 +157,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, /* Execute the opcode and arguments */ status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, - aml_length, NULL, ACPI_IMODE_EXECUTE); + aml_length, NULL, 3); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; diff --git a/trunk/drivers/acpi/dispatcher/dsutils.c b/trunk/drivers/acpi/dispatcher/dsutils.c index e4073e05a75c..05230baf5de8 100644 --- a/trunk/drivers/acpi/dispatcher/dsutils.c +++ b/trunk/drivers/acpi/dispatcher/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dispatcher/dswexec.c b/trunk/drivers/acpi/dispatcher/dswexec.c index 69693fa07224..d7a616c3104e 100644 --- a/trunk/drivers/acpi/dispatcher/dswexec.c +++ b/trunk/drivers/acpi/dispatcher/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -219,7 +219,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, if (!op) { status = acpi_ds_load2_begin_op(walk_state, out_op); if (ACPI_FAILURE(status)) { - goto error_exit; + return_ACPI_STATUS(status); } op = *out_op; @@ -238,7 +238,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, status = acpi_ds_scope_stack_pop(walk_state); if (ACPI_FAILURE(status)) { - goto error_exit; + return_ACPI_STATUS(status); } } } @@ -287,7 +287,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, status = acpi_ds_result_stack_push(walk_state); if (ACPI_FAILURE(status)) { - goto error_exit; + return_ACPI_STATUS(status); } status = acpi_ds_exec_begin_control_op(walk_state, op); @@ -328,10 +328,6 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, /* Nothing to do here during method execution */ return_ACPI_STATUS(status); - - error_exit: - status = acpi_ds_method_error(status, walk_state); - return_ACPI_STATUS(status); } /***************************************************************************** diff --git a/trunk/drivers/acpi/dispatcher/dswload.c b/trunk/drivers/acpi/dispatcher/dswload.c index 8ab9d1b29a4c..e3ca7f6539c1 100644 --- a/trunk/drivers/acpi/dispatcher/dswload.c +++ b/trunk/drivers/acpi/dispatcher/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -196,7 +196,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, * one of the opcodes that actually opens a scope */ switch (node->type) { - case ACPI_TYPE_ANY: case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: @@ -547,7 +546,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, acpi_status status; acpi_object_type object_type; char *buffer_ptr; - u32 flags; ACPI_FUNCTION_TRACE(ds_load2_begin_op); @@ -671,7 +669,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, * one of the opcodes that actually opens a scope */ switch (node->type) { - case ACPI_TYPE_ANY: case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: @@ -753,20 +750,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, break; } - flags = ACPI_NS_NO_UPSEARCH; - if (walk_state->pass_number == ACPI_IMODE_EXECUTE) { - - /* Execution mode, node cannot already exist, node is temporary */ - - flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY); - } - - /* Add new entry or lookup existing entry */ + /* Add new entry into namespace */ status = acpi_ns_lookup(walk_state->scope_info, buffer_ptr, - object_type, ACPI_IMODE_LOAD_PASS2, flags, - walk_state, &node); + object_type, ACPI_IMODE_LOAD_PASS2, + ACPI_NS_NO_UPSEARCH, walk_state, &(node)); break; } diff --git a/trunk/drivers/acpi/dispatcher/dswscope.c b/trunk/drivers/acpi/dispatcher/dswscope.c index 3927c495e4bf..c9228972f5f6 100644 --- a/trunk/drivers/acpi/dispatcher/dswscope.c +++ b/trunk/drivers/acpi/dispatcher/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dispatcher/dswstate.c b/trunk/drivers/acpi/dispatcher/dswstate.c index 16c8e38b51ef..7817e5522679 100644 --- a/trunk/drivers/acpi/dispatcher/dswstate.c +++ b/trunk/drivers/acpi/dispatcher/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 90990a4b6526..688e83a16906 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -615,20 +615,28 @@ static acpi_status find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; - acpi_handle tmp; + acpi_handle tmp, parent; struct dock_station *ds = context; struct dock_dependent_device *dd; status = acpi_bus_get_ejd(handle, &tmp); - if (ACPI_FAILURE(status)) - return AE_OK; + if (ACPI_FAILURE(status)) { + /* try the parent device as well */ + status = acpi_get_parent(handle, &parent); + if (ACPI_FAILURE(status)) + goto fdd_out; + /* see if parent is dependent on dock */ + status = acpi_bus_get_ejd(parent, &tmp); + if (ACPI_FAILURE(status)) + goto fdd_out; + } if (tmp == ds->handle) { dd = alloc_dock_dependent_device(handle); if (dd) add_dock_dependent_device(ds, dd); } - +fdd_out: return AE_OK; } diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 743ce27fa0bb..cbdf031f3c09 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -872,8 +872,9 @@ static int __init acpi_ec_get_real_ecdt(void) acpi_status status; struct acpi_table_ecdt *ecdt_ptr; - status = acpi_get_table(ACPI_SIG_ECDT, 1, - (struct acpi_table_header **)&ecdt_ptr); + status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) + &ecdt_ptr); if (ACPI_FAILURE(status)) return -ENODEV; @@ -890,14 +891,14 @@ static int __init acpi_ec_get_real_ecdt(void) if (acpi_ec_mode == EC_INTR) { init_waitqueue_head(&ec_ecdt->wait); } - ec_ecdt->command_addr = ecdt_ptr->control.address; - ec_ecdt->data_addr = ecdt_ptr->data.address; - ec_ecdt->gpe = ecdt_ptr->gpe; + ec_ecdt->command_addr = ecdt_ptr->ec_control.address; + ec_ecdt->data_addr = ecdt_ptr->ec_data.address; + ec_ecdt->gpe = ecdt_ptr->gpe_bit; /* use the GL just to be safe */ ec_ecdt->global_lock = TRUE; ec_ecdt->uid = ecdt_ptr->uid; - status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle); + status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); if (ACPI_FAILURE(status)) { goto error; } diff --git a/trunk/drivers/acpi/events/evevent.c b/trunk/drivers/acpi/events/evevent.c index a1f87b5def2a..919037d6acff 100644 --- a/trunk/drivers/acpi/events/evevent.c +++ b/trunk/drivers/acpi/events/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,6 +70,13 @@ acpi_status acpi_ev_initialize_events(void) ACPI_FUNCTION_TRACE(ev_initialize_events); + /* Make sure we have ACPI tables */ + + if (!acpi_gbl_DSDT) { + ACPI_WARNING((AE_INFO, "No ACPI tables present!")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + /* * Initialize the Fixed and General Purpose Events. This is done prior to * enabling SCIs to prevent interrupts from occurring before the handlers are @@ -204,7 +211,8 @@ static acpi_status acpi_ev_fixed_event_initialize(void) if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { status = acpi_set_register(acpi_gbl_fixed_event_info[i]. - enable_register_id, 0); + enable_register_id, 0, + ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return (status); } @@ -290,7 +298,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) /* Clear the status bit */ (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. - status_register_id, 1); + status_register_id, 1, ACPI_MTX_DO_NOT_LOCK); /* * Make sure we've got a handler. If not, report an error. @@ -298,7 +306,8 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) */ if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, 0); + enable_register_id, 0, + ACPI_MTX_DO_NOT_LOCK); ACPI_ERROR((AE_INFO, "No installed handler for fixed event [%08X]", diff --git a/trunk/drivers/acpi/events/evgpe.c b/trunk/drivers/acpi/events/evgpe.c index dfac3ecc596e..c76c0583ca6a 100644 --- a/trunk/drivers/acpi/events/evgpe.c +++ b/trunk/drivers/acpi/events/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -121,9 +121,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, if (!gpe_register_info) { return_ACPI_STATUS(AE_NOT_EXIST); } - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); + register_bit = gpe_event_info->register_bit; /* 1) Disable case. Simply clear all enable bits */ @@ -460,7 +458,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Examine one GPE bit */ - if (enabled_status_byte & (1 << j)) { + if (enabled_status_byte & + acpi_gbl_decode_to8bit[j]) { /* * Found an active GPE. Dispatch the event to a handler * or method. @@ -571,7 +570,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "while evaluating GPE method [%4.4s]", + "While evaluating GPE method [%4.4s]", acpi_ut_get_node_name (local_gpe_event_info.dispatch. method_node))); @@ -619,8 +618,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) ACPI_FUNCTION_TRACE(ev_gpe_dispatch); - acpi_gpe_count++; - /* * If edge-triggered, clear the GPE status bit now. Note that * level-triggered events are cleared after the GPE is serviced. @@ -636,23 +633,20 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) } } - if (!acpi_gbl_system_awake_and_running) { - /* - * We just woke up because of a wake GPE. Disable any further GPEs - * until we are fully up and running (Only wake GPEs should be enabled - * at this time, but we just brute-force disable them all.) - * 1) We must disable this particular wake GPE so it won't fire again - * 2) We want to disable all wake GPEs, since we are now awake - */ - (void)acpi_hw_disable_all_gpes(); + /* Save current system state */ + + if (acpi_gbl_system_awake_and_running) { + ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); + } else { + ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); } /* - * Dispatch the GPE to either an installed handler, or the control method - * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke - * it and do not attempt to run the method. If there is neither a handler - * nor a method, we disable this GPE to prevent further such pointless - * events from firing. + * Dispatch the GPE to either an installed handler, or the control + * method associated with this GPE (_Lxx or _Exx). + * If a handler exists, we invoke it and do not attempt to run the method. + * If there is neither a handler nor a method, we disable the level to + * prevent further events from coming in here. */ switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { case ACPI_GPE_DISPATCH_HANDLER: @@ -683,8 +677,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) case ACPI_GPE_DISPATCH_METHOD: /* - * Disable the GPE, so it doesn't keep firing before the method has a - * chance to run (it runs asynchronously with interrupts enabled). + * Disable GPE, so it doesn't keep firing before the method has a + * chance to run. */ status = acpi_ev_disable_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { @@ -717,7 +711,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) gpe_number)); /* - * Disable the GPE. The GPE will remain disabled until the ACPI + * Disable the GPE. The GPE will remain disabled until the ACPI * Core Subsystem is restarted, or a handler is installed. */ status = acpi_ev_disable_gpe(gpe_event_info); @@ -732,3 +726,50 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) return_UINT32(ACPI_INTERRUPT_HANDLED); } + +#ifdef ACPI_GPE_NOTIFY_CHECK +/******************************************************************************* + * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED + * + * FUNCTION: acpi_ev_check_for_wake_only_gpe + * + * PARAMETERS: gpe_event_info - info for this GPE + * + * RETURN: Status + * + * DESCRIPTION: Determine if a a GPE is "wake-only". + * + * Called from Notify() code in interpreter when a "DeviceWake" + * Notify comes in. + * + ******************************************************************************/ + +acpi_status +acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(ev_check_for_wake_only_gpe); + + if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */ + ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) { /* System state at GPE time */ + /* This must be a wake-only GPE, disable it */ + + status = acpi_ev_disable_gpe(gpe_event_info); + + /* Set GPE to wake-only. Do not change wake disabled/enabled status */ + + acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); + + ACPI_INFO((AE_INFO, + "GPE %p was updated from wake/run to wake-only", + gpe_event_info)); + + /* This was a wake-only GPE */ + + return_ACPI_STATUS(AE_WAKE_ONLY_GPE); + } + + return_ACPI_STATUS(AE_OK); +} +#endif diff --git a/trunk/drivers/acpi/events/evgpeblk.c b/trunk/drivers/acpi/events/evgpeblk.c index ad5bc76edf46..95ddeb48bc0f 100644 --- a/trunk/drivers/acpi/events/evgpeblk.c +++ b/trunk/drivers/acpi/events/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 /* Install new interrupt handler if not SCI_INT */ - if (interrupt_number != acpi_gbl_FADT.sci_interrupt) { + if (interrupt_number != acpi_gbl_FADT->sci_int) { status = acpi_os_install_interrupt_handler(interrupt_number, acpi_ev_gpe_xrupt_handler, gpe_xrupt); @@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) /* We never want to remove the SCI interrupt handler */ - if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) { + if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) { gpe_xrupt->gpe_block_list_head = NULL; return_ACPI_STATUS(AE_OK); } @@ -796,31 +796,30 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) (u8) (gpe_block->block_base_number + (i * ACPI_GPE_REGISTER_WIDTH)); - this_register->status_address.address = - gpe_block->block_address.address + i; + ACPI_STORE_ADDRESS(this_register->status_address.address, + (gpe_block->block_address.address + i)); - this_register->enable_address.address = - gpe_block->block_address.address + i + - gpe_block->register_count; + ACPI_STORE_ADDRESS(this_register->enable_address.address, + (gpe_block->block_address.address + + i + gpe_block->register_count)); - this_register->status_address.space_id = - gpe_block->block_address.space_id; - this_register->enable_address.space_id = - gpe_block->block_address.space_id; - this_register->status_address.bit_width = + this_register->status_address.address_space_id = + gpe_block->block_address.address_space_id; + this_register->enable_address.address_space_id = + gpe_block->block_address.address_space_id; + this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; - this_register->enable_address.bit_width = + this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH; - this_register->status_address.bit_offset = + this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; - this_register->enable_address.bit_offset = + this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH; /* Init the event_info for each GPE within this register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { - this_event->gpe_number = - (u8) (this_register->base_gpe_number + j); + this_event->register_bit = acpi_gbl_decode_to8bit[j]; this_event->register_info = this_register; this_event++; } @@ -1110,12 +1109,11 @@ acpi_status acpi_ev_gpe_initialize(void) * If EITHER the register length OR the block address are zero, then that * particular block is not supported. */ - if (acpi_gbl_FADT.gpe0_block_length && - acpi_gbl_FADT.xgpe0_block.address) { + if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) { /* GPE block 0 exists (has both length and address > 0) */ - register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2); + register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2); gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; @@ -1123,9 +1121,9 @@ acpi_status acpi_ev_gpe_initialize(void) /* Install GPE Block 0 */ status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, - &acpi_gbl_FADT.xgpe0_block, + &acpi_gbl_FADT->xgpe0_blk, register_count0, 0, - acpi_gbl_FADT.sci_interrupt, + acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]); if (ACPI_FAILURE(status)) { @@ -1134,21 +1132,20 @@ acpi_status acpi_ev_gpe_initialize(void) } } - if (acpi_gbl_FADT.gpe1_block_length && - acpi_gbl_FADT.xgpe1_block.address) { + if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) { /* GPE block 1 exists (has both length and address > 0) */ - register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2); + register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2); /* Check for GPE0/GPE1 overlap (if both banks exist) */ if ((register_count0) && - (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) { + (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) { ACPI_ERROR((AE_INFO, "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", - gpe_number_max, acpi_gbl_FADT.gpe1_base, - acpi_gbl_FADT.gpe1_base + + gpe_number_max, acpi_gbl_FADT->gpe1_base, + acpi_gbl_FADT->gpe1_base + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1))); @@ -1160,11 +1157,10 @@ acpi_status acpi_ev_gpe_initialize(void) status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, - &acpi_gbl_FADT.xgpe1_block, + &acpi_gbl_FADT->xgpe1_blk, register_count1, - acpi_gbl_FADT.gpe1_base, - acpi_gbl_FADT. - sci_interrupt, + acpi_gbl_FADT->gpe1_base, + acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks [1]); @@ -1177,7 +1173,7 @@ acpi_status acpi_ev_gpe_initialize(void) * GPE0 and GPE1 do not have to be contiguous in the GPE number * space. However, GPE0 always starts at GPE number zero. */ - gpe_number_max = acpi_gbl_FADT.gpe1_base + + gpe_number_max = acpi_gbl_FADT->gpe1_base + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); } } diff --git a/trunk/drivers/acpi/events/evmisc.c b/trunk/drivers/acpi/events/evmisc.c index 1b784ffe54c3..bf63edc6608d 100644 --- a/trunk/drivers/acpi/events/evmisc.c +++ b/trunk/drivers/acpi/events/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,17 +63,13 @@ static const char *acpi_notify_value_names[] = { }; #endif -/* Pointer to FACS needed for the Global Lock */ - -static struct acpi_table_facs *facs = NULL; - /* Local prototypes */ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); -static u32 acpi_ev_global_lock_handler(void *context); +static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context); -static acpi_status acpi_ev_remove_global_lock_handler(void); +static u32 acpi_ev_global_lock_handler(void *context); /******************************************************************************* * @@ -284,21 +280,51 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) acpi_ut_delete_generic_state(notify_info); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_global_lock_thread + * + * PARAMETERS: Context - From thread interface, not used + * + * RETURN: None + * + * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the + * Global Lock. Simply signal all threads that are waiting + * for the lock. + * + ******************************************************************************/ + +static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context) +{ + acpi_status status; + + /* Signal threads that are waiting for the lock */ + + if (acpi_gbl_global_lock_thread_count) { + + /* Send sufficient units to the semaphore */ + + status = + acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, + acpi_gbl_global_lock_thread_count); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not signal Global Lock semaphore")); + } + } +} + /******************************************************************************* * * FUNCTION: acpi_ev_global_lock_handler * * PARAMETERS: Context - From thread interface, not used * - * RETURN: ACPI_INTERRUPT_HANDLED + * RETURN: ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED * * DESCRIPTION: Invoked directly from the SCI handler when a global lock - * release interrupt occurs. Attempt to acquire the global lock, - * if successful, signal the thread waiting for the lock. - * - * NOTE: Assumes that the semaphore can be signaled from interrupt level. If - * this is not possible for some reason, a separate thread will have to be - * scheduled to do this. + * release interrupt occurs. Grab the global lock and queue + * the global lock thread for execution * ******************************************************************************/ @@ -307,24 +333,16 @@ static u32 acpi_ev_global_lock_handler(void *context) u8 acquired = FALSE; /* - * Attempt to get the lock. - * + * Attempt to get the lock * If we don't get it now, it will be marked pending and we will * take another interrupt when it becomes free. */ - ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { /* Got the lock, now wake all threads waiting for it */ - acpi_gbl_global_lock_acquired = TRUE; - /* Send a unit to the semaphore */ - - if (ACPI_FAILURE(acpi_os_signal_semaphore( - acpi_gbl_global_lock_semaphore, 1))) { - ACPI_ERROR((AE_INFO, - "Could not signal Global Lock semaphore")); - } + acpi_ev_global_lock_thread(context); } return (ACPI_INTERRUPT_HANDLED); @@ -348,13 +366,6 @@ acpi_status acpi_ev_init_global_lock_handler(void) ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); - status = - acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - (struct acpi_table_header **)&facs); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - acpi_gbl_global_lock_present = TRUE; status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, acpi_ev_global_lock_handler, @@ -378,31 +389,6 @@ acpi_status acpi_ev_init_global_lock_handler(void) return_ACPI_STATUS(status); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_remove_global_lock_handler - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Remove the handler for the Global Lock - * - ******************************************************************************/ - -static acpi_status acpi_ev_remove_global_lock_handler(void) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); - - acpi_gbl_global_lock_present = FALSE; - status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, - acpi_ev_global_lock_handler); - - return_ACPI_STATUS(status); -} - /****************************************************************************** * * FUNCTION: acpi_ev_acquire_global_lock @@ -413,16 +399,6 @@ static acpi_status acpi_ev_remove_global_lock_handler(void) * * DESCRIPTION: Attempt to gain ownership of the Global Lock. * - * MUTEX: Interpreter must be locked - * - * Note: The original implementation allowed multiple threads to "acquire" the - * Global Lock, and the OS would hold the lock until the last thread had - * released it. However, this could potentially starve the BIOS out of the - * lock, especially in the case where there is a tight handshake between the - * Embedded Controller driver and the BIOS. Therefore, this implementation - * allows only one thread to acquire the HW Global Lock at a time, and makes - * the global lock appear as a standard mutex on the OS side. - * *****************************************************************************/ acpi_status acpi_ev_acquire_global_lock(u16 timeout) @@ -432,51 +408,53 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) ACPI_FUNCTION_TRACE(ev_acquire_global_lock); - /* - * Only one thread can acquire the GL at a time, the global_lock_mutex - * enforces this. This interface releases the interpreter if we must wait. - */ - status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); +#ifndef ACPI_APPLICATION + /* Make sure that we actually have a global lock */ + + if (!acpi_gbl_global_lock_present) { + return_ACPI_STATUS(AE_NO_GLOBAL_LOCK); } +#endif + + /* One more thread wants the global lock */ + + acpi_gbl_global_lock_thread_count++; /* - * Make sure that a global lock actually exists. If not, just treat - * the lock as a standard mutex. + * If we (OS side vs. BIOS side) have the hardware lock already, + * we are done */ - if (!acpi_gbl_global_lock_present) { - acpi_gbl_global_lock_acquired = TRUE; + if (acpi_gbl_global_lock_acquired) { return_ACPI_STATUS(AE_OK); } - /* Attempt to acquire the actual hardware lock */ + /* We must acquire the actual hardware lock */ - ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); + ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { /* We got the lock */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Acquired hardware Global Lock\n")); + "Acquired the HW Global Lock\n")); acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); } /* - * Did not get the lock. The pending bit was set above, and we must now + * Did not get the lock. The pending bit was set above, and we must now * wait until we get the global lock released interrupt. */ - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); /* - * Wait for handshake with the global lock interrupt handler. - * This interface releases the interpreter if we must wait. + * Acquire the global lock semaphore first. + * Since this wait will block, we must release the interpreter */ - status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, - ACPI_WAIT_FOREVER); - + status = + acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, + timeout); return_ACPI_STATUS(status); } @@ -499,39 +477,38 @@ acpi_status acpi_ev_release_global_lock(void) ACPI_FUNCTION_TRACE(ev_release_global_lock); - /* Lock must be already acquired */ - - if (!acpi_gbl_global_lock_acquired) { + if (!acpi_gbl_global_lock_thread_count) { ACPI_WARNING((AE_INFO, - "Cannot release the ACPI Global Lock, it has not been acquired")); + "Cannot release HW Global Lock, it has not been acquired")); return_ACPI_STATUS(AE_NOT_ACQUIRED); } - if (acpi_gbl_global_lock_present) { + /* One fewer thread has the global lock */ - /* Allow any thread to release the lock */ + acpi_gbl_global_lock_thread_count--; + if (acpi_gbl_global_lock_thread_count) { - ACPI_RELEASE_GLOBAL_LOCK(facs, pending); + /* There are still some threads holding the lock, cannot release */ - /* - * If the pending bit was set, we must write GBL_RLS to the control - * register - */ - if (pending) { - status = - acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, - 1); - } - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Released hardware Global Lock\n")); + return_ACPI_STATUS(AE_OK); } + /* + * No more threads holding lock, we can do the actual hardware + * release + */ + ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, pending); acpi_gbl_global_lock_acquired = FALSE; - /* Release the local GL mutex */ + /* + * If the pending bit was set, we must write GBL_RLS to the control + * register + */ + if (pending) { + status = acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, + 1, ACPI_MTX_LOCK); + } - acpi_os_release_mutex(acpi_gbl_global_lock_mutex); return_ACPI_STATUS(status); } @@ -581,12 +558,6 @@ void acpi_ev_terminate(void) if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); } - - status = acpi_ev_remove_global_lock_handler(); - if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not remove Global Lock handler")); - } } /* Deallocate all handler objects installed within GPE info structs */ diff --git a/trunk/drivers/acpi/events/evregion.c b/trunk/drivers/acpi/events/evregion.c index e99f0c435a47..21caae04fe85 100644 --- a/trunk/drivers/acpi/events/evregion.c +++ b/trunk/drivers/acpi/events/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -291,6 +291,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 bit_width, acpi_integer * value) { acpi_status status; + acpi_status status2; acpi_adr_space_handler handler; acpi_adr_space_setup region_setup; union acpi_operand_object *handler_desc; @@ -344,7 +345,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * setup will potentially execute control methods * (e.g., _REG method for this region) */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = region_setup(region_obj, ACPI_REGION_ACTIVATE, handler_desc->address_space.context, @@ -352,7 +353,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, /* Re-enter the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } /* Check for failure of the Region Setup */ @@ -405,7 +409,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); } /* Call the handler */ @@ -426,7 +430,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * We just returned from a non-default handler, we must re-enter the * interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); diff --git a/trunk/drivers/acpi/events/evrgnini.c b/trunk/drivers/acpi/events/evrgnini.c index a4fa7e6822a3..203d1359190a 100644 --- a/trunk/drivers/acpi/events/evrgnini.c +++ b/trunk/drivers/acpi/events/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,11 +48,6 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evrgnini") -/* Local prototypes */ -static u8 acpi_ev_match_pci_root_bridge(char *id); - -static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); - /******************************************************************************* * * FUNCTION: acpi_ev_system_memory_region_setup @@ -67,7 +62,6 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); * DESCRIPTION: Setup a system_memory operation region * ******************************************************************************/ - acpi_status acpi_ev_system_memory_region_setup(acpi_handle handle, u32 function, @@ -174,9 +168,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, union acpi_operand_object *handler_obj; struct acpi_namespace_node *parent_node; struct acpi_namespace_node *pci_root_node; - struct acpi_namespace_node *pci_device_node; union acpi_operand_object *region_obj = (union acpi_operand_object *)handle; + struct acpi_device_id object_hID; ACPI_FUNCTION_TRACE(ev_pci_config_region_setup); @@ -221,30 +215,45 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, pci_root_node = parent_node; while (pci_root_node != acpi_gbl_root_node) { + status = + acpi_ut_execute_HID(pci_root_node, &object_hID); + if (ACPI_SUCCESS(status)) { + /* + * Got a valid _HID string, check if this is a PCI root. + * New for ACPI 3.0: check for a PCI Express root also. + */ + if (! + (ACPI_STRNCMP + (object_hID.value, PCI_ROOT_HID_STRING, + sizeof(PCI_ROOT_HID_STRING))) + || + !(ACPI_STRNCMP + (object_hID.value, + PCI_EXPRESS_ROOT_HID_STRING, + sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { + + /* Install a handler for this PCI root bridge */ - /* Get the _HID/_CID in order to detect a root_bridge */ - - if (acpi_ev_is_pci_root_bridge(pci_root_node)) { - - /* Install a handler for this PCI root bridge */ - - status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); - if (ACPI_FAILURE(status)) { - if (status == AE_SAME_HANDLER) { - /* - * It is OK if the handler is already installed on the root - * bridge. Still need to return a context object for the - * new PCI_Config operation region, however. - */ - status = AE_OK; - } else { - ACPI_EXCEPTION((AE_INFO, status, - "Could not install PciConfig handler for Root Bridge %4.4s", - acpi_ut_get_node_name - (pci_root_node))); + status = + acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); + if (ACPI_FAILURE(status)) { + if (status == AE_SAME_HANDLER) { + /* + * It is OK if the handler is already installed on the root + * bridge. Still need to return a context object for the + * new PCI_Config operation region, however. + */ + status = AE_OK; + } else { + ACPI_EXCEPTION((AE_INFO, + status, + "Could not install PciConfig handler for Root Bridge %4.4s", + acpi_ut_get_node_name + (pci_root_node))); + } } + break; } - break; } pci_root_node = acpi_ns_get_parent_node(pci_root_node); @@ -273,25 +282,14 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, /* * For PCI_Config space access, we need the segment, bus, * device and function numbers. Acquire them here. - * - * Find the parent device object. (This allows the operation region to be - * within a subscope under the device, such as a control method.) */ - pci_device_node = region_obj->region.node; - while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) { - pci_device_node = acpi_ns_get_parent_node(pci_device_node); - } - - if (!pci_device_node) { - return_ACPI_STATUS(AE_AML_OPERAND_TYPE); - } /* * Get the PCI device and function numbers from the _ADR object * contained in the parent's scope. */ status = - acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node, + acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node, &pci_value); /* @@ -329,91 +327,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_match_pci_root_bridge - * - * PARAMETERS: Id - The HID/CID in string format - * - * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge - * - * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. - * - ******************************************************************************/ - -static u8 acpi_ev_match_pci_root_bridge(char *id) -{ - - /* - * Check if this is a PCI root. - * ACPI 3.0+: check for a PCI Express root also. - */ - if (!(ACPI_STRNCMP(id, - PCI_ROOT_HID_STRING, - sizeof(PCI_ROOT_HID_STRING))) || - !(ACPI_STRNCMP(id, - PCI_EXPRESS_ROOT_HID_STRING, - sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { - return (TRUE); - } - - return (FALSE); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ev_is_pci_root_bridge - * - * PARAMETERS: Node - Device node being examined - * - * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge - * - * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by - * examining the _HID and _CID for the device. - * - ******************************************************************************/ - -static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) -{ - acpi_status status; - struct acpi_device_id hid; - struct acpi_compatible_id_list *cid; - acpi_native_uint i; - - /* - * Get the _HID and check for a PCI Root Bridge - */ - status = acpi_ut_execute_HID(node, &hid); - if (ACPI_FAILURE(status)) { - return (FALSE); - } - - if (acpi_ev_match_pci_root_bridge(hid.value)) { - return (TRUE); - } - - /* - * The _HID did not match. - * Get the _CID and check for a PCI Root Bridge - */ - status = acpi_ut_execute_CID(node, &cid); - if (ACPI_FAILURE(status)) { - return (FALSE); - } - - /* Check all _CIDs in the returned list */ - - for (i = 0; i < cid->count; i++) { - if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) { - ACPI_FREE(cid); - return (TRUE); - } - } - - ACPI_FREE(cid); - return (FALSE); -} - /******************************************************************************* * * FUNCTION: acpi_ev_pci_bar_region_setup @@ -519,9 +432,6 @@ acpi_ev_default_region_setup(acpi_handle handle, * a PCI address in the scope of the definition. This address is * required to perform an access to PCI config space. * - * MUTEX: Interpreter should be unlocked, because we may run the _REG - * method for this region. - * ******************************************************************************/ acpi_status diff --git a/trunk/drivers/acpi/events/evsci.c b/trunk/drivers/acpi/events/evsci.c index 7e5d15ce2395..8106215ad554 100644 --- a/trunk/drivers/acpi/events/evsci.c +++ b/trunk/drivers/acpi/events/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -142,10 +142,9 @@ u32 acpi_ev_install_sci_handler(void) ACPI_FUNCTION_TRACE(ev_install_sci_handler); - status = - acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, - acpi_ev_sci_xrupt_handler, - acpi_gbl_gpe_xrupt_list_head); + status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int, + acpi_ev_sci_xrupt_handler, + acpi_gbl_gpe_xrupt_list_head); return_ACPI_STATUS(status); } @@ -176,9 +175,8 @@ acpi_status acpi_ev_remove_sci_handler(void) /* Just let the OS remove the handler and disable the level */ - status = - acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, - acpi_ev_sci_xrupt_handler); + status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int, + acpi_ev_sci_xrupt_handler); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/events/evxface.c b/trunk/drivers/acpi/events/evxface.c index 685a103a3587..923fd2b46955 100644 --- a/trunk/drivers/acpi/events/evxface.c +++ b/trunk/drivers/acpi/events/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -768,9 +768,11 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) return (AE_BAD_PARAMETER); } - /* Must lock interpreter to prevent race conditions */ + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return (status); + } - acpi_ex_enter_interpreter(); status = acpi_ev_acquire_global_lock(timeout); acpi_ex_exit_interpreter(); diff --git a/trunk/drivers/acpi/events/evxfevnt.c b/trunk/drivers/acpi/events/evxfevnt.c index 17065e98807c..7ebc2efac936 100644 --- a/trunk/drivers/acpi/events/evxfevnt.c +++ b/trunk/drivers/acpi/events/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,6 @@ #include #include #include -#include #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxfevnt") @@ -66,14 +65,13 @@ acpi_status acpi_enable(void) ACPI_FUNCTION_TRACE(acpi_enable); - /* ACPI tables must be present */ + /* Make sure we have the FADT */ - if (!acpi_tb_tables_loaded()) { + if (!acpi_gbl_FADT) { + ACPI_WARNING((AE_INFO, "No FADT information present!")); return_ACPI_STATUS(AE_NO_ACPI_TABLES); } - /* Check current mode */ - if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in ACPI mode\n")); @@ -113,6 +111,11 @@ acpi_status acpi_disable(void) ACPI_FUNCTION_TRACE(acpi_disable); + if (!acpi_gbl_FADT) { + ACPI_WARNING((AE_INFO, "No FADT information present!")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n")); @@ -166,7 +169,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, 1); + enable_register_id, 1, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -175,7 +178,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags) status = acpi_get_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, &value); + enable_register_id, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -365,14 +368,14 @@ acpi_status acpi_disable_event(u32 event, u32 flags) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, 0); + enable_register_id, 0, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_get_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, &value); + enable_register_id, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -418,7 +421,7 @@ acpi_status acpi_clear_event(u32 event) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. - status_register_id, 1); + status_register_id, 1, ACPI_MTX_LOCK); return_ACPI_STATUS(status); } @@ -507,7 +510,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) status = acpi_get_register(acpi_gbl_fixed_event_info[event]. - status_register_id, event_status); + status_register_id, event_status, ACPI_MTX_LOCK); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/events/evxfregn.c b/trunk/drivers/acpi/events/evxfregn.c index 7bf09c5fb242..83b12a9afa32 100644 --- a/trunk/drivers/acpi/events/evxfregn.c +++ b/trunk/drivers/acpi/events/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exconfig.c b/trunk/drivers/acpi/executer/exconfig.c index 25802f302ffe..c8341fa5fe01 100644 --- a/trunk/drivers/acpi/executer/exconfig.c +++ b/trunk/drivers/acpi/executer/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig") /* Local prototypes */ static acpi_status -acpi_ex_add_table(acpi_native_uint table_index, +acpi_ex_add_table(struct acpi_table_header *table, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle); @@ -74,11 +74,12 @@ acpi_ex_add_table(acpi_native_uint table_index, ******************************************************************************/ static acpi_status -acpi_ex_add_table(acpi_native_uint table_index, +acpi_ex_add_table(struct acpi_table_header *table, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle) { acpi_status status; + struct acpi_table_desc table_info; union acpi_operand_object *obj_desc; ACPI_FUNCTION_TRACE(ex_add_table); @@ -97,16 +98,42 @@ acpi_ex_add_table(acpi_native_uint table_index, /* Install the new table into the local data structures */ - obj_desc->reference.object = ACPI_CAST_PTR(void, table_index); + ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); + + table_info.type = ACPI_TABLE_ID_SSDT; + table_info.pointer = table; + table_info.length = (acpi_size) table->length; + table_info.allocation = ACPI_MEM_ALLOCATED; + + status = acpi_tb_install_table(&table_info); + obj_desc->reference.object = table_info.installed_desc; + + if (ACPI_FAILURE(status)) { + if (status == AE_ALREADY_EXISTS) { + + /* Table already exists, just return the handle */ + + return_ACPI_STATUS(AE_OK); + } + goto cleanup; + } /* Add the table to the namespace */ - status = acpi_ns_load_table(table_index, parent_node); + status = acpi_ns_load_table(table_info.installed_desc, parent_node); if (ACPI_FAILURE(status)) { - acpi_ut_remove_reference(obj_desc); - *ddb_handle = NULL; + + /* Uninstall table on error */ + + (void)acpi_tb_uninstall_table(table_info.installed_desc); + goto cleanup; } + return_ACPI_STATUS(AE_OK); + + cleanup: + acpi_ut_remove_reference(obj_desc); + *ddb_handle = NULL; return_ACPI_STATUS(status); } @@ -119,7 +146,7 @@ acpi_ex_add_table(acpi_native_uint table_index, * * RETURN: Status * - * DESCRIPTION: Load an ACPI table from the RSDT/XSDT + * DESCRIPTION: Load an ACPI table * ******************************************************************************/ @@ -129,20 +156,33 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, { acpi_status status; union acpi_operand_object **operand = &walk_state->operands[0]; - acpi_native_uint table_index; + struct acpi_table_header *table; struct acpi_namespace_node *parent_node; struct acpi_namespace_node *start_node; struct acpi_namespace_node *parameter_node = NULL; union acpi_operand_object *ddb_handle; - struct acpi_table_header *table; ACPI_FUNCTION_TRACE(ex_load_table_op); - /* Find the ACPI table in the RSDT/XSDT */ +#if 0 + /* + * Make sure that the signature does not match one of the tables that + * is already loaded. + */ + status = acpi_tb_match_signature(operand[0]->string.pointer, NULL); + if (status == AE_OK) { + + /* Signature matched -- don't allow override */ + + return_ACPI_STATUS(AE_ALREADY_EXISTS); + } +#endif + + /* Find the ACPI table */ status = acpi_tb_find_table(operand[0]->string.pointer, operand[1]->string.pointer, - operand[2]->string.pointer, &table_index); + operand[2]->string.pointer, &table); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { return_ACPI_STATUS(status); @@ -205,7 +245,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, /* Load the table into the namespace */ - status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); + status = acpi_ex_add_table(table, parent_node, &ddb_handle); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -226,13 +266,9 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, } } - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_SUCCESS(status)) { - ACPI_INFO((AE_INFO, - "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", - table->signature, table->oem_id, - table->oem_table_id)); - } + ACPI_INFO((AE_INFO, + "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", + table->signature, table->oem_id, table->oem_table_id)); *return_desc = ddb_handle; return_ACPI_STATUS(status); @@ -242,7 +278,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, * * FUNCTION: acpi_ex_load_op * - * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be + * PARAMETERS: obj_desc - Region or Field where the table will be * obtained * Target - Where a handle to the table will be stored * walk_state - Current state @@ -251,12 +287,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, * * DESCRIPTION: Load an ACPI table from a field or operation region * - * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer - * objects before this code is reached. - * - * If source is an operation region, it must refer to system_memory, as - * per the ACPI specification. - * ******************************************************************************/ acpi_status @@ -264,26 +294,22 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, union acpi_operand_object *target, struct acpi_walk_state *walk_state) { - union acpi_operand_object *ddb_handle; - struct acpi_table_desc table_desc; - acpi_native_uint table_index; acpi_status status; + union acpi_operand_object *ddb_handle; + union acpi_operand_object *buffer_desc = NULL; + struct acpi_table_header *table_ptr = NULL; + acpi_physical_address address; + struct acpi_table_header table_header; + acpi_integer temp; + u32 i; ACPI_FUNCTION_TRACE(ex_load_op); - ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); - - /* Source Object can be either an op_region or a Buffer/Field */ + /* Object can be either an op_region or a Field */ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_REGION: - /* Region must be system_memory (from ACPI spec) */ - - if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { - return_ACPI_STATUS(AE_AML_OPERAND_TYPE); - } - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", obj_desc, acpi_ut_get_object_type_name(obj_desc))); @@ -299,41 +325,113 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, } } - table_desc.address = obj_desc->region.address; - table_desc.length = obj_desc->region.length; - table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; - break; + /* Get the base physical address of the region */ - case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ + address = obj_desc->region.address; - /* Simply extract the buffer from the buffer object */ + /* Get part of the table header to get the table length */ - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Load from Buffer or Field %p %s\n", obj_desc, + table_header.length = 0; + for (i = 0; i < 8; i++) { + status = + acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, + (acpi_physical_address) + (i + address), 8, + &temp); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the one valid byte of the returned 64-bit value */ + + ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp; + } + + /* Sanity check the table length */ + + if (table_header.length < sizeof(struct acpi_table_header)) { + return_ACPI_STATUS(AE_BAD_HEADER); + } + + /* Allocate a buffer for the entire table */ + + table_ptr = ACPI_ALLOCATE(table_header.length); + if (!table_ptr) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Get the entire table from the op region */ + + for (i = 0; i < table_header.length; i++) { + status = + acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, + (acpi_physical_address) + (i + address), 8, + &temp); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* Get the one valid byte of the returned 64-bit value */ + + ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp; + } + break; + + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Field %p %s\n", + obj_desc, acpi_ut_get_object_type_name(obj_desc))); - table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header, - obj_desc->buffer.pointer); - table_desc.length = table_desc.pointer->length; - table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; + /* + * The length of the field must be at least as large as the table. + * Read the entire field and thus the entire table. Buffer is + * allocated during the read. + */ + status = + acpi_ex_read_data_from_field(walk_state, obj_desc, + &buffer_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + table_ptr = ACPI_CAST_PTR(struct acpi_table_header, + buffer_desc->buffer.pointer); + + /* All done with the buffer_desc, delete it */ + + buffer_desc->buffer.pointer = NULL; + acpi_ut_remove_reference(buffer_desc); + + /* Sanity check the table length */ - obj_desc->buffer.pointer = NULL; + if (table_ptr->length < sizeof(struct acpi_table_header)) { + status = AE_BAD_HEADER; + goto cleanup; + } break; default: return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } - /* - * Install the new table into the local data structures - */ - status = acpi_tb_add_table(&table_desc, &table_index); - if (ACPI_FAILURE(status)) { + /* The table must be either an SSDT or a PSDT */ + + if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) && + (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) { + ACPI_ERROR((AE_INFO, + "Table has invalid signature [%4.4s], must be SSDT or PSDT", + table_ptr->signature)); + status = AE_BAD_SIGNATURE; goto cleanup; } - status = - acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); + /* Install the new table into the local data structures */ + + status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle); if (ACPI_FAILURE(status)) { /* On error, table_ptr was deallocated above */ @@ -352,9 +450,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, return_ACPI_STATUS(status); } + ACPI_INFO((AE_INFO, + "Dynamic SSDT Load - OemId [%6.6s] OemTableId [%8.8s]", + table_ptr->oem_id, table_ptr->oem_table_id)); + cleanup: if (ACPI_FAILURE(status)) { - acpi_tb_delete_table(&table_desc); + ACPI_FREE(table_ptr); } return_ACPI_STATUS(status); } @@ -375,7 +477,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) { acpi_status status = AE_OK; union acpi_operand_object *table_desc = ddb_handle; - acpi_native_uint table_index; + struct acpi_table_desc *table_info; ACPI_FUNCTION_TRACE(ex_unload_table); @@ -391,18 +493,19 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the table index from the ddb_handle */ + /* Get the actual table descriptor from the ddb_handle */ - table_index = (acpi_native_uint) table_desc->reference.object; + table_info = (struct acpi_table_desc *)table_desc->reference.object; /* * Delete the entire namespace under this table Node * (Offset contains the table_id) */ - acpi_tb_delete_namespace_by_owner(table_index); - acpi_tb_release_owner_id(table_index); + acpi_ns_delete_namespace_by_owner(table_info->owner_id); + + /* Delete the table itself */ - acpi_tb_set_table_loaded_flag(table_index, FALSE); + (void)acpi_tb_uninstall_table(table_info->installed_desc); /* Delete the table descriptor (ddb_handle) */ diff --git a/trunk/drivers/acpi/executer/exconvrt.c b/trunk/drivers/acpi/executer/exconvrt.c index d470e8b1f4ea..544e81a6a438 100644 --- a/trunk/drivers/acpi/executer/exconvrt.c +++ b/trunk/drivers/acpi/executer/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/excreate.c b/trunk/drivers/acpi/executer/excreate.c index 7c38528a7e83..34eec82c1b1e 100644 --- a/trunk/drivers/acpi/executer/excreate.c +++ b/trunk/drivers/acpi/executer/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -359,9 +359,8 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *obj_desc; struct acpi_namespace_node *node; - union acpi_operand_object *region_obj2; - acpi_native_uint table_index; struct acpi_table_header *table; + union acpi_operand_object *region_obj2; ACPI_FUNCTION_TRACE(ex_create_table_region); @@ -381,7 +380,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) status = acpi_tb_find_table(operand[1]->string.pointer, operand[2]->string.pointer, - operand[3]->string.pointer, &table_index); + operand[3]->string.pointer, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -396,11 +395,6 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) region_obj2 = obj_desc->common.next_object; region_obj2->extra.region_context = NULL; - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Init the region from the operands */ obj_desc->region.space_id = REGION_DATA_TABLE; @@ -559,8 +553,7 @@ acpi_ex_create_method(u8 * aml_start, obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); if (!obj_desc) { - status = AE_NO_MEMORY; - goto exit; + return_ACPI_STATUS(AE_NO_MEMORY); } /* Save the method's AML pointer and length */ @@ -583,7 +576,10 @@ acpi_ex_create_method(u8 * aml_start, * Get the sync_level. If method is serialized, a mutex will be * created for this method when it is parsed. */ - if (method_flags & AML_METHOD_SERIALIZED) { + if (acpi_gbl_all_methods_serialized) { + obj_desc->method.sync_level = 0; + obj_desc->method.method_flags |= AML_METHOD_SERIALIZED; + } else if (method_flags & AML_METHOD_SERIALIZED) { /* * ACPI 1.0: sync_level = 0 * ACPI 2.0: sync_level = sync_level in method declaration @@ -601,7 +597,6 @@ acpi_ex_create_method(u8 * aml_start, acpi_ut_remove_reference(obj_desc); - exit: /* Remove a reference to the operand */ acpi_ut_remove_reference(operand[1]); diff --git a/trunk/drivers/acpi/executer/exdump.c b/trunk/drivers/acpi/executer/exdump.c index 68d283fd60e7..2450943add33 100644 --- a/trunk/drivers/acpi/executer/exdump.c +++ b/trunk/drivers/acpi/executer/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,6 +59,8 @@ static void acpi_ex_out_string(char *title, char *value); static void acpi_ex_out_pointer(char *title, void *value); +static void acpi_ex_out_address(char *title, acpi_physical_address value); + static void acpi_ex_dump_object(union acpi_operand_object *obj_desc, struct acpi_exdump_info *info); @@ -90,11 +92,10 @@ static struct acpi_exdump_info acpi_ex_dump_string[4] = { {ACPI_EXD_STRING, 0, NULL} }; -static struct acpi_exdump_info acpi_ex_dump_buffer[5] = { +static struct acpi_exdump_info acpi_ex_dump_buffer[4] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.node), "Parent Node"}, {ACPI_EXD_BUFFER, 0, NULL} }; @@ -164,8 +165,8 @@ static struct acpi_exdump_info acpi_ex_dump_power[5] = { static struct acpi_exdump_info acpi_ex_dump_processor[7] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"}, {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify), "System Notify"}, @@ -378,12 +379,18 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, break; case ACPI_EXD_POINTER: - case ACPI_EXD_ADDRESS: acpi_ex_out_pointer(name, *ACPI_CAST_PTR(void *, target)); break; + case ACPI_EXD_ADDRESS: + + acpi_ex_out_address(name, + *ACPI_CAST_PTR + (acpi_physical_address, target)); + break; + case ACPI_EXD_STRING: acpi_ut_print_string(obj_desc->string.pointer, @@ -827,6 +834,16 @@ static void acpi_ex_out_pointer(char *title, void *value) acpi_os_printf("%20s : %p\n", title, value); } +static void acpi_ex_out_address(char *title, acpi_physical_address value) +{ + +#if ACPI_MACHINE_WIDTH == 16 + acpi_os_printf("%20s : %p\n", title, value); +#else + acpi_os_printf("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value)); +#endif +} + /******************************************************************************* * * FUNCTION: acpi_ex_dump_namespace_node diff --git a/trunk/drivers/acpi/executer/exfield.c b/trunk/drivers/acpi/executer/exfield.c index 2d88a3d8d1ad..9ea9c3a67ca9 100644 --- a/trunk/drivers/acpi/executer/exfield.c +++ b/trunk/drivers/acpi/executer/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exfldio.c b/trunk/drivers/acpi/executer/exfldio.c index 65a48b6170ee..40f0bee6faa5 100644 --- a/trunk/drivers/acpi/executer/exfldio.c +++ b/trunk/drivers/acpi/executer/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -257,13 +257,14 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, } ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, - " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n", + " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", acpi_ut_get_region_name(rgn_desc->region. space_id), rgn_desc->region.space_id, obj_desc->common_field.access_byte_width, obj_desc->common_field.base_byte_offset, - field_datum_byte_offset, (void *)address)); + field_datum_byte_offset, + ACPI_FORMAT_UINT64(address))); /* Invoke the appropriate address_space/op_region handler */ diff --git a/trunk/drivers/acpi/executer/exmisc.c b/trunk/drivers/acpi/executer/exmisc.c index f13d1cec2d6d..bd98aab017cf 100644 --- a/trunk/drivers/acpi/executer/exmisc.c +++ b/trunk/drivers/acpi/executer/exmisc.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exmutex.c b/trunk/drivers/acpi/executer/exmutex.c index 5101bad5baf8..bf90f04f2c60 100644 --- a/trunk/drivers/acpi/executer/exmutex.c +++ b/trunk/drivers/acpi/executer/exmutex.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,6 @@ #include #include -#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exmutex") @@ -151,7 +150,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Sanity check: we must have a valid thread ID */ + /* Sanity check -- we must have a valid thread ID */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO, @@ -175,28 +174,24 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Support for multiple acquires by the owning thread */ if (obj_desc->mutex.owner_thread) { - if (obj_desc->mutex.owner_thread->thread_id == - walk_state->thread->thread_id) { + + /* Special case for Global Lock, allow all threads */ + + if ((obj_desc->mutex.owner_thread->thread_id == + walk_state->thread->thread_id) || + (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK)) { /* - * The mutex is already owned by this thread, just increment the - * acquisition depth + * The mutex is already owned by this thread, + * just increment the acquisition depth */ obj_desc->mutex.acquisition_depth++; return_ACPI_STATUS(AE_OK); } } - /* Acquire the mutex, wait if necessary. Special case for Global Lock */ - - if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { - status = - acpi_ev_acquire_global_lock((u16) time_desc->integer.value); - } else { - status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, - (u16) time_desc->integer. - value); - } + /* Acquire the mutex, wait if necessary */ + status = acpi_ex_system_acquire_mutex(time_desc, obj_desc); if (ACPI_FAILURE(status)) { /* Includes failure from a timeout on time_desc */ @@ -216,6 +211,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Link the mutex to the current thread for force-unlock at method exit */ acpi_ex_link_mutex(obj_desc, walk_state->thread); + return_ACPI_STATUS(AE_OK); } @@ -236,7 +232,7 @@ acpi_status acpi_ex_release_mutex(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { - acpi_status status = AE_OK; + acpi_status status; ACPI_FUNCTION_TRACE(ex_release_mutex); @@ -253,7 +249,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); } - /* Sanity check: we must have a valid thread ID */ + /* Sanity check -- we must have a valid thread ID */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO, @@ -268,7 +264,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, */ if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) - && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { + && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { ACPI_ERROR((AE_INFO, "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", (unsigned long)walk_state->thread->thread_id, @@ -278,8 +274,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, } /* - * The sync level of the mutex must be less than or equal to the current - * sync level + * The sync level of the mutex must be less than or + * equal to the current sync level */ if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { ACPI_ERROR((AE_INFO, @@ -302,15 +298,11 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, acpi_ex_unlink_mutex(obj_desc); - /* Release the mutex, special case for Global Lock */ + /* Release the mutex */ - if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { - status = acpi_ev_release_global_lock(); - } else { - acpi_os_release_mutex(obj_desc->mutex.os_mutex); - } + status = acpi_ex_system_release_mutex(obj_desc); - /* Update the mutex and restore sync_level */ + /* Update the mutex and walk state, restore sync_level before acquire */ obj_desc->mutex.owner_thread = NULL; walk_state->thread->current_sync_level = @@ -329,49 +321,39 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, * * DESCRIPTION: Release all mutexes held by this thread * - * NOTE: This function is called as the thread is exiting the interpreter. - * Mutexes are not released when an individual control method is exited, but - * only when the parent thread actually exits the interpreter. This allows one - * method to acquire a mutex, and a different method to release it, as long as - * this is performed underneath a single parent control method. - * ******************************************************************************/ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) { union acpi_operand_object *next = thread->acquired_mutex_list; - union acpi_operand_object *obj_desc; + union acpi_operand_object *this; + acpi_status status; ACPI_FUNCTION_ENTRY(); /* Traverse the list of owned mutexes, releasing each one */ while (next) { - obj_desc = next; - next = obj_desc->mutex.next; - - obj_desc->mutex.prev = NULL; - obj_desc->mutex.next = NULL; - obj_desc->mutex.acquisition_depth = 0; - - /* Release the mutex, special case for Global Lock */ + this = next; + next = this->mutex.next; - if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { + this->mutex.acquisition_depth = 1; + this->mutex.prev = NULL; + this->mutex.next = NULL; - /* Ignore errors */ + /* Release the mutex */ - (void)acpi_ev_release_global_lock(); - } else { - acpi_os_release_mutex(obj_desc->mutex.os_mutex); + status = acpi_ex_system_release_mutex(this); + if (ACPI_FAILURE(status)) { + continue; } /* Mark mutex unowned */ - obj_desc->mutex.owner_thread = NULL; + this->mutex.owner_thread = NULL; /* Update Thread sync_level (Last mutex is the important one) */ - thread->current_sync_level = - obj_desc->mutex.original_sync_level; + thread->current_sync_level = this->mutex.original_sync_level; } } diff --git a/trunk/drivers/acpi/executer/exnames.c b/trunk/drivers/acpi/executer/exnames.c index 1ee4fb1175c6..d3d70364626c 100644 --- a/trunk/drivers/acpi/executer/exnames.c +++ b/trunk/drivers/acpi/executer/exnames.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exoparg1.c b/trunk/drivers/acpi/executer/exoparg1.c index 252f10acbbcc..6374d8be88e0 100644 --- a/trunk/drivers/acpi/executer/exoparg1.c +++ b/trunk/drivers/acpi/executer/exoparg1.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -104,7 +104,9 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) status = AE_NO_MEMORY; goto cleanup; } +#if ACPI_MACHINE_WIDTH != 16 return_desc->integer.value = acpi_os_get_timer(); +#endif break; default: /* Unknown opcode */ diff --git a/trunk/drivers/acpi/executer/exoparg2.c b/trunk/drivers/acpi/executer/exoparg2.c index 17e652e65379..7d2cbc113160 100644 --- a/trunk/drivers/acpi/executer/exoparg2.c +++ b/trunk/drivers/acpi/executer/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exoparg3.c b/trunk/drivers/acpi/executer/exoparg3.c index 7fe67cf82cee..e2d945dfd509 100644 --- a/trunk/drivers/acpi/executer/exoparg3.c +++ b/trunk/drivers/acpi/executer/exoparg3.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exoparg6.c b/trunk/drivers/acpi/executer/exoparg6.c index bd80a9cb3d65..f0c0ba6eb408 100644 --- a/trunk/drivers/acpi/executer/exoparg6.c +++ b/trunk/drivers/acpi/executer/exoparg6.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exprep.c b/trunk/drivers/acpi/executer/exprep.c index a6696621ff1b..44d064f427b9 100644 --- a/trunk/drivers/acpi/executer/exprep.c +++ b/trunk/drivers/acpi/executer/exprep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exregion.c b/trunk/drivers/acpi/executer/exregion.c index 2e9ce94798c7..3cc97ba48b36 100644 --- a/trunk/drivers/acpi/executer/exregion.c +++ b/trunk/drivers/acpi/executer/exregion.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -155,15 +155,16 @@ acpi_ex_system_memory_space_handler(u32 function, /* Create a new mapping starting at the address given */ - mem_info->mapped_logical_address = - acpi_os_map_memory((acpi_native_uint) address, window_size); - if (!mem_info->mapped_logical_address) { + status = acpi_os_map_memory(address, window_size, + (void **)&mem_info-> + mapped_logical_address); + if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", ACPI_FORMAT_UINT64(address), (u32) window_size)); mem_info->mapped_length = 0; - return_ACPI_STATUS(AE_NO_MEMORY); + return_ACPI_STATUS(status); } /* Save the physical address and mapping size */ @@ -209,10 +210,11 @@ acpi_ex_system_memory_space_handler(u32 function, *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); break; +#if ACPI_MACHINE_WIDTH != 16 case 64: *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); break; - +#endif default: /* bit_width was already validated */ break; @@ -234,9 +236,11 @@ acpi_ex_system_memory_space_handler(u32 function, ACPI_SET32(logical_addr_ptr) = (u32) * value; break; +#if ACPI_MACHINE_WIDTH != 16 case 64: ACPI_SET64(logical_addr_ptr) = (u64) * value; break; +#endif default: /* bit_width was already validated */ diff --git a/trunk/drivers/acpi/executer/exresnte.c b/trunk/drivers/acpi/executer/exresnte.c index 2b3a01cc4929..3089b05a1368 100644 --- a/trunk/drivers/acpi/executer/exresnte.c +++ b/trunk/drivers/acpi/executer/exresnte.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exresolv.c b/trunk/drivers/acpi/executer/exresolv.c index 6c64e55dab0e..6499de878017 100644 --- a/trunk/drivers/acpi/executer/exresolv.c +++ b/trunk/drivers/acpi/executer/exresolv.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -141,7 +141,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, acpi_status status = AE_OK; union acpi_operand_object *stack_desc; void *temp_node; - union acpi_operand_object *obj_desc = NULL; + union acpi_operand_object *obj_desc; u16 opcode; ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); @@ -299,6 +299,8 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, status = acpi_ds_get_package_arguments(stack_desc); break; + /* These cases may never happen here, but just in case.. */ + case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: @@ -312,10 +314,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, status = acpi_ex_read_data_from_field(walk_state, stack_desc, &obj_desc); - - /* Remove a reference to the original operand, then override */ - - acpi_ut_remove_reference(*stack_ptr); *stack_ptr = (void *)obj_desc; break; diff --git a/trunk/drivers/acpi/executer/exresop.c b/trunk/drivers/acpi/executer/exresop.c index ba761862a599..4c93d0972333 100644 --- a/trunk/drivers/acpi/executer/exresop.c +++ b/trunk/drivers/acpi/executer/exresop.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -611,20 +611,22 @@ acpi_ex_resolve_operands(u16 opcode, } goto next_operand; - case ARGI_REGION_OR_BUFFER: /* Used by Load() only */ + case ARGI_REGION_OR_FIELD: - /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */ + /* Need an operand of type REGION or a FIELD in a region */ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_BUFFER: case ACPI_TYPE_REGION: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: /* Valid operand */ break; default: ACPI_ERROR((AE_INFO, - "Needed [Region/Buffer], found [%s] %p", + "Needed [Region/RegionField], found [%s] %p", acpi_ut_get_object_type_name (obj_desc), obj_desc)); diff --git a/trunk/drivers/acpi/executer/exstore.c b/trunk/drivers/acpi/executer/exstore.c index f4b69a637820..0456405ba019 100644 --- a/trunk/drivers/acpi/executer/exstore.c +++ b/trunk/drivers/acpi/executer/exstore.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exstoren.c b/trunk/drivers/acpi/executer/exstoren.c index 1d622c625c64..591aaf0e18b3 100644 --- a/trunk/drivers/acpi/executer/exstoren.c +++ b/trunk/drivers/acpi/executer/exstoren.c @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exstorob.c b/trunk/drivers/acpi/executer/exstorob.c index 8233d40178ee..99ebe5adfcda 100644 --- a/trunk/drivers/acpi/executer/exstorob.c +++ b/trunk/drivers/acpi/executer/exstorob.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/executer/exsystem.c b/trunk/drivers/acpi/executer/exsystem.c index 9460baff3032..28aef3e69ecc 100644 --- a/trunk/drivers/acpi/executer/exsystem.c +++ b/trunk/drivers/acpi/executer/exsystem.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,6 +66,7 @@ ACPI_MODULE_NAME("exsystem") acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) { acpi_status status; + acpi_status status2; ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); @@ -78,7 +79,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_wait_semaphore(semaphore, 1, timeout); @@ -88,7 +89,13 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + + /* Report fatal error, could not acquire interpreter */ + + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); @@ -112,6 +119,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) { acpi_status status; + acpi_status status2; ACPI_FUNCTION_TRACE(ex_system_wait_mutex); @@ -124,7 +132,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_acquire_mutex(mutex, timeout); @@ -134,7 +142,13 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + + /* Report fatal error, could not acquire interpreter */ + + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); @@ -195,18 +209,96 @@ acpi_status acpi_ex_system_do_stall(u32 how_long) acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) { + acpi_status status; + ACPI_FUNCTION_ENTRY(); /* Since this thread will sleep, we must release the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); acpi_os_sleep(how_long); /* And now we must get the interpreter again */ - acpi_ex_reacquire_interpreter(); - return (AE_OK); + status = acpi_ex_enter_interpreter(); + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_system_acquire_mutex + * + * PARAMETERS: time_desc - Maximum time to wait for the mutex + * obj_desc - The object descriptor for this op + * + * RETURN: Status + * + * DESCRIPTION: Provides an access point to perform synchronization operations + * within the AML. This function will cause a lock to be generated + * for the Mutex pointed to by obj_desc. + * + ******************************************************************************/ + +acpi_status +acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc, + union acpi_operand_object * obj_desc) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE_PTR(ex_system_acquire_mutex, obj_desc); + + if (!obj_desc) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Support for the _GL_ Mutex object -- go get the global lock */ + + if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) { + status = + acpi_ev_acquire_global_lock((u16) time_desc->integer.value); + return_ACPI_STATUS(status); + } + + status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, + (u16) time_desc->integer.value); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_system_release_mutex + * + * PARAMETERS: obj_desc - The object descriptor for this op + * + * RETURN: Status + * + * DESCRIPTION: Provides an access point to perform synchronization operations + * within the AML. This operation is a request to release a + * previously acquired Mutex. If the Mutex variable is set then + * it will be decremented. + * + ******************************************************************************/ + +acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE(ex_system_release_mutex); + + if (!obj_desc) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Support for the _GL_ Mutex object -- release the global lock */ + + if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) { + status = acpi_ev_release_global_lock(); + return_ACPI_STATUS(status); + } + + acpi_os_release_mutex(obj_desc->mutex.os_mutex); + return_ACPI_STATUS(AE_OK); } /******************************************************************************* @@ -222,7 +314,7 @@ acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) * ******************************************************************************/ -acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) +acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc) { acpi_status status = AE_OK; diff --git a/trunk/drivers/acpi/executer/exutils.c b/trunk/drivers/acpi/executer/exutils.c index 6b0aeccbb69b..982c8b65876f 100644 --- a/trunk/drivers/acpi/executer/exutils.c +++ b/trunk/drivers/acpi/executer/exutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -76,15 +76,14 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base); * * PARAMETERS: None * - * RETURN: None + * RETURN: Status * - * DESCRIPTION: Enter the interpreter execution region. Failure to enter - * the interpreter region is a fatal system error. Used in - * conjunction with exit_interpreter. + * DESCRIPTION: Enter the interpreter execution region. Failure to enter + * the interpreter region is a fatal system error * ******************************************************************************/ -void acpi_ex_enter_interpreter(void) +acpi_status acpi_ex_enter_interpreter(void) { acpi_status status; @@ -92,42 +91,10 @@ void acpi_ex_enter_interpreter(void) status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not acquire AML Interpreter mutex")); + ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); } - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ex_reacquire_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Reacquire the interpreter execution region from within the - * interpreter code. Failure to enter the interpreter region is a - * fatal system error. Used in conjuction with - * relinquish_interpreter - * - ******************************************************************************/ - -void acpi_ex_reacquire_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_reacquire_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter, - * since it was not actually released by acpi_ex_relinquish_interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_enter_interpreter(); - } - - return_VOID; + return_ACPI_STATUS(status); } /******************************************************************************* @@ -138,9 +105,17 @@ void acpi_ex_reacquire_interpreter(void) * * RETURN: None * - * DESCRIPTION: Exit the interpreter execution region. This is the top level - * routine used to exit the interpreter when all processing has - * been completed. + * DESCRIPTION: Exit the interpreter execution region + * + * Cases where the interpreter is unlocked: + * 1) Completion of the execution of a control method + * 2) Method blocked on a Sleep() AML opcode + * 3) Method blocked on an Acquire() AML opcode + * 4) Method blocked on a Wait() AML opcode + * 5) Method blocked to acquire the global lock + * 6) Method blocked to execute a serialized control method that is + * already executing + * 7) About to invoke a user-installed opregion handler * ******************************************************************************/ @@ -152,46 +127,7 @@ void acpi_ex_exit_interpreter(void) status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not release AML Interpreter mutex")); - } - - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ex_relinquish_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Exit the interpreter execution region, from within the - * interpreter - before attempting an operation that will possibly - * block the running thread. - * - * Cases where the interpreter is unlocked internally - * 1) Method to be blocked on a Sleep() AML opcode - * 2) Method to be blocked on an Acquire() AML opcode - * 3) Method to be blocked on a Wait() AML opcode - * 4) Method to be blocked to acquire the global lock - * 5) Method to be blocked waiting to execute a serialized control method - * that is currently executing - * 6) About to invoke a user-installed opregion handler - * - ******************************************************************************/ - -void acpi_ex_relinquish_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_relinquish_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_exit_interpreter(); + ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); } return_VOID; @@ -205,8 +141,8 @@ void acpi_ex_relinquish_interpreter(void) * * RETURN: none * - * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is - * 32-bit, as determined by the revision of the DSDT. + * DESCRIPTION: Truncate a number to 32-bits if the currently executing method + * belongs to a 32-bit ACPI table. * ******************************************************************************/ diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 7b6c9ff9bebe..8a0324b43e53 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -86,6 +86,129 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) return ret; } +/* Get PCI root bridge's handle from its segment and bus number */ +struct acpi_find_pci_root { + unsigned int seg; + unsigned int bus; + acpi_handle handle; +}; + +static acpi_status +do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) +{ + unsigned long *busnr = data; + struct acpi_resource_address64 address; + + if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && + resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) + return AE_OK; + + acpi_resource_to_address64(resource, &address); + if ((address.address_length > 0) && + (address.resource_type == ACPI_BUS_NUMBER_RANGE)) + *busnr = address.minimum; + + return AE_OK; +} + +static int get_root_bridge_busnr(acpi_handle handle) +{ + acpi_status status; + unsigned long bus, bbn; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + + status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, + &bbn); + if (status == AE_NOT_FOUND) { + /* Assume bus = 0 */ + printk(KERN_INFO PREFIX + "Assume root bridge [%s] bus is 0\n", + (char *)buffer.pointer); + status = AE_OK; + bbn = 0; + } + if (ACPI_FAILURE(status)) { + bbn = -ENODEV; + goto exit; + } + if (bbn > 0) + goto exit; + + /* _BBN in some systems return 0 for all root bridges */ + bus = -1; + status = acpi_walk_resources(handle, METHOD_NAME__CRS, + do_root_bridge_busnr_callback, &bus); + /* If _CRS failed, we just use _BBN */ + if (ACPI_FAILURE(status) || (bus == -1)) + goto exit; + /* We select _CRS */ + if (bbn != bus) { + printk(KERN_INFO PREFIX + "_BBN and _CRS returns different value for %s. Select _CRS\n", + (char *)buffer.pointer); + bbn = bus; + } + exit: + kfree(buffer.pointer); + return (int)bbn; +} + +static acpi_status +find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context; + unsigned long seg, bus; + acpi_status status; + int tmp; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + + status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg); + if (status == AE_NOT_FOUND) { + /* Assume seg = 0 */ + status = AE_OK; + seg = 0; + } + if (ACPI_FAILURE(status)) { + status = AE_CTRL_DEPTH; + goto exit; + } + + tmp = get_root_bridge_busnr(handle); + if (tmp < 0) { + printk(KERN_ERR PREFIX + "Find root bridge failed for %s\n", + (char *)buffer.pointer); + status = AE_CTRL_DEPTH; + goto exit; + } + bus = tmp; + + if (seg == find->seg && bus == find->bus) + { + find->handle = handle; + status = AE_CTRL_TERMINATE; + } + else + status = AE_OK; + exit: + kfree(buffer.pointer); + return status; +} + +acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) +{ + struct acpi_find_pci_root find = { seg, bus, NULL }; + + acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL); + return find.handle; +} +EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); + /* Get device's handler per its address under its parent */ struct acpi_find_child { acpi_handle handle; diff --git a/trunk/drivers/acpi/hardware/hwacpi.c b/trunk/drivers/acpi/hardware/hwacpi.c index 6031ca13dd2f..de50fab2a910 100644 --- a/trunk/drivers/acpi/hardware/hwacpi.c +++ b/trunk/drivers/acpi/hardware/hwacpi.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,41 @@ #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwacpi") +/****************************************************************************** + * + * FUNCTION: acpi_hw_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize and validate the various ACPI registers defined in + * the FADT. + * + ******************************************************************************/ +acpi_status acpi_hw_initialize(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(hw_initialize); + + /* We must have the ACPI tables by the time we get here */ + + if (!acpi_gbl_FADT) { + ACPI_ERROR((AE_INFO, "No FADT is present")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* Sanity check the FADT for valid values */ + + status = acpi_ut_validate_fadt(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + return_ACPI_STATUS(AE_OK); +} + /****************************************************************************** * * FUNCTION: acpi_hw_set_mode @@ -58,6 +93,7 @@ ACPI_MODULE_NAME("hwacpi") * DESCRIPTION: Transitions the system into the requested mode. * ******************************************************************************/ + acpi_status acpi_hw_set_mode(u32 mode) { @@ -70,7 +106,7 @@ acpi_status acpi_hw_set_mode(u32 mode) * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. */ - if (!acpi_gbl_FADT.smi_command) { + if (!acpi_gbl_FADT->smi_cmd) { ACPI_ERROR((AE_INFO, "No SMI_CMD in FADT, mode transition failed")); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); @@ -83,7 +119,7 @@ acpi_status acpi_hw_set_mode(u32 mode) * we make sure both the numbers are zero to determine these * transitions are not supported. */ - if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) { + if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { ACPI_ERROR((AE_INFO, "No ACPI mode transition supported in this system (enable/disable both zero)")); return_ACPI_STATUS(AE_OK); @@ -94,8 +130,9 @@ acpi_status acpi_hw_set_mode(u32 mode) /* BIOS should have disabled ALL fixed and GP events */ - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.acpi_enable, 8); + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->acpi_enable, + 8); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Attempting to enable ACPI mode\n")); break; @@ -106,8 +143,8 @@ acpi_status acpi_hw_set_mode(u32 mode) * BIOS should clear all fixed status bits and restore fixed event * enable bits to default */ - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.acpi_disable, + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->acpi_disable, 8); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Attempting to enable Legacy (non-ACPI) mode\n")); @@ -167,11 +204,12 @@ u32 acpi_hw_get_mode(void) * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. */ - if (!acpi_gbl_FADT.smi_command) { + if (!acpi_gbl_FADT->smi_cmd) { return_UINT32(ACPI_SYS_MODE_ACPI); } - status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value); + status = + acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE(status)) { return_UINT32(ACPI_SYS_MODE_LEGACY); } diff --git a/trunk/drivers/acpi/hardware/hwgpe.c b/trunk/drivers/acpi/hardware/hwgpe.c index 117a05cadaaa..608a3a60ee11 100644 --- a/trunk/drivers/acpi/hardware/hwgpe.c +++ b/trunk/drivers/acpi/hardware/hwgpe.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -105,20 +105,14 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info) acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) { acpi_status status; - u8 register_bit; ACPI_FUNCTION_ENTRY(); - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); - /* * Write a one to the appropriate bit in the status register to * clear this GPE. */ - status = acpi_hw_low_level_write(8, register_bit, + status = acpi_hw_low_level_write(8, gpe_event_info->register_bit, &gpe_event_info->register_info-> status_address); @@ -161,10 +155,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Get the register bitmask for this GPE */ - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + register_bit = gpe_event_info->register_bit; /* GPE currently enabled? (enabled for runtime?) */ diff --git a/trunk/drivers/acpi/hardware/hwregs.c b/trunk/drivers/acpi/hardware/hwregs.c index 1d371fa663f2..fa58c1edce1e 100644 --- a/trunk/drivers/acpi/hardware/hwregs.c +++ b/trunk/drivers/acpi/hardware/hwregs.c @@ -7,7 +7,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,15 +54,17 @@ ACPI_MODULE_NAME("hwregs") * * FUNCTION: acpi_hw_clear_acpi_status * - * PARAMETERS: None + * PARAMETERS: Flags - Lock the hardware or not * - * RETURN: None + * RETURN: none * * DESCRIPTION: Clears all fixed and general purpose status bits * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * + * NOTE: TBD: Flags parameter is obsolete, to be removed + * ******************************************************************************/ -acpi_status acpi_hw_clear_acpi_status(void) +acpi_status acpi_hw_clear_acpi_status(u32 flags) { acpi_status status; acpi_cpu_flags lock_flags = 0; @@ -71,7 +73,7 @@ acpi_status acpi_hw_clear_acpi_status(void) ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", ACPI_BITMASK_ALL_FIXED_STATUS, - (u16) acpi_gbl_FADT.xpm1a_event_block.address)); + (u16) acpi_gbl_FADT->xpm1a_evt_blk.address)); lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); @@ -84,10 +86,10 @@ acpi_status acpi_hw_clear_acpi_status(void) /* Clear the fixed events */ - if (acpi_gbl_FADT.xpm1b_event_block.address) { + if (acpi_gbl_FADT->xpm1b_evt_blk.address) { status = acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, - &acpi_gbl_FADT.xpm1b_event_block); + &acpi_gbl_FADT->xpm1b_evt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -251,15 +253,18 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) * * PARAMETERS: register_id - ID of ACPI bit_register to access * return_value - Value that was read from the register + * Flags - Lock the hardware or not * * RETURN: Status and the value read from specified Register. Value * returned is normalized to bit0 (is shifted all the way right) * * DESCRIPTION: ACPI bit_register read function. * + * NOTE: TBD: Flags parameter is obsolete, to be removed + * ******************************************************************************/ -acpi_status acpi_get_register(u32 register_id, u32 * return_value) +acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) { u32 register_value = 0; struct acpi_bit_register_info *bit_reg_info; @@ -307,13 +312,16 @@ ACPI_EXPORT_SYMBOL(acpi_get_register) * PARAMETERS: register_id - ID of ACPI bit_register to access * Value - (only used on write) value to write to the * Register, NOT pre-normalized to the bit pos + * Flags - Lock the hardware or not * * RETURN: Status * * DESCRIPTION: ACPI Bit Register write function. * + * NOTE: TBD: Flags parameter is obsolete, to be removed + * ******************************************************************************/ -acpi_status acpi_set_register(u32 register_id, u32 value) +acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) { u32 register_value = 0; struct acpi_bit_register_info *bit_reg_info; @@ -414,9 +422,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", register_value, - ACPI_FORMAT_UINT64(acpi_gbl_FADT. - xpm2_control_block. - address))); + ACPI_FORMAT_UINT64(acpi_gbl_FADT-> + xpm2_cnt_blk.address))); ACPI_REGISTER_INSERT_VALUE(register_value, bit_reg_info->bit_position, @@ -426,9 +433,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", register_value, - ACPI_FORMAT_UINT64(acpi_gbl_FADT. - xpm2_control_block. - address))); + ACPI_FORMAT_UINT64(acpi_gbl_FADT-> + xpm2_cnt_blk.address))); status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM2_CONTROL, @@ -489,7 +495,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(16, &value1, - &acpi_gbl_FADT.xpm1a_event_block); + &acpi_gbl_FADT->xpm1a_evt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -498,7 +504,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(16, &value2, - &acpi_gbl_FADT.xpm1b_event_block); + &acpi_gbl_FADT->xpm1b_evt_blk); value1 |= value2; break; @@ -521,14 +527,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(16, &value1, - &acpi_gbl_FADT.xpm1a_control_block); + &acpi_gbl_FADT->xpm1a_cnt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } status = acpi_hw_low_level_read(16, &value2, - &acpi_gbl_FADT.xpm1b_control_block); + &acpi_gbl_FADT->xpm1b_cnt_blk); value1 |= value2; break; @@ -536,20 +542,19 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(8, &value1, - &acpi_gbl_FADT.xpm2_control_block); + &acpi_gbl_FADT->xpm2_cnt_blk); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ status = acpi_hw_low_level_read(32, &value1, - &acpi_gbl_FADT.xpm_timer_block); + &acpi_gbl_FADT->xpm_tmr_blk); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ - status = - acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); + status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8); break; default: @@ -630,7 +635,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_event_block); + &acpi_gbl_FADT->xpm1a_evt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -639,7 +644,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_event_block); + &acpi_gbl_FADT->xpm1b_evt_blk); break; case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ @@ -677,50 +682,49 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_control_block); + &acpi_gbl_FADT->xpm1a_cnt_blk); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_control_block); + &acpi_gbl_FADT->xpm1b_cnt_blk); break; case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1a_control_block); + &acpi_gbl_FADT->xpm1a_cnt_blk); break; case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ status = acpi_hw_low_level_write(16, value, - &acpi_gbl_FADT.xpm1b_control_block); + &acpi_gbl_FADT->xpm1b_cnt_blk); break; case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ status = acpi_hw_low_level_write(8, value, - &acpi_gbl_FADT.xpm2_control_block); + &acpi_gbl_FADT->xpm2_cnt_blk); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ status = acpi_hw_low_level_write(32, value, - &acpi_gbl_FADT.xpm_timer_block); + &acpi_gbl_FADT->xpm_tmr_blk); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ /* SMI_CMD is currently always in IO space */ - status = - acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8); break; default: @@ -779,7 +783,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) * Two address spaces supported: Memory or IO. * PCI_Config is not supported here because the GAS struct is insufficient */ - switch (reg->space_id) { + switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: status = acpi_os_read_memory((acpi_physical_address) address, @@ -788,20 +792,22 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) case ACPI_ADR_SPACE_SYSTEM_IO: - status = - acpi_os_read_port((acpi_io_address) address, value, width); + status = acpi_os_read_port((acpi_io_address) address, + value, width); break; default: ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); + "Unsupported address space: %X", + reg->address_space_id)); return (AE_BAD_PARAMETER); } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", - *value, width, ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); + *value, width, + ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->address_space_id))); return (status); } @@ -848,7 +854,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) * Two address spaces supported: Memory or IO. * PCI_Config is not supported here because the GAS struct is insufficient */ - switch (reg->space_id) { + switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: status = acpi_os_write_memory((acpi_physical_address) address, @@ -857,20 +863,22 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) case ACPI_ADR_SPACE_SYSTEM_IO: - status = acpi_os_write_port((acpi_io_address) address, value, - width); + status = acpi_os_write_port((acpi_io_address) address, + value, width); break; default: ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); + "Unsupported address space: %X", + reg->address_space_id)); return (AE_BAD_PARAMETER); } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", - value, width, ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); + value, width, + ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->address_space_id))); return (status); } diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c index 57901ca3ade9..8bb43cae60c2 100644 --- a/trunk/drivers/acpi/hardware/hwsleep.c +++ b/trunk/drivers/acpi/hardware/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,7 +43,6 @@ */ #include -#include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwsleep") @@ -63,32 +62,17 @@ ACPI_MODULE_NAME("hwsleep") acpi_status acpi_set_firmware_waking_vector(acpi_physical_address physical_address) { - struct acpi_table_facs *facs; - acpi_status status; ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); - /* Get the FACS */ - - status = - acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - (struct acpi_table_header **)&facs); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Set the vector */ - if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { - /* - * ACPI 1.0 FACS or short table or optional X_ field is zero - */ - facs->firmware_waking_vector = (u32) physical_address; + if (acpi_gbl_common_fACS.vector_width == 32) { + *(ACPI_CAST_PTR + (u32, acpi_gbl_common_fACS.firmware_waking_vector)) + = (u32) physical_address; } else { - /* - * ACPI 2.0 FACS with valid X_ field - */ - facs->xfirmware_waking_vector = physical_address; + *acpi_gbl_common_fACS.firmware_waking_vector = physical_address; } return_ACPI_STATUS(AE_OK); @@ -113,8 +97,6 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) acpi_status acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) { - struct acpi_table_facs *facs; - acpi_status status; ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); @@ -122,29 +104,16 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the FACS */ - - status = - acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - (struct acpi_table_header **)&facs); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Get the vector */ - if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { - /* - * ACPI 1.0 FACS or short table or optional X_ field is zero - */ - *physical_address = - (acpi_physical_address) facs->firmware_waking_vector; + if (acpi_gbl_common_fACS.vector_width == 32) { + *physical_address = (acpi_physical_address) + * + (ACPI_CAST_PTR + (u32, acpi_gbl_common_fACS.firmware_waking_vector)); } else { - /* - * ACPI 2.0 FACS with valid X_ field - */ *physical_address = - (acpi_physical_address) facs->xfirmware_waking_vector; + *acpi_gbl_common_fACS.firmware_waking_vector; } return_ACPI_STATUS(AE_OK); @@ -277,14 +246,15 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) /* Clear wake status */ - status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); + status = + acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Clear all fixed and general purpose status bits */ - status = acpi_hw_clear_acpi_status(); + status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -397,7 +367,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) /* Wait until we enter sleep state */ do { - status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); + status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, + ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -430,12 +401,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); - status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); + status = + acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_hw_clear_acpi_status(); + status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -457,12 +429,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) ACPI_FLUSH_CPU_CACHE(); - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.S4bios_request, 8); + status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, + (u32) acpi_gbl_FADT->S4bios_req, 8); do { acpi_os_stall(1000); - status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); + status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, + ACPI_MTX_DO_NOT_LOCK); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -595,11 +568,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) (void) acpi_set_register(acpi_gbl_fixed_event_info - [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1); + [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1, + ACPI_MTX_DO_NOT_LOCK); (void) acpi_set_register(acpi_gbl_fixed_event_info - [ACPI_EVENT_POWER_BUTTON].status_register_id, 1); + [ACPI_EVENT_POWER_BUTTON].status_register_id, 1, + ACPI_MTX_DO_NOT_LOCK); arg.integer.value = ACPI_SST_WORKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); diff --git a/trunk/drivers/acpi/hardware/hwtimer.c b/trunk/drivers/acpi/hardware/hwtimer.c index c32eab696acd..c4ec47c939fd 100644 --- a/trunk/drivers/acpi/hardware/hwtimer.c +++ b/trunk/drivers/acpi/hardware/hwtimer.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution) return_ACPI_STATUS(AE_BAD_PARAMETER); } - if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { + if (acpi_gbl_FADT->tmr_val_ext == 0) { *resolution = 24; } else { *resolution = 32; @@ -98,8 +98,7 @@ acpi_status acpi_get_timer(u32 * ticks) return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = - acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block); + status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk); return_ACPI_STATUS(status); } @@ -154,7 +153,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) if (start_ticks < end_ticks) { delta_ticks = end_ticks - start_ticks; } else if (start_ticks > end_ticks) { - if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { + if (acpi_gbl_FADT->tmr_val_ext == 0) { /* 24-bit Timer */ diff --git a/trunk/drivers/acpi/motherboard.c b/trunk/drivers/acpi/motherboard.c index b61107b05262..2e17ec75af03 100644 --- a/trunk/drivers/acpi/motherboard.c +++ b/trunk/drivers/acpi/motherboard.c @@ -134,41 +134,41 @@ static void __init acpi_request_region (struct acpi_generic_address *addr, if (!addr->address || !length) return; - if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) + if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) request_region(addr->address, length, desc); - else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) request_mem_region(addr->address, length, desc); } static void __init acpi_reserve_resources(void) { - acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, - acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK"); + acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk, + acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK"); - acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, - acpi_gbl_FADT.pm1_event_length, "ACPI PM1b_EVT_BLK"); + acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk, + acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK"); - acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, - acpi_gbl_FADT.pm1_control_length, "ACPI PM1a_CNT_BLK"); + acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk, + acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK"); - acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, - acpi_gbl_FADT.pm1_control_length, "ACPI PM1b_CNT_BLK"); + acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk, + acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK"); - if (acpi_gbl_FADT.pm_timer_length == 4) - acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR"); + if (acpi_gbl_FADT->pm_tm_len == 4) + acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR"); - acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, - acpi_gbl_FADT.pm2_control_length, "ACPI PM2_CNT_BLK"); + acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk, + acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK"); /* Length of GPE blocks must be a non-negative multiple of 2 */ - if (!(acpi_gbl_FADT.gpe0_block_length & 0x1)) - acpi_request_region(&acpi_gbl_FADT.xgpe0_block, - acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK"); + if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1)) + acpi_request_region(&acpi_gbl_FADT->xgpe0_blk, + acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK"); - if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) - acpi_request_region(&acpi_gbl_FADT.xgpe1_block, - acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); + if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1)) + acpi_request_region(&acpi_gbl_FADT->xgpe1_blk, + acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK"); } static int __init acpi_motherboard_init(void) diff --git a/trunk/drivers/acpi/namespace/nsaccess.c b/trunk/drivers/acpi/namespace/nsaccess.c index 57faf598bad8..c1c6c236df9a 100644 --- a/trunk/drivers/acpi/namespace/nsaccess.c +++ b/trunk/drivers/acpi/namespace/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -195,27 +195,31 @@ acpi_status acpi_ns_root_initialize(void) obj_desc->mutex.sync_level = (u8) (ACPI_TO_INTEGER(val) - 1); - /* Create a mutex */ + if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { - status = - acpi_os_create_mutex(&obj_desc->mutex. - os_mutex); - if (ACPI_FAILURE(status)) { - acpi_ut_remove_reference(obj_desc); - goto unlock_and_exit; - } + /* Create a counting semaphore for the global lock */ - /* Special case for ACPI Global Lock */ + status = + acpi_os_create_semaphore + (ACPI_NO_UNIT_LIMIT, 1, + &acpi_gbl_global_lock_semaphore); + if (ACPI_FAILURE(status)) { + acpi_ut_remove_reference + (obj_desc); + goto unlock_and_exit; + } - if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { - acpi_gbl_global_lock_mutex = - obj_desc->mutex.os_mutex; + /* Mark this mutex as very special */ - /* Create additional counting semaphore for global lock */ + obj_desc->mutex.os_mutex = + ACPI_GLOBAL_LOCK; + } else { + /* Create a mutex */ status = - acpi_os_create_semaphore(1, 0, - &acpi_gbl_global_lock_semaphore); + acpi_os_create_mutex(&obj_desc-> + mutex. + os_mutex); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference (obj_desc); diff --git a/trunk/drivers/acpi/namespace/nsalloc.c b/trunk/drivers/acpi/namespace/nsalloc.c index 1d693d8ad2d8..55b407aae266 100644 --- a/trunk/drivers/acpi/namespace/nsalloc.c +++ b/trunk/drivers/acpi/namespace/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,9 +61,6 @@ ACPI_MODULE_NAME("nsalloc") struct acpi_namespace_node *acpi_ns_create_node(u32 name) { struct acpi_namespace_node *node; -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - u32 temp; -#endif ACPI_FUNCTION_TRACE(ns_create_node); @@ -74,15 +71,6 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - temp = - acpi_gbl_ns_node_list->total_allocated - - acpi_gbl_ns_node_list->total_freed; - if (temp > acpi_gbl_ns_node_list->max_occupied) { - acpi_gbl_ns_node_list->max_occupied = temp; - } -#endif - node->name.integer = name; ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); return_PTR(node); diff --git a/trunk/drivers/acpi/namespace/nsdump.c b/trunk/drivers/acpi/namespace/nsdump.c index 1fc4f86676e1..d72df66aa965 100644 --- a/trunk/drivers/acpi/namespace/nsdump.c +++ b/trunk/drivers/acpi/namespace/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -205,7 +205,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { this_node->name.integer = - acpi_ut_repair_name(this_node->name.ascii); + acpi_ut_repair_name(this_node->name.integer); ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", this_node->name.integer)); @@ -226,12 +226,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, obj_desc = acpi_ns_get_attached_object(this_node); acpi_dbg_level = dbg_level; - /* Temp nodes are those nodes created by a control method */ - - if (this_node->flags & ANOBJ_TEMPORARY) { - acpi_os_printf("(T) "); - } - switch (info->display_type & ACPI_DISPLAY_MASK) { case ACPI_DISPLAY_SUMMARY: @@ -629,8 +623,7 @@ acpi_ns_dump_objects(acpi_object_type type, info.display_type = display_type; (void)acpi_ns_walk_namespace(type, start_handle, max_depth, - ACPI_NS_WALK_NO_UNLOCK | - ACPI_NS_WALK_TEMP_NODES, + ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object, (void *)&info, NULL); } diff --git a/trunk/drivers/acpi/namespace/nsdumpdv.c b/trunk/drivers/acpi/namespace/nsdumpdv.c index 5097e167939e..c6bf5d30fca3 100644 --- a/trunk/drivers/acpi/namespace/nsdumpdv.c +++ b/trunk/drivers/acpi/namespace/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/namespace/nseval.c b/trunk/drivers/acpi/namespace/nseval.c index aa6370c67ec1..4b0a4a8c9843 100644 --- a/trunk/drivers/acpi/namespace/nseval.c +++ b/trunk/drivers/acpi/namespace/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -154,7 +154,11 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) * Execute the method via the interpreter. The interpreter is locked * here before calling into the AML parser */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + status = acpi_ps_execute_method(info); acpi_ex_exit_interpreter(); } else { @@ -178,7 +182,10 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) * resolution, we must lock it because we could access an opregion. * The opregion access code assumes that the interpreter is locked. */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } /* Function has a strange interface */ diff --git a/trunk/drivers/acpi/namespace/nsinit.c b/trunk/drivers/acpi/namespace/nsinit.c index 326af8fc0ce7..aec8488c0019 100644 --- a/trunk/drivers/acpi/namespace/nsinit.c +++ b/trunk/drivers/acpi/namespace/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -213,7 +213,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle, u32 level, void *context, void **return_value) { acpi_object_type type; - acpi_status status = AE_OK; + acpi_status status; struct acpi_init_walk_info *info = (struct acpi_init_walk_info *)context; struct acpi_namespace_node *node = @@ -267,7 +267,10 @@ acpi_ns_init_one_object(acpi_handle obj_handle, /* * Must lock the interpreter before executing AML code */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return (status); + } /* * Each of these types can contain executable AML code within the diff --git a/trunk/drivers/acpi/namespace/nsload.c b/trunk/drivers/acpi/namespace/nsload.c index d4f9654fd20f..fe75d888e183 100644 --- a/trunk/drivers/acpi/namespace/nsload.c +++ b/trunk/drivers/acpi/namespace/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,12 +44,13 @@ #include #include #include -#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsload") /* Local prototypes */ +static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type); + #ifdef ACPI_FUTURE_IMPLEMENTATION acpi_status acpi_ns_unload_namespace(acpi_handle handle); @@ -61,7 +62,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); * * FUNCTION: acpi_ns_load_table * - * PARAMETERS: table_index - Index for table to be loaded + * PARAMETERS: table_desc - Descriptor for table to be loaded * Node - Owning NS node * * RETURN: Status @@ -71,13 +72,42 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); ******************************************************************************/ acpi_status -acpi_ns_load_table(acpi_native_uint table_index, +acpi_ns_load_table(struct acpi_table_desc *table_desc, struct acpi_namespace_node *node) { acpi_status status; ACPI_FUNCTION_TRACE(ns_load_table); + /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ + + if (! + (acpi_gbl_table_data[table_desc->type]. + flags & ACPI_TABLE_EXECUTABLE)) { + + /* Just ignore this table */ + + return_ACPI_STATUS(AE_OK); + } + + /* Check validity of the AML start and length */ + + if (!table_desc->aml_start) { + ACPI_ERROR((AE_INFO, "Null AML pointer")); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n", + table_desc->aml_start)); + + /* Ignore table if there is no AML contained within */ + + if (!table_desc->aml_length) { + ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]", + table_desc->pointer->signature)); + return_ACPI_STATUS(AE_OK); + } + /* * Parse the table and load the namespace with all named * objects found within. Control methods are NOT parsed @@ -87,34 +117,15 @@ acpi_ns_load_table(acpi_native_uint table_index, * to another control method, we can't continue parsing * because we don't know how many arguments to parse next! */ - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* If table already loaded into namespace, just return */ - - if (acpi_tb_is_table_loaded(table_index)) { - status = AE_ALREADY_EXISTS; - goto unlock; - } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); - status = acpi_tb_allocate_owner_id(table_index); + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - goto unlock; - } - - status = acpi_ns_parse_table(table_index, node->child); - if (ACPI_SUCCESS(status)) { - acpi_tb_set_table_loaded_flag(table_index, TRUE); - } else { - acpi_tb_release_owner_id(table_index); + return_ACPI_STATUS(status); } - unlock: + status = acpi_ns_parse_table(table_desc, node->child); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -130,7 +141,7 @@ acpi_ns_load_table(acpi_native_uint table_index, ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Method Parsing and Object Initialization ****\n")); - status = acpi_ds_initialize_objects(table_index, node); + status = acpi_ds_initialize_objects(table_desc, node); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Method Parsing and Object Initialization ****\n")); @@ -138,7 +149,99 @@ acpi_ns_load_table(acpi_native_uint table_index, return_ACPI_STATUS(status); } -#ifdef ACPI_OBSOLETE_FUNCTIONS +/******************************************************************************* + * + * FUNCTION: acpi_ns_load_table_by_type + * + * PARAMETERS: table_type - Id of the table type to load + * + * RETURN: Status + * + * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables + * of the given type are loaded. The mechanism allows this + * routine to be called repeatedly. + * + ******************************************************************************/ + +static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) +{ + u32 i; + acpi_status status; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE(ns_load_table_by_type); + + status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* + * Table types supported are: + * DSDT (one), SSDT/PSDT (multiple) + */ + switch (table_type) { + case ACPI_TABLE_ID_DSDT: + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n")); + + table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next; + + /* If table already loaded into namespace, just return */ + + if (table_desc->loaded_into_namespace) { + goto unlock_and_exit; + } + + /* Now load the single DSDT */ + + status = acpi_ns_load_table(table_desc, acpi_gbl_root_node); + if (ACPI_SUCCESS(status)) { + table_desc->loaded_into_namespace = TRUE; + } + break; + + case ACPI_TABLE_ID_SSDT: + case ACPI_TABLE_ID_PSDT: + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Namespace load: %d SSDT or PSDTs\n", + acpi_gbl_table_lists[table_type].count)); + + /* + * Traverse list of SSDT or PSDT tables + */ + table_desc = acpi_gbl_table_lists[table_type].next; + for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) { + /* + * Only attempt to load table into namespace if it is not + * already loaded! + */ + if (!table_desc->loaded_into_namespace) { + status = + acpi_ns_load_table(table_desc, + acpi_gbl_root_node); + if (ACPI_FAILURE(status)) { + break; + } + + table_desc->loaded_into_namespace = TRUE; + } + + table_desc = table_desc->next; + } + break; + + default: + status = AE_SUPPORT; + break; + } + + unlock_and_exit: + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + return_ACPI_STATUS(status); +} + /******************************************************************************* * * FUNCTION: acpi_load_namespace @@ -185,7 +288,6 @@ acpi_status acpi_ns_load_namespace(void) return_ACPI_STATUS(status); } -#endif #ifdef ACPI_FUTURE_IMPLEMENTATION /******************************************************************************* diff --git a/trunk/drivers/acpi/namespace/nsnames.c b/trunk/drivers/acpi/namespace/nsnames.c index cbd94af08cc5..97b8332c9746 100644 --- a/trunk/drivers/acpi/namespace/nsnames.c +++ b/trunk/drivers/acpi/namespace/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/namespace/nsobject.c b/trunk/drivers/acpi/namespace/nsobject.c index d9d7377bc6e6..aabe8794b908 100644 --- a/trunk/drivers/acpi/namespace/nsobject.c +++ b/trunk/drivers/acpi/namespace/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/namespace/nsparse.c b/trunk/drivers/acpi/namespace/nsparse.c index e696aa847990..155505a4ef69 100644 --- a/trunk/drivers/acpi/namespace/nsparse.c +++ b/trunk/drivers/acpi/namespace/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,7 +45,6 @@ #include #include #include -#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsparse") @@ -63,24 +62,14 @@ ACPI_MODULE_NAME("nsparse") * ******************************************************************************/ acpi_status -acpi_ns_one_complete_parse(acpi_native_uint pass_number, - acpi_native_uint table_index) +acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) { union acpi_parse_object *parse_root; acpi_status status; - acpi_native_uint aml_length; - u8 *aml_start; struct acpi_walk_state *walk_state; - struct acpi_table_header *table; - acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(ns_one_complete_parse); - status = acpi_tb_get_owner_id(table_index, &owner_id); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Create and init a Root Node */ parse_root = acpi_ps_create_scope_op(); @@ -90,41 +79,26 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state(table_desc->owner_id, + NULL, NULL, NULL); if (!walk_state) { acpi_ps_free_op(parse_root); return_ACPI_STATUS(AE_NO_MEMORY); } - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); - acpi_ps_free_op(parse_root); - return_ACPI_STATUS(status); - } - - /* Table must consist of at least a complete header */ - - if (table->length < sizeof(struct acpi_table_header)) { - status = AE_BAD_HEADER; - } else { - aml_start = (u8 *) table + sizeof(struct acpi_table_header); - aml_length = table->length - sizeof(struct acpi_table_header); - status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, - aml_start, aml_length, NULL, - (u8) pass_number); - } - + status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, + table_desc->aml_start, + table_desc->aml_length, NULL, + pass_number); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); - acpi_ps_delete_parse_tree(parse_root); return_ACPI_STATUS(status); } /* Parse the AML */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", - (unsigned)pass_number)); + pass_number)); status = acpi_ps_parse_aml(walk_state); acpi_ps_delete_parse_tree(parse_root); @@ -145,7 +119,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, ******************************************************************************/ acpi_status -acpi_ns_parse_table(acpi_native_uint table_index, +acpi_ns_parse_table(struct acpi_table_desc *table_desc, struct acpi_namespace_node *start_node) { acpi_status status; @@ -160,10 +134,10 @@ acpi_ns_parse_table(acpi_native_uint table_index, * each Parser Op subtree is deleted when it is finished. This saves * a great deal of memory, and allows a small cache of parse objects * to service the entire parse. The second pass of the parse then - * performs another complete parse of the AML. + * performs another complete parse of the AML.. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); - status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index); + status = acpi_ns_one_complete_parse(1, table_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -178,7 +152,7 @@ acpi_ns_parse_table(acpi_native_uint table_index, * parse objects are all cached. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); - status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index); + status = acpi_ns_one_complete_parse(2, table_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/namespace/nssearch.c b/trunk/drivers/acpi/namespace/nssearch.c index e863be665ce8..500e2bbcfaf7 100644 --- a/trunk/drivers/acpi/namespace/nssearch.c +++ b/trunk/drivers/acpi/namespace/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -321,8 +321,7 @@ acpi_ns_search_and_enter(u32 target_name, * even though there are a few bad names. */ if (!acpi_ut_valid_acpi_name(target_name)) { - target_name = - acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name)); + target_name = acpi_ut_repair_name(target_name); /* Report warning only if in strict mode or debug mode */ @@ -402,10 +401,6 @@ acpi_ns_search_and_enter(u32 target_name, } #endif - if (flags & ACPI_NS_TEMPORARY) { - new_node->flags |= ANOBJ_TEMPORARY; - } - /* Install the new object into the parent's list of children */ acpi_ns_install_node(walk_state, node, new_node, type); diff --git a/trunk/drivers/acpi/namespace/nsutils.c b/trunk/drivers/acpi/namespace/nsutils.c index 90fd059615ff..aa4e799d9a8c 100644 --- a/trunk/drivers/acpi/namespace/nsutils.c +++ b/trunk/drivers/acpi/namespace/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -770,6 +770,13 @@ void acpi_ns_terminate(void) } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); + + /* + * 2) Now we can delete the ACPI tables + */ + acpi_tb_delete_all_tables(); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); + return_VOID; } diff --git a/trunk/drivers/acpi/namespace/nswalk.c b/trunk/drivers/acpi/namespace/nswalk.c index 94eb8f332d94..c8f6bef16ed0 100644 --- a/trunk/drivers/acpi/namespace/nswalk.c +++ b/trunk/drivers/acpi/namespace/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -126,7 +126,7 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, * PARAMETERS: Type - acpi_object_type to search for * start_node - Handle in namespace where search begins * max_depth - Depth to which search is to reach - * Flags - Whether to unlock the NS before invoking + * unlock_before_callback- Whether to unlock the NS before invoking * the callback routine * user_function - Called when an object of "Type" is found * Context - Passed to user function @@ -153,7 +153,7 @@ acpi_status acpi_ns_walk_namespace(acpi_object_type type, acpi_handle start_node, u32 max_depth, - u32 flags, + u8 unlock_before_callback, acpi_walk_callback user_function, void *context, void **return_value) { @@ -193,34 +193,20 @@ acpi_ns_walk_namespace(acpi_object_type type, acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, child_node); if (child_node) { - - /* Found next child, get the type if we are not searching for ANY */ - - if (type != ACPI_TYPE_ANY) { - child_type = child_node->type; - } - /* - * Ignore all temporary namespace nodes (created during control - * method execution) unless told otherwise. These temporary nodes - * can cause a race condition because they can be deleted during the - * execution of the user function (if the namespace is unlocked before - * invocation of the user function.) Only the debugger namespace dump - * will examine the temporary nodes. + * Found node, Get the type if we are not + * searching for ANY */ - if ((child_node->flags & ANOBJ_TEMPORARY) && - !(flags & ACPI_NS_WALK_TEMP_NODES)) { - status = AE_CTRL_DEPTH; + if (type != ACPI_TYPE_ANY) { + child_type = child_node->type; } - /* Type must match requested type */ - - else if (child_type == type) { + if (child_type == type) { /* - * Found a matching node, invoke the user callback function. - * Unlock the namespace if flag is set. + * Found a matching node, invoke the user + * callback function */ - if (flags & ACPI_NS_WALK_UNLOCK) { + if (unlock_before_callback) { mutex_status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); @@ -230,11 +216,10 @@ acpi_ns_walk_namespace(acpi_object_type type, } } - status = - user_function(child_node, level, context, - return_value); + status = user_function(child_node, level, + context, return_value); - if (flags & ACPI_NS_WALK_UNLOCK) { + if (unlock_before_callback) { mutex_status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); @@ -266,17 +251,20 @@ acpi_ns_walk_namespace(acpi_object_type type, } /* - * Depth first search: Attempt to go down another level in the - * namespace if we are allowed to. Don't go any further if we have - * reached the caller specified maximum depth or if the user - * function has specified that the maximum depth has been reached. + * Depth first search: + * Attempt to go down another level in the namespace + * if we are allowed to. Don't go any further if we + * have reached the caller specified maximum depth + * or if the user function has specified that the + * maximum depth has been reached. */ if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) { - - /* There is at least one child of this node, visit it */ - + /* + * There is at least one child of this + * node, visit the onde + */ level++; parent_node = child_node; child_node = NULL; @@ -284,8 +272,9 @@ acpi_ns_walk_namespace(acpi_object_type type, } } else { /* - * No more children of this node (acpi_ns_get_next_node failed), go - * back upwards in the namespace tree to the node's parent. + * No more children of this node (acpi_ns_get_next_node + * failed), go back upwards in the namespace tree to + * the node's parent. */ level--; child_node = parent_node; diff --git a/trunk/drivers/acpi/namespace/nsxfeval.c b/trunk/drivers/acpi/namespace/nsxfeval.c index 7ac6ace50059..dca6799ac678 100644 --- a/trunk/drivers/acpi/namespace/nsxfeval.c +++ b/trunk/drivers/acpi/namespace/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -170,6 +170,7 @@ acpi_evaluate_object(acpi_handle handle, struct acpi_buffer *return_buffer) { acpi_status status; + acpi_status status2; struct acpi_evaluate_info *info; acpi_size buffer_space_needed; u32 i; @@ -328,12 +329,14 @@ acpi_evaluate_object(acpi_handle handle, * Delete the internal return object. NOTE: Interpreter must be * locked to avoid race condition. */ - acpi_ex_enter_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_SUCCESS(status2)) { - /* Remove one reference on the return object (should delete it) */ + /* Remove one reference on the return object (should delete it) */ - acpi_ut_remove_reference(info->return_object); - acpi_ex_exit_interpreter(); + acpi_ut_remove_reference(info->return_object); + acpi_ex_exit_interpreter(); + } } cleanup: diff --git a/trunk/drivers/acpi/namespace/nsxfname.c b/trunk/drivers/acpi/namespace/nsxfname.c index b489781b22a8..978213a6c19f 100644 --- a/trunk/drivers/acpi/namespace/nsxfname.c +++ b/trunk/drivers/acpi/namespace/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -84,41 +84,38 @@ acpi_get_handle(acpi_handle parent, /* Convert a parent handle to a prefix node */ if (parent) { + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + prefix_node = acpi_ns_map_handle_to_node(parent); if (!prefix_node) { + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - } - - /* - * Valid cases are: - * 1) Fully qualified pathname - * 2) Parent + Relative pathname - * - * Error for - */ - if (acpi_ns_valid_root_prefix(pathname[0])) { - /* Pathname is fully qualified (starts with '\') */ - - /* Special case for root-only, since we can't search for it */ - - if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) { - *ret_handle = - acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); - return (AE_OK); + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); } - } else if (!prefix_node) { + } - /* Relative path with null prefix is disallowed */ + /* Special case for root, since we can't search for it */ - return (AE_BAD_PARAMETER); + if (ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH) == 0) { + *ret_handle = + acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); + return (AE_OK); } - /* Find the Node and convert to a handle */ + /* + * Find the Node and convert to a handle + */ + status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, + &node); - status = - acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node); + *ret_handle = NULL; if (ACPI_SUCCESS(status)) { *ret_handle = acpi_ns_convert_entry_to_handle(node); } diff --git a/trunk/drivers/acpi/namespace/nsxfobj.c b/trunk/drivers/acpi/namespace/nsxfobj.c index faa375887201..a18b1c223129 100644 --- a/trunk/drivers/acpi/namespace/nsxfobj.c +++ b/trunk/drivers/acpi/namespace/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 4a9faff4c01d..bd96a7045925 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -45,7 +45,7 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS] int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; -extern int __init acpi_table_parse_madt_family(char *id, +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, @@ -89,7 +89,7 @@ void __cpuinit acpi_unmap_pxm_to_node(int node) node_clear(node, nodes_found_map); } -void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) +void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) { ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); @@ -99,35 +99,36 @@ void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) switch (header->type) { - case ACPI_SRAT_TYPE_CPU_AFFINITY: + case ACPI_SRAT_PROCESSOR_AFFINITY: #ifdef ACPI_DEBUG_OUTPUT { - struct acpi_srat_cpu_affinity *p = - (struct acpi_srat_cpu_affinity *)header; + struct acpi_table_processor_affinity *p = + (struct acpi_table_processor_affinity *)header; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", - p->apic_id, p->local_sapic_eid, - p->proximity_domain_lo, - (p->flags & ACPI_SRAT_CPU_ENABLED)? - "enabled" : "disabled")); + p->apic_id, p->lsapic_eid, + p->proximity_domain, + p->flags. + enabled ? "enabled" : "disabled")); } #endif /* ACPI_DEBUG_OUTPUT */ break; - case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + case ACPI_SRAT_MEMORY_AFFINITY: #ifdef ACPI_DEBUG_OUTPUT { - struct acpi_srat_mem_affinity *p = - (struct acpi_srat_mem_affinity *)header; + struct acpi_table_memory_affinity *p = + (struct acpi_table_memory_affinity *)header; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n", - (unsigned long)p->base_address, - (unsigned long)p->length, + "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n", + p->base_addr_hi, p->base_addr_lo, + p->length_hi, p->length_lo, p->memory_type, p->proximity_domain, - (p->flags & ACPI_SRAT_MEM_ENABLED)? - "enabled" : "disabled", - (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)? - " hot-pluggable" : "")); + p->flags. + enabled ? "enabled" : "disabled", + p->flags. + hot_pluggable ? " hot-pluggable" : + "")); } #endif /* ACPI_DEBUG_OUTPUT */ break; @@ -140,18 +141,18 @@ void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) } } -static int __init acpi_parse_slit(struct acpi_table_header *table) +static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size) { struct acpi_table_slit *slit; u32 localities; - if (!table) + if (!phys_addr || !size) return -EINVAL; - slit = (struct acpi_table_slit *)table; + slit = (struct acpi_table_slit *)__va(phys_addr); /* downcast just for %llu vs %lu for i386/ia64 */ - localities = (u32) slit->locality_count; + localities = (u32) slit->localities; acpi_numa_slit_init(slit); @@ -159,12 +160,12 @@ static int __init acpi_parse_slit(struct acpi_table_header *table) } static int __init -acpi_parse_processor_affinity(struct acpi_subtable_header * header, +acpi_parse_processor_affinity(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_srat_cpu_affinity *processor_affinity; + struct acpi_table_processor_affinity *processor_affinity; - processor_affinity = (struct acpi_srat_cpu_affinity *)header; + processor_affinity = (struct acpi_table_processor_affinity *)header; if (!processor_affinity) return -EINVAL; @@ -177,12 +178,12 @@ acpi_parse_processor_affinity(struct acpi_subtable_header * header, } static int __init -acpi_parse_memory_affinity(struct acpi_subtable_header * header, +acpi_parse_memory_affinity(acpi_table_entry_header * header, const unsigned long end) { - struct acpi_srat_mem_affinity *memory_affinity; + struct acpi_table_memory_affinity *memory_affinity; - memory_affinity = (struct acpi_srat_mem_affinity *)header; + memory_affinity = (struct acpi_table_memory_affinity *)header; if (!memory_affinity) return -EINVAL; @@ -194,23 +195,23 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, return 0; } -static int __init acpi_parse_srat(struct acpi_table_header *table) +static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size) { struct acpi_table_srat *srat; - if (!table) + if (!phys_addr || !size) return -EINVAL; - srat = (struct acpi_table_srat *)table; + srat = (struct acpi_table_srat *)__va(phys_addr); return 0; } int __init -acpi_table_parse_srat(enum acpi_srat_type id, +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_SIG_SRAT, + return acpi_table_parse_madt_family(ACPI_SRAT, sizeof(struct acpi_table_srat), id, handler, max_entries); } @@ -220,17 +221,17 @@ int __init acpi_numa_init(void) int result; /* SRAT: Static Resource Affinity Table */ - result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat); + result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat); if (result > 0) { - result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, + result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, acpi_parse_processor_affinity, NR_CPUS); - result = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific + result = 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_SIG_SLIT, acpi_parse_slit); + result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit); acpi_numa_arch_fixup(); return 0; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index a28f5b8972b4..57ae1e5cde0a 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -137,43 +136,53 @@ void acpi_os_vprintf(const char *fmt, va_list args) #endif } -acpi_physical_address __init acpi_os_get_root_pointer(void) +acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) { if (efi_enabled) { + addr->pointer_type = ACPI_PHYSICAL_POINTER; if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) - return efi.acpi20; + addr->pointer.physical = efi.acpi20; else if (efi.acpi != EFI_INVALID_TABLE_ADDR) - return efi.acpi; + addr->pointer.physical = efi.acpi; else { printk(KERN_ERR PREFIX "System description tables not found\n"); - return 0; + return AE_NOT_FOUND; } - } else - return acpi_find_rsdp(); + } else { + if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) { + printk(KERN_ERR PREFIX + "System description tables not found\n"); + return AE_NOT_FOUND; + } + } + + return AE_OK; } -void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) +acpi_status +acpi_os_map_memory(acpi_physical_address phys, acpi_size size, + void __iomem ** virt) { if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); - return 0; + return AE_BAD_PARAMETER; } - if (acpi_gbl_permanent_mmap) - /* - * ioremap checks to ensure this is in reserved space - */ - return ioremap((unsigned long)phys, size); - else - return __acpi_map_table((unsigned long)phys, size); + /* + * ioremap checks to ensure this is in reserved space + */ + *virt = ioremap((unsigned long)phys, size); + + if (!*virt) + return AE_NO_MEMORY; + + return AE_OK; } EXPORT_SYMBOL_GPL(acpi_os_map_memory); void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) { - if (acpi_gbl_permanent_mmap) { - iounmap(virt); - } + iounmap(virt); } EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); @@ -245,7 +254,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, * FADT. It may not be the same if an interrupt source override exists * for the SCI. */ - gsi = acpi_gbl_FADT.sci_interrupt; + gsi = acpi_fadt.sci_int; if (acpi_gsi_to_irq(gsi, &irq) < 0) { printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", gsi); diff --git a/trunk/drivers/acpi/parser/psargs.c b/trunk/drivers/acpi/parser/psargs.c index c2b9835c890b..bf88e076c3e9 100644 --- a/trunk/drivers/acpi/parser/psargs.c +++ b/trunk/drivers/acpi/parser/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psloop.c b/trunk/drivers/acpi/parser/psloop.c index 773aee82fbb8..e1541db3753a 100644 --- a/trunk/drivers/acpi/parser/psloop.c +++ b/trunk/drivers/acpi/parser/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,11 +42,12 @@ */ /* - * Parse the AML and build an operation tree as most interpreters, (such as - * Perl) do. Parsing is done by hand rather than with a YACC generated parser - * to tightly constrain stack and dynamic memory usage. Parsing is kept - * flexible and the code fairly compact by parsing based on a list of AML - * opcode templates in aml_op_info[]. + * Parse the AML and build an operation tree as most interpreters, + * like Perl, do. Parsing is done by hand rather than with a YACC + * generated parser to tightly constrain stack and dynamic memory + * usage. At the same time, parsing is kept flexible and the code + * fairly compact by parsing based on a list of AML opcode + * templates in aml_op_info[] */ #include @@ -59,761 +60,6 @@ ACPI_MODULE_NAME("psloop") static u32 acpi_gbl_depth = 0; -/* Local prototypes */ - -static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state); - -static acpi_status -acpi_ps_build_named_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, - union acpi_parse_object *unnamed_op, - union acpi_parse_object **op); - -static acpi_status -acpi_ps_create_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object **new_op); - -static acpi_status -acpi_ps_get_arguments(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object *op); - -static acpi_status -acpi_ps_complete_op(struct acpi_walk_state *walk_state, - union acpi_parse_object **op, acpi_status status); - -static acpi_status -acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, - union acpi_parse_object *op, acpi_status status); - -/******************************************************************************* - * - * FUNCTION: acpi_ps_get_aml_opcode - * - * PARAMETERS: walk_state - Current state - * - * RETURN: Status - * - * DESCRIPTION: Extract the next AML opcode from the input stream. - * - ******************************************************************************/ - -static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) -{ - - ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state); - - walk_state->aml_offset = - (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml, - walk_state->parser_state.aml_start); - walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state)); - - /* - * First cut to determine what we have found: - * 1) A valid AML opcode - * 2) A name string - * 3) An unknown/invalid opcode - */ - walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode); - - switch (walk_state->op_info->class) { - case AML_CLASS_ASCII: - case AML_CLASS_PREFIX: - /* - * Starts with a valid prefix or ASCII char, this is a name - * string. Convert the bare name string to a namepath. - */ - walk_state->opcode = AML_INT_NAMEPATH_OP; - walk_state->arg_types = ARGP_NAMESTRING; - break; - - case AML_CLASS_UNKNOWN: - - /* The opcode is unrecognized. Just skip unknown opcodes */ - - ACPI_ERROR((AE_INFO, - "Found unknown opcode %X at AML address %p offset %X, ignoring", - walk_state->opcode, walk_state->parser_state.aml, - walk_state->aml_offset)); - - ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128); - - /* Assume one-byte bad opcode */ - - walk_state->parser_state.aml++; - return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); - - default: - - /* Found opcode info, this is a normal opcode */ - - walk_state->parser_state.aml += - acpi_ps_get_opcode_size(walk_state->opcode); - walk_state->arg_types = walk_state->op_info->parse_args; - break; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_build_named_op - * - * PARAMETERS: walk_state - Current state - * aml_op_start - Begin of named Op in AML - * unnamed_op - Early Op (not a named Op) - * Op - Returned Op - * - * RETURN: Status - * - * DESCRIPTION: Parse a named Op - * - ******************************************************************************/ - -static acpi_status -acpi_ps_build_named_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, - union acpi_parse_object *unnamed_op, - union acpi_parse_object **op) -{ - acpi_status status = AE_OK; - union acpi_parse_object *arg = NULL; - - ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); - - unnamed_op->common.value.arg = NULL; - unnamed_op->common.aml_opcode = walk_state->opcode; - - /* - * Get and append arguments until we find the node that contains - * the name (the type ARGP_NAME). - */ - while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) && - (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) { - status = - acpi_ps_get_next_arg(walk_state, - &(walk_state->parser_state), - GET_CURRENT_ARG_TYPE(walk_state-> - arg_types), &arg); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - acpi_ps_append_arg(unnamed_op, arg); - INCREMENT_ARG_LIST(walk_state->arg_types); - } - - /* - * Make sure that we found a NAME and didn't run out of arguments - */ - if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) { - return_ACPI_STATUS(AE_AML_NO_OPERAND); - } - - /* We know that this arg is a name, move to next arg */ - - INCREMENT_ARG_LIST(walk_state->arg_types); - - /* - * Find the object. This will either insert the object into - * the namespace or simply look it up - */ - walk_state->op = NULL; - - status = walk_state->descending_callback(walk_state, op); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog")); - return_ACPI_STATUS(status); - } - - if (!*op) { - return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); - } - - status = acpi_ps_next_parse_state(walk_state, *op, status); - if (ACPI_FAILURE(status)) { - if (status == AE_CTRL_PENDING) { - return_ACPI_STATUS(AE_CTRL_PARSE_PENDING); - } - return_ACPI_STATUS(status); - } - - acpi_ps_append_arg(*op, unnamed_op->common.value.arg); - acpi_gbl_depth++; - - if ((*op)->common.aml_opcode == AML_REGION_OP) { - /* - * Defer final parsing of an operation_region body, because we don't - * have enough info in the first pass to parse it correctly (i.e., - * there may be method calls within the term_arg elements of the body.) - * - * However, we must continue parsing because the opregion is not a - * standalone package -- we don't know where the end is at this point. - * - * (Length is unknown until parse of the body complete) - */ - (*op)->named.data = aml_op_start; - (*op)->named.length = 0; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_create_op - * - * PARAMETERS: walk_state - Current state - * aml_op_start - Op start in AML - * new_op - Returned Op - * - * RETURN: Status - * - * DESCRIPTION: Get Op from AML - * - ******************************************************************************/ - -static acpi_status -acpi_ps_create_op(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object **new_op) -{ - acpi_status status = AE_OK; - union acpi_parse_object *op; - union acpi_parse_object *named_op = NULL; - - ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); - - status = acpi_ps_get_aml_opcode(walk_state); - if (status == AE_CTRL_PARSE_CONTINUE) { - return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); - } - - /* Create Op structure and append to parent's argument list */ - - walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode); - op = acpi_ps_alloc_op(walk_state->opcode); - if (!op) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - if (walk_state->op_info->flags & AML_NAMED) { - status = - acpi_ps_build_named_op(walk_state, aml_op_start, op, - &named_op); - acpi_ps_free_op(op); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - *new_op = named_op; - return_ACPI_STATUS(AE_OK); - } - - /* Not a named opcode, just allocate Op and append to parent */ - - if (walk_state->op_info->flags & AML_CREATE) { - /* - * Backup to beginning of create_xXXfield declaration - * body_length is unknown until we parse the body - */ - op->named.data = aml_op_start; - op->named.length = 0; - } - - acpi_ps_append_arg(acpi_ps_get_parent_scope - (&(walk_state->parser_state)), op); - - if (walk_state->descending_callback != NULL) { - /* - * Find the object. This will either insert the object into - * the namespace or simply look it up - */ - walk_state->op = *new_op = op; - - status = walk_state->descending_callback(walk_state, &op); - status = acpi_ps_next_parse_state(walk_state, op, status); - if (status == AE_CTRL_PENDING) { - status = AE_CTRL_PARSE_PENDING; - } - } - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_get_arguments - * - * PARAMETERS: walk_state - Current state - * aml_op_start - Op start in AML - * Op - Current Op - * - * RETURN: Status - * - * DESCRIPTION: Get arguments for passed Op. - * - ******************************************************************************/ - -static acpi_status -acpi_ps_get_arguments(struct acpi_walk_state *walk_state, - u8 * aml_op_start, union acpi_parse_object *op) -{ - acpi_status status = AE_OK; - union acpi_parse_object *arg = NULL; - - ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); - - switch (op->common.aml_opcode) { - case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ - case AML_WORD_OP: /* AML_WORDDATA_ARG */ - case AML_DWORD_OP: /* AML_DWORDATA_ARG */ - case AML_QWORD_OP: /* AML_QWORDATA_ARG */ - case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ - - /* Fill in constant or string argument directly */ - - acpi_ps_get_next_simple_arg(&(walk_state->parser_state), - GET_CURRENT_ARG_TYPE(walk_state-> - arg_types), - op); - break; - - case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ - - status = - acpi_ps_get_next_namepath(walk_state, - &(walk_state->parser_state), op, - 1); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - walk_state->arg_types = 0; - break; - - default: - /* - * Op is not a constant or string, append each argument to the Op - */ - while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) - && !walk_state->arg_count) { - walk_state->aml_offset = - (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml, - walk_state->parser_state. - aml_start); - - status = - acpi_ps_get_next_arg(walk_state, - &(walk_state->parser_state), - GET_CURRENT_ARG_TYPE - (walk_state->arg_types), &arg); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (arg) { - arg->common.aml_offset = walk_state->aml_offset; - acpi_ps_append_arg(op, arg); - } - - INCREMENT_ARG_LIST(walk_state->arg_types); - } - - /* Special processing for certain opcodes */ - - /* TBD (remove): Temporary mechanism to disable this code if needed */ - -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - - if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && - ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { - /* - * We want to skip If/Else/While constructs during Pass1 because we - * want to actually conditionally execute the code during Pass2. - * - * Except for disassembly, where we always want to walk the - * If/Else/While packages - */ - switch (op->common.aml_opcode) { - case AML_IF_OP: - case AML_ELSE_OP: - case AML_WHILE_OP: - - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Pass1: Skipping an If/Else/While body\n")); - - /* Skip body of if/else/while in pass 1 */ - - walk_state->parser_state.aml = - walk_state->parser_state.pkg_end; - walk_state->arg_count = 0; - break; - - default: - break; - } - } -#endif - - switch (op->common.aml_opcode) { - case AML_METHOD_OP: - /* - * Skip parsing of control method because we don't have enough - * info in the first pass to parse it correctly. - * - * Save the length and address of the body - */ - op->named.data = walk_state->parser_state.aml; - op->named.length = (u32) - (walk_state->parser_state.pkg_end - - walk_state->parser_state.aml); - - /* Skip body of method */ - - walk_state->parser_state.aml = - walk_state->parser_state.pkg_end; - walk_state->arg_count = 0; - break; - - case AML_BUFFER_OP: - case AML_PACKAGE_OP: - case AML_VAR_PACKAGE_OP: - - if ((op->common.parent) && - (op->common.parent->common.aml_opcode == - AML_NAME_OP) - && (walk_state->pass_number <= - ACPI_IMODE_LOAD_PASS2)) { - /* - * Skip parsing of Buffers and Packages because we don't have - * enough info in the first pass to parse them correctly. - */ - op->named.data = aml_op_start; - op->named.length = (u32) - (walk_state->parser_state.pkg_end - - aml_op_start); - - /* Skip body */ - - walk_state->parser_state.aml = - walk_state->parser_state.pkg_end; - walk_state->arg_count = 0; - } - break; - - case AML_WHILE_OP: - - if (walk_state->control_state) { - walk_state->control_state->control.package_end = - walk_state->parser_state.pkg_end; - } - break; - - default: - - /* No action for all other opcodes */ - break; - } - - break; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_complete_op - * - * PARAMETERS: walk_state - Current state - * Op - Returned Op - * Status - Parse status before complete Op - * - * RETURN: Status - * - * DESCRIPTION: Complete Op - * - ******************************************************************************/ - -static acpi_status -acpi_ps_complete_op(struct acpi_walk_state *walk_state, - union acpi_parse_object **op, acpi_status status) -{ - acpi_status status2; - - ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state); - - /* - * Finished one argument of the containing scope - */ - walk_state->parser_state.scope->parse_scope.arg_count--; - - /* Close this Op (will result in parse subtree deletion) */ - - status2 = acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - - *op = NULL; - - switch (status) { - case AE_OK: - break; - - case AE_CTRL_TRANSFER: - - /* We are about to transfer to a called method */ - - walk_state->prev_op = NULL; - walk_state->prev_arg_types = walk_state->arg_types; - return_ACPI_STATUS(status); - - case AE_CTRL_END: - - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - if (*op) { - walk_state->op = *op; - walk_state->op_info = - acpi_ps_get_opcode_info((*op)->common.aml_opcode); - walk_state->opcode = (*op)->common.aml_opcode; - - status = walk_state->ascending_callback(walk_state); - status = - acpi_ps_next_parse_state(walk_state, *op, status); - - status2 = acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - - status = AE_OK; - break; - - case AE_CTRL_BREAK: - case AE_CTRL_CONTINUE: - - /* Pop off scopes until we find the While */ - - while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) { - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - if ((*op)->common.aml_opcode != AML_WHILE_OP) { - status2 = acpi_ds_result_stack_pop(walk_state); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - } - - /* Close this iteration of the While loop */ - - walk_state->op = *op; - walk_state->op_info = - acpi_ps_get_opcode_info((*op)->common.aml_opcode); - walk_state->opcode = (*op)->common.aml_opcode; - - status = walk_state->ascending_callback(walk_state); - status = acpi_ps_next_parse_state(walk_state, *op, status); - - status2 = acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - - status = AE_OK; - break; - - case AE_CTRL_TERMINATE: - - /* Clean up */ - do { - if (*op) { - status2 = - acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - status2 = acpi_ds_result_stack_pop(walk_state); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - - acpi_ut_delete_generic_state - (acpi_ut_pop_generic_state - (&walk_state->control_state)); - } - - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - } while (*op); - - return_ACPI_STATUS(AE_OK); - - default: /* All other non-AE_OK status */ - - do { - if (*op) { - status2 = - acpi_ps_complete_this_op(walk_state, *op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - - } while (*op); - -#if 0 - /* - * TBD: Cleanup parse ops on error - */ - if (*op == NULL) { - acpi_ps_pop_scope(parser_state, op, - &walk_state->arg_types, - &walk_state->arg_count); - } -#endif - walk_state->prev_op = NULL; - walk_state->prev_arg_types = walk_state->arg_types; - return_ACPI_STATUS(status); - } - - /* This scope complete? */ - - if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) { - acpi_ps_pop_scope(&(walk_state->parser_state), op, - &walk_state->arg_types, - &walk_state->arg_count); - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op)); - } else { - *op = NULL; - } - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_complete_final_op - * - * PARAMETERS: walk_state - Current state - * Op - Current Op - * Status - Current parse status before complete last - * Op - * - * RETURN: Status - * - * DESCRIPTION: Complete last Op. - * - ******************************************************************************/ - -static acpi_status -acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, - union acpi_parse_object *op, acpi_status status) -{ - acpi_status status2; - - ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state); - - /* - * Complete the last Op (if not completed), and clear the scope stack. - * It is easily possible to end an AML "package" with an unbounded number - * of open scopes (such as when several ASL blocks are closed with - * sequential closing braces). We want to terminate each one cleanly. - */ - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", - op)); - do { - if (op) { - if (walk_state->ascending_callback != NULL) { - walk_state->op = op; - walk_state->op_info = - acpi_ps_get_opcode_info(op->common. - aml_opcode); - walk_state->opcode = op->common.aml_opcode; - - status = - walk_state->ascending_callback(walk_state); - status = - acpi_ps_next_parse_state(walk_state, op, - status); - if (status == AE_CTRL_PENDING) { - status = - acpi_ps_complete_op(walk_state, &op, - AE_OK); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } - - if (status == AE_CTRL_TERMINATE) { - status = AE_OK; - - /* Clean up */ - do { - if (op) { - status2 = - acpi_ps_complete_this_op - (walk_state, op); - if (ACPI_FAILURE - (status2)) { - return_ACPI_STATUS - (status2); - } - } - - acpi_ps_pop_scope(& - (walk_state-> - parser_state), - &op, - &walk_state-> - arg_types, - &walk_state-> - arg_count); - - } while (op); - - return_ACPI_STATUS(status); - } - - else if (ACPI_FAILURE(status)) { - - /* First error is most important */ - - (void) - acpi_ps_complete_this_op(walk_state, - op); - return_ACPI_STATUS(status); - } - } - - status2 = acpi_ps_complete_this_op(walk_state, op); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - } - - acpi_ps_pop_scope(&(walk_state->parser_state), &op, - &walk_state->arg_types, - &walk_state->arg_count); - - } while (op); - - return_ACPI_STATUS(status); -} - /******************************************************************************* * * FUNCTION: acpi_ps_parse_loop @@ -830,7 +76,10 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) { acpi_status status = AE_OK; + acpi_status status2; union acpi_parse_object *op = NULL; /* current op */ + union acpi_parse_object *arg = NULL; + union acpi_parse_object *pre_op = NULL; struct acpi_parse_state *parser_state; u8 *aml_op_start = NULL; @@ -879,7 +128,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) "Invoked method did not return a value")); } - ACPI_EXCEPTION((AE_INFO, status, "GetPredicate Failed")); return_ACPI_STATUS(status); @@ -905,30 +153,222 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) } #endif - /* Iterative parsing loop, while there is more AML to process: */ + /* Iterative parsing loop, while there is more AML to process: */ + + while ((parser_state->aml < parser_state->aml_end) || (op)) { + aml_op_start = parser_state->aml; + if (!op) { + + /* Get the next opcode from the AML stream */ + + walk_state->aml_offset = + (u32) ACPI_PTR_DIFF(parser_state->aml, + parser_state->aml_start); + walk_state->opcode = acpi_ps_peek_opcode(parser_state); + + /* + * First cut to determine what we have found: + * 1) A valid AML opcode + * 2) A name string + * 3) An unknown/invalid opcode + */ + walk_state->op_info = + acpi_ps_get_opcode_info(walk_state->opcode); + switch (walk_state->op_info->class) { + case AML_CLASS_ASCII: + case AML_CLASS_PREFIX: + /* + * Starts with a valid prefix or ASCII char, this is a name + * string. Convert the bare name string to a namepath. + */ + walk_state->opcode = AML_INT_NAMEPATH_OP; + walk_state->arg_types = ARGP_NAMESTRING; + break; + + case AML_CLASS_UNKNOWN: + + /* The opcode is unrecognized. Just skip unknown opcodes */ + + ACPI_ERROR((AE_INFO, + "Found unknown opcode %X at AML address %p offset %X, ignoring", + walk_state->opcode, + parser_state->aml, + walk_state->aml_offset)); + + ACPI_DUMP_BUFFER(parser_state->aml, 128); + + /* Assume one-byte bad opcode */ + + parser_state->aml++; + continue; + + default: + + /* Found opcode info, this is a normal opcode */ + + parser_state->aml += + acpi_ps_get_opcode_size(walk_state->opcode); + walk_state->arg_types = + walk_state->op_info->parse_args; + break; + } + + /* Create Op structure and append to parent's argument list */ + + if (walk_state->op_info->flags & AML_NAMED) { + + /* Allocate a new pre_op if necessary */ + + if (!pre_op) { + pre_op = + acpi_ps_alloc_op(walk_state-> + opcode); + if (!pre_op) { + status = AE_NO_MEMORY; + goto close_this_op; + } + } + + pre_op->common.value.arg = NULL; + pre_op->common.aml_opcode = walk_state->opcode; + + /* + * Get and append arguments until we find the node that contains + * the name (the type ARGP_NAME). + */ + while (GET_CURRENT_ARG_TYPE + (walk_state->arg_types) + && + (GET_CURRENT_ARG_TYPE + (walk_state->arg_types) != ARGP_NAME)) { + status = + acpi_ps_get_next_arg(walk_state, + parser_state, + GET_CURRENT_ARG_TYPE + (walk_state-> + arg_types), + &arg); + if (ACPI_FAILURE(status)) { + goto close_this_op; + } + + acpi_ps_append_arg(pre_op, arg); + INCREMENT_ARG_LIST(walk_state-> + arg_types); + } + + /* + * Make sure that we found a NAME and didn't run out of + * arguments + */ + if (!GET_CURRENT_ARG_TYPE + (walk_state->arg_types)) { + status = AE_AML_NO_OPERAND; + goto close_this_op; + } + + /* We know that this arg is a name, move to next arg */ + + INCREMENT_ARG_LIST(walk_state->arg_types); - while ((parser_state->aml < parser_state->aml_end) || (op)) { - aml_op_start = parser_state->aml; - if (!op) { - status = - acpi_ps_create_op(walk_state, aml_op_start, &op); - if (ACPI_FAILURE(status)) { - if (status == AE_CTRL_PARSE_CONTINUE) { + /* + * Find the object. This will either insert the object into + * the namespace or simply look it up + */ + walk_state->op = NULL; + + status = + walk_state->descending_callback(walk_state, + &op); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "During name lookup/catalog")); + goto close_this_op; + } + + if (!op) { continue; } - if (status == AE_CTRL_PARSE_PENDING) { + status = + acpi_ps_next_parse_state(walk_state, op, + status); + if (status == AE_CTRL_PENDING) { status = AE_OK; + goto close_this_op; } - status = - acpi_ps_complete_op(walk_state, &op, - status); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto close_this_op; } - continue; + acpi_ps_append_arg(op, + pre_op->common.value.arg); + acpi_gbl_depth++; + + if (op->common.aml_opcode == AML_REGION_OP) { + /* + * Defer final parsing of an operation_region body, + * because we don't have enough info in the first pass + * to parse it correctly (i.e., there may be method + * calls within the term_arg elements of the body.) + * + * However, we must continue parsing because + * the opregion is not a standalone package -- + * we don't know where the end is at this point. + * + * (Length is unknown until parse of the body complete) + */ + op->named.data = aml_op_start; + op->named.length = 0; + } + } else { + /* Not a named opcode, just allocate Op and append to parent */ + + walk_state->op_info = + acpi_ps_get_opcode_info(walk_state->opcode); + op = acpi_ps_alloc_op(walk_state->opcode); + if (!op) { + status = AE_NO_MEMORY; + goto close_this_op; + } + + if (walk_state->op_info->flags & AML_CREATE) { + /* + * Backup to beginning of create_xXXfield declaration + * body_length is unknown until we parse the body + */ + op->named.data = aml_op_start; + op->named.length = 0; + } + + acpi_ps_append_arg(acpi_ps_get_parent_scope + (parser_state), op); + + if ((walk_state->descending_callback != NULL)) { + /* + * Find the object. This will either insert the object into + * the namespace or simply look it up + */ + walk_state->op = op; + + status = + walk_state-> + descending_callback(walk_state, + &op); + status = + acpi_ps_next_parse_state(walk_state, + op, + status); + if (status == AE_CTRL_PENDING) { + status = AE_OK; + goto close_this_op; + } + + if (ACPI_FAILURE(status)) { + goto close_this_op; + } + } } op->common.aml_offset = walk_state->aml_offset; @@ -955,17 +395,172 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) /* Get arguments */ - status = - acpi_ps_get_arguments(walk_state, aml_op_start, op); - if (ACPI_FAILURE(status)) { + switch (op->common.aml_opcode) { + case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ + case AML_WORD_OP: /* AML_WORDDATA_ARG */ + case AML_DWORD_OP: /* AML_DWORDATA_ARG */ + case AML_QWORD_OP: /* AML_QWORDATA_ARG */ + case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ + + /* Fill in constant or string argument directly */ + + acpi_ps_get_next_simple_arg(parser_state, + GET_CURRENT_ARG_TYPE + (walk_state-> + arg_types), op); + break; + + case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ + status = - acpi_ps_complete_op(walk_state, &op, - status); + acpi_ps_get_next_namepath(walk_state, + parser_state, op, + 1); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto close_this_op; } - continue; + walk_state->arg_types = 0; + break; + + default: + /* + * Op is not a constant or string, append each argument + * to the Op + */ + while (GET_CURRENT_ARG_TYPE + (walk_state->arg_types) + && !walk_state->arg_count) { + walk_state->aml_offset = (u32) + ACPI_PTR_DIFF(parser_state->aml, + parser_state-> + aml_start); + + status = + acpi_ps_get_next_arg(walk_state, + parser_state, + GET_CURRENT_ARG_TYPE + (walk_state-> + arg_types), + &arg); + if (ACPI_FAILURE(status)) { + goto close_this_op; + } + + if (arg) { + arg->common.aml_offset = + walk_state->aml_offset; + acpi_ps_append_arg(op, arg); + } + INCREMENT_ARG_LIST(walk_state-> + arg_types); + } + + /* Special processing for certain opcodes */ + + /* TBD (remove): Temporary mechanism to disable this code if needed */ + +#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE + + if ((walk_state->pass_number <= + ACPI_IMODE_LOAD_PASS1) + && + ((walk_state-> + parse_flags & ACPI_PARSE_DISASSEMBLE) == + 0)) { + /* + * We want to skip If/Else/While constructs during Pass1 + * because we want to actually conditionally execute the + * code during Pass2. + * + * Except for disassembly, where we always want to + * walk the If/Else/While packages + */ + switch (op->common.aml_opcode) { + case AML_IF_OP: + case AML_ELSE_OP: + case AML_WHILE_OP: + + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Pass1: Skipping an If/Else/While body\n")); + + /* Skip body of if/else/while in pass 1 */ + + parser_state->aml = + parser_state->pkg_end; + walk_state->arg_count = 0; + break; + + default: + break; + } + } +#endif + switch (op->common.aml_opcode) { + case AML_METHOD_OP: + + /* + * Skip parsing of control method + * because we don't have enough info in the first pass + * to parse it correctly. + * + * Save the length and address of the body + */ + op->named.data = parser_state->aml; + op->named.length = + (u32) (parser_state->pkg_end - + parser_state->aml); + + /* Skip body of method */ + + parser_state->aml = + parser_state->pkg_end; + walk_state->arg_count = 0; + break; + + case AML_BUFFER_OP: + case AML_PACKAGE_OP: + case AML_VAR_PACKAGE_OP: + + if ((op->common.parent) && + (op->common.parent->common. + aml_opcode == AML_NAME_OP) + && (walk_state->pass_number <= + ACPI_IMODE_LOAD_PASS2)) { + /* + * Skip parsing of Buffers and Packages + * because we don't have enough info in the first pass + * to parse them correctly. + */ + op->named.data = aml_op_start; + op->named.length = + (u32) (parser_state-> + pkg_end - + aml_op_start); + + /* Skip body */ + + parser_state->aml = + parser_state->pkg_end; + walk_state->arg_count = 0; + } + break; + + case AML_WHILE_OP: + + if (walk_state->control_state) { + walk_state->control_state-> + control.package_end = + parser_state->pkg_end; + } + break; + + default: + + /* No action for all other opcodes */ + break; + } + break; } } @@ -980,16 +575,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) walk_state->arg_types, walk_state->arg_count); if (ACPI_FAILURE(status)) { - status = - acpi_ps_complete_op(walk_state, &op, - status); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - continue; + goto close_this_op; } - op = NULL; continue; } @@ -1041,16 +628,269 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) acpi_ps_next_parse_state(walk_state, op, status); if (status == AE_CTRL_PENDING) { status = AE_OK; + goto close_this_op; } } - status = acpi_ps_complete_op(walk_state, &op, status); - if (ACPI_FAILURE(status)) { + close_this_op: + /* + * Finished one argument of the containing scope + */ + parser_state->scope->parse_scope.arg_count--; + + /* Finished with pre_op */ + + if (pre_op) { + acpi_ps_free_op(pre_op); + pre_op = NULL; + } + + /* Close this Op (will result in parse subtree deletion) */ + + status2 = acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + op = NULL; + + switch (status) { + case AE_OK: + break; + + case AE_CTRL_TRANSFER: + + /* We are about to transfer to a called method. */ + + walk_state->prev_op = op; + walk_state->prev_arg_types = walk_state->arg_types; + return_ACPI_STATUS(status); + + case AE_CTRL_END: + + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + if (op) { + walk_state->op = op; + walk_state->op_info = + acpi_ps_get_opcode_info(op->common. + aml_opcode); + walk_state->opcode = op->common.aml_opcode; + + status = + walk_state->ascending_callback(walk_state); + status = + acpi_ps_next_parse_state(walk_state, op, + status); + + status2 = + acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + op = NULL; + } + status = AE_OK; + break; + + case AE_CTRL_BREAK: + case AE_CTRL_CONTINUE: + + /* Pop off scopes until we find the While */ + + while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + if (op->common.aml_opcode != AML_WHILE_OP) { + status2 = + acpi_ds_result_stack_pop + (walk_state); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + } + } + + /* Close this iteration of the While loop */ + + walk_state->op = op; + walk_state->op_info = + acpi_ps_get_opcode_info(op->common.aml_opcode); + walk_state->opcode = op->common.aml_opcode; + + status = walk_state->ascending_callback(walk_state); + status = + acpi_ps_next_parse_state(walk_state, op, status); + + status2 = acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + op = NULL; + + status = AE_OK; + break; + + case AE_CTRL_TERMINATE: + + status = AE_OK; + + /* Clean up */ + do { + if (op) { + status2 = + acpi_ps_complete_this_op(walk_state, + op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + + status2 = + acpi_ds_result_stack_pop + (walk_state); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + + acpi_ut_delete_generic_state + (acpi_ut_pop_generic_state + (&walk_state->control_state)); + } + + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + } while (op); + + return_ACPI_STATUS(status); + + default: /* All other non-AE_OK status */ + + do { + if (op) { + status2 = + acpi_ps_complete_this_op(walk_state, + op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + } + + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + + } while (op); + + /* + * TBD: Cleanup parse ops on error + */ +#if 0 + if (op == NULL) { + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + } +#endif + walk_state->prev_op = op; + walk_state->prev_arg_types = walk_state->arg_types; return_ACPI_STATUS(status); } + /* This scope complete? */ + + if (acpi_ps_has_completed_scope(parser_state)) { + acpi_ps_pop_scope(parser_state, &op, + &walk_state->arg_types, + &walk_state->arg_count); + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Popped scope, Op=%p\n", op)); + } else { + op = NULL; + } + } /* while parser_state->Aml */ - status = acpi_ps_complete_final_op(walk_state, op, status); + /* + * Complete the last Op (if not completed), and clear the scope stack. + * It is easily possible to end an AML "package" with an unbounded number + * of open scopes (such as when several ASL blocks are closed with + * sequential closing braces). We want to terminate each one cleanly. + */ + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", + op)); + do { + if (op) { + if (walk_state->ascending_callback != NULL) { + walk_state->op = op; + walk_state->op_info = + acpi_ps_get_opcode_info(op->common. + aml_opcode); + walk_state->opcode = op->common.aml_opcode; + + status = + walk_state->ascending_callback(walk_state); + status = + acpi_ps_next_parse_state(walk_state, op, + status); + if (status == AE_CTRL_PENDING) { + status = AE_OK; + goto close_this_op; + } + + if (status == AE_CTRL_TERMINATE) { + status = AE_OK; + + /* Clean up */ + do { + if (op) { + status2 = + acpi_ps_complete_this_op + (walk_state, op); + if (ACPI_FAILURE + (status2)) { + return_ACPI_STATUS + (status2); + } + } + + acpi_ps_pop_scope(parser_state, + &op, + &walk_state-> + arg_types, + &walk_state-> + arg_count); + + } while (op); + + return_ACPI_STATUS(status); + } + + else if (ACPI_FAILURE(status)) { + + /* First error is most important */ + + (void) + acpi_ps_complete_this_op(walk_state, + op); + return_ACPI_STATUS(status); + } + } + + status2 = acpi_ps_complete_this_op(walk_state, op); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + } + + acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, + &walk_state->arg_count); + + } while (op); + return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/parser/psopcode.c b/trunk/drivers/acpi/parser/psopcode.c index 16d8b6cc3c22..4bd25e32769f 100644 --- a/trunk/drivers/acpi/parser/psopcode.c +++ b/trunk/drivers/acpi/parser/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psparse.c b/trunk/drivers/acpi/parser/psparse.c index 5d63f48e56b5..a02aa62fe1e5 100644 --- a/trunk/drivers/acpi/parser/psparse.c +++ b/trunk/drivers/acpi/parser/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -540,11 +540,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) if ((status == AE_ALREADY_EXISTS) && (!walk_state->method_desc->method.mutex)) { - ACPI_INFO((AE_INFO, - "Marking method %4.4s as Serialized", - walk_state->method_node->name. - ascii)); - /* * Method tried to create an object twice. The probable cause is * that the method cannot handle reentrancy. diff --git a/trunk/drivers/acpi/parser/psscope.c b/trunk/drivers/acpi/parser/psscope.c index 77cfa4ed0cfe..a3e0314de24d 100644 --- a/trunk/drivers/acpi/parser/psscope.c +++ b/trunk/drivers/acpi/parser/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/pstree.c b/trunk/drivers/acpi/parser/pstree.c index 966e7ea2a0c4..0015717ef096 100644 --- a/trunk/drivers/acpi/parser/pstree.c +++ b/trunk/drivers/acpi/parser/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psutils.c b/trunk/drivers/acpi/parser/psutils.c index 8ca52002db55..d405387b7414 100644 --- a/trunk/drivers/acpi/parser/psutils.c +++ b/trunk/drivers/acpi/parser/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/pswalk.c b/trunk/drivers/acpi/parser/pswalk.c index 49f9757434e4..a84a547a0f1b 100644 --- a/trunk/drivers/acpi/parser/pswalk.c +++ b/trunk/drivers/acpi/parser/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/parser/psxface.c b/trunk/drivers/acpi/parser/psxface.c index 94103bced75e..5d996c1140af 100644 --- a/trunk/drivers/acpi/parser/psxface.c +++ b/trunk/drivers/acpi/parser/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,6 +54,8 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info); static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); +static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info); + static void acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); @@ -213,8 +215,6 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) { acpi_status status; - union acpi_parse_object *op; - struct acpi_walk_state *walk_state; ACPI_FUNCTION_TRACE(ps_execute_method); @@ -234,7 +234,8 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) } /* - * The caller "owns" the parameters, so give each one an extra reference + * The caller "owns" the parameters, so give each one an extra + * reference */ acpi_ps_update_parameter_list(info, REF_INCREMENT); @@ -243,50 +244,30 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) acpi_ps_start_trace(info); /* - * Execute the method. Performs parse simultaneously + * 1) Perform the first pass parse of the method to enter any + * named objects that it creates into the namespace */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n", - info->resolved_node->name.ascii, info->resolved_node, - info->obj_desc)); - - /* Create and init a Root Node */ - - op = acpi_ps_create_scope_op(); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* Create and initialize a new walk state */ - - info->pass_number = ACPI_IMODE_EXECUTE; - walk_state = - acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, - NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup; - } + "**** Begin Method Parse **** Entry=%p obj=%p\n", + info->resolved_node, info->obj_desc)); - status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, - info->obj_desc->method.aml_start, - info->obj_desc->method.aml_length, info, - info->pass_number); + info->pass_number = 1; + status = acpi_ps_execute_pass(info); if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); goto cleanup; } - /* Parse the AML */ - - status = acpi_ps_parse_aml(walk_state); + /* + * 2) Execute the method. Performs second pass parse simultaneously + */ + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "**** Begin Method Execution **** Entry=%p obj=%p\n", + info->resolved_node, info->obj_desc)); - /* walk_state was deleted by parse_aml */ + info->pass_number = 3; + status = acpi_ps_execute_pass(info); cleanup: - acpi_ps_delete_parse_tree(op); - /* End optional tracing */ acpi_ps_stop_trace(info); @@ -349,3 +330,62 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) } } } + +/******************************************************************************* + * + * FUNCTION: acpi_ps_execute_pass + * + * PARAMETERS: Info - See struct acpi_evaluate_info + * (Used: pass_number, Node, and obj_desc) + * + * RETURN: Status + * + * DESCRIPTION: Single AML pass: Parse or Execute a control method + * + ******************************************************************************/ + +static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info) +{ + acpi_status status; + union acpi_parse_object *op; + struct acpi_walk_state *walk_state; + + ACPI_FUNCTION_TRACE(ps_execute_pass); + + /* Create and init a Root Node */ + + op = acpi_ps_create_scope_op(); + if (!op) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Create and initialize a new walk state */ + + walk_state = + acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, + NULL, NULL); + if (!walk_state) { + status = AE_NO_MEMORY; + goto cleanup; + } + + status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, + info->obj_desc->method.aml_start, + info->obj_desc->method.aml_length, + info->pass_number == 1 ? NULL : info, + info->pass_number); + if (ACPI_FAILURE(status)) { + acpi_ds_delete_walk_state(walk_state); + goto cleanup; + } + + /* Parse the AML */ + + status = acpi_ps_parse_aml(walk_state); + + /* Walk state was deleted by parse_aml */ + + cleanup: + acpi_ps_delete_parse_tree(op); + return_ACPI_STATUS(status); +} diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index 0f683c8c6fbc..481e633bbf41 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -513,7 +513,7 @@ int __init acpi_irq_penalty_init(void) } } /* Add a penalty for the SCI */ - acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; + acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING; return 0; } @@ -785,7 +785,7 @@ static int irqrouter_resume(struct sys_device *dev) /* Make sure SCI is enabled again (Apple firmware bug?) */ - acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); + acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1, ACPI_MTX_DO_NOT_LOCK); list_for_each(node, &acpi_link.entries) { link = list_entry(node, struct acpi_pci_link, node); diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 1f06229040ac..a860efa2c562 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -117,19 +117,6 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) EXPORT_SYMBOL(acpi_pci_unregister_driver); -acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) -{ - struct acpi_pci_root *tmp; - - list_for_each_entry(tmp, &acpi_pci_roots, node) { - if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) - return tmp->device->handle; - } - return NULL; -} - -EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); - static acpi_status get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index eacf9a252019..5f9496d59ed6 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -375,126 +375,30 @@ static int acpi_processor_remove_fs(struct acpi_device *device) } /* Use the acpiid in MADT to map cpus in case of SMP */ - #ifndef CONFIG_SMP -static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} +#define convert_acpiid_to_cpu(acpi_id) (-1) #else -static struct acpi_table_madt *madt; - -static int map_lapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_apic *lapic = - (struct acpi_madt_local_apic *)entry; - if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && - lapic->processor_id == acpi_id) { - *apic_id = lapic->id; - return 1; - } - return 0; -} - -static int map_lsapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_sapic *lsapic = - (struct acpi_madt_local_sapic *)entry; - /* Only check enabled APICs*/ - if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { - /* First check against id */ - if (lsapic->processor_id == acpi_id) { - *apic_id = lsapic->id; - return 1; - /* Check against optional uid */ - } else if (entry->length >= 16 && - lsapic->uid == acpi_id) { - *apic_id = lsapic->uid; - return 1; - } - } - return 0; -} - #ifdef CONFIG_IA64 +#define arch_acpiid_to_apicid ia64_acpiid_to_sapicid #define arch_cpu_to_apicid ia64_cpu_to_sapicid +#define ARCH_BAD_APICID (0xffff) #else +#define arch_acpiid_to_apicid x86_acpiid_to_apicid #define arch_cpu_to_apicid x86_cpu_to_apicid +#define ARCH_BAD_APICID (0xff) #endif -static int map_madt_entry(u32 acpi_id) -{ - unsigned long madt_end, entry; - int apic_id = -1; - - if (!madt) - return apic_id; - - entry = (unsigned long)madt; - madt_end = entry + madt->header.length; - - /* Parse all entries looking for a match. */ - - entry += sizeof(struct acpi_table_madt); - while (entry + sizeof(struct acpi_subtable_header) < madt_end) { - struct acpi_subtable_header *header = - (struct acpi_subtable_header *)entry; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - if (map_lapic_id(header, acpi_id, &apic_id)) - break; - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - if (map_lsapic_id(header, acpi_id, &apic_id)) - break; - } - entry += header->length; - } - return apic_id; -} - -static int map_mat_entry(acpi_handle handle, u32 acpi_id) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_subtable_header *header; - int apic_id = -1; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - goto exit; - - if (!buffer.length || !buffer.pointer) - goto exit; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(struct acpi_subtable_header)) { - goto exit; - } - - header = (struct acpi_subtable_header *)obj->buffer.pointer; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - map_lapic_id(header, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - map_lsapic_id(header, acpi_id, &apic_id); - } - -exit: - if (buffer.pointer) - kfree(buffer.pointer); - return apic_id; -} - -static int get_cpu_id(acpi_handle handle, u32 acpi_id) +static int convert_acpiid_to_cpu(u8 acpi_id) { + u16 apic_id; int i; - int apic_id = -1; - apic_id = map_mat_entry(handle, acpi_id); - if (apic_id == -1) - apic_id = map_madt_entry(acpi_id); - if (apic_id == -1) - return apic_id; + apic_id = arch_acpiid_to_apicid[acpi_id]; + if (apic_id == ARCH_BAD_APICID) + return -1; - for (i = 0; i < NR_CPUS; ++i) { + for (i = 0; i < NR_CPUS; i++) { if (arch_cpu_to_apicid[i] == apic_id) return i; } @@ -506,7 +410,7 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id) Driver Interface -------------------------------------------------------------------------- */ -static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) +static int acpi_processor_get_info(struct acpi_processor *pr) { acpi_status status = 0; union acpi_object object = { 0 }; @@ -527,7 +431,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) * Check to see if we have bus mastering arbitration control. This * is required for proper C3 usage (to maintain cache coherency). */ - if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) { + if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) { pr->flags.bm_control = 1; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Bus mastering arbitration control present\n")); @@ -535,35 +439,24 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No bus mastering arbitration control\n")); - /* Check if it is a Device with HID and UID */ - if (has_uid) { - unsigned long value; - status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, - NULL, &value); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); - return -ENODEV; - } - pr->acpi_id = value; - } else { - /* - * Evalute the processor object. Note that it is common on SMP to - * have the first (boot) processor with a valid PBLK address while - * all others have a NULL address. - */ - status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Evaluating processor object\n"); - return -ENODEV; - } - - /* - * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. - * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c - */ - pr->acpi_id = object.processor.proc_id; + /* + * Evalute the processor object. Note that it is common on SMP to + * have the first (boot) processor with a valid PBLK address while + * all others have a NULL address. + */ + status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Evaluating processor object\n"); + return -ENODEV; } - cpu_index = get_cpu_id(pr->handle, pr->acpi_id); + + /* + * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. + * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c + */ + pr->acpi_id = object.processor.proc_id; + + cpu_index = convert_acpiid_to_cpu(pr->acpi_id); /* Handle UP system running SMP kernel, with no LAPIC in MADT */ if (!cpu0_initialized && (cpu_index == -1) && @@ -580,7 +473,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) * less than the max # of CPUs. They should be ignored _iff * they are physically not present. */ - if (pr->id == -1) { + if (cpu_index == -1) { if (ACPI_FAILURE (acpi_processor_hotadd_init(pr->handle, &pr->id))) { return -ENODEV; @@ -597,8 +490,8 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) object.processor.pblk_length); else { pr->throttling.address = object.processor.pblk_address; - pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset; - pr->throttling.duty_width = acpi_gbl_FADT.duty_width; + pr->throttling.duty_offset = acpi_fadt.duty_offset; + pr->throttling.duty_width = acpi_fadt.duty_width; pr->pblk = object.processor.pblk_address; @@ -632,7 +525,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) pr = acpi_driver_data(device); - result = acpi_processor_get_info(pr, device->flags.unique_id); + result = acpi_processor_get_info(pr); if (result) { /* Processor is physically not present */ return 0; @@ -1002,12 +895,6 @@ static int __init acpi_processor_init(void) memset(&processors, 0, sizeof(processors)); memset(&errata, 0, sizeof(errata)); -#ifdef CONFIG_SMP - if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, - (struct acpi_table_header **)&madt))) - madt = 0; -#endif - acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); if (!acpi_processor_dir) return -ENOMEM; diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 6c6751b1405b..3f30af21574e 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -160,7 +160,7 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2) { if (t2 >= t1) return (t2 - t1); - else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) + else if (!acpi_fadt.tmr_val_ext) return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); else return ((0xFFFFFFFF - t1) + t2); @@ -187,7 +187,8 @@ acpi_processor_power_activate(struct acpi_processor *pr, case ACPI_STATE_C3: /* Disable bus master reload */ if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, + ACPI_MTX_DO_NOT_LOCK); break; } } @@ -197,7 +198,8 @@ acpi_processor_power_activate(struct acpi_processor *pr, case ACPI_STATE_C3: /* Enable bus master reload */ if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, + ACPI_MTX_DO_NOT_LOCK); break; } @@ -234,7 +236,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) /* Dummy wait op - must do something useless after P_LVL2 read because chipsets cannot guarantee that STPCLK# signal gets asserted in time to freeze execution properly. */ - unused = inl(acpi_gbl_FADT.xpm_timer_block.address); + unused = inl(acpi_fadt.xpm_tmr_blk.address); } } @@ -289,10 +291,12 @@ static void acpi_processor_idle(void) pr->power.bm_activity <<= diff; - acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); + acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, + &bm_status, ACPI_MTX_DO_NOT_LOCK); if (bm_status) { pr->power.bm_activity |= 0x1; - acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); + acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, + 1, ACPI_MTX_DO_NOT_LOCK); } /* * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect @@ -334,7 +338,7 @@ static void acpi_processor_idle(void) * detection phase, to work cleanly with logical CPU hotplug. */ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && - !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) + !pr->flags.has_cst && !acpi_fadt.plvl2_up) cx = &pr->power.states[ACPI_STATE_C1]; #endif @@ -380,11 +384,11 @@ static void acpi_processor_idle(void) case ACPI_STATE_C2: /* Get start time (ticks) */ - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C2 */ acpi_cstate_enter(cx); /* Get end time (ticks) */ - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t2 = inl(acpi_fadt.xpm_tmr_blk.address); #ifdef CONFIG_GENERIC_TIME /* TSC halts in C2, so notify users */ @@ -407,7 +411,8 @@ static void acpi_processor_idle(void) * All CPUs are trying to go to C3 * Disable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, + ACPI_MTX_DO_NOT_LOCK); } } else { /* SMP with no shared cache... Invalidate cache */ @@ -415,15 +420,16 @@ static void acpi_processor_idle(void) } /* Get start time (ticks) */ - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C3 */ acpi_cstate_enter(cx); /* Get end time (ticks) */ - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + t2 = inl(acpi_fadt.xpm_tmr_blk.address); if (pr->flags.bm_check) { /* Enable bus master arbitration */ atomic_dec(&c3_cpu_count); - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, + ACPI_MTX_DO_NOT_LOCK); } #ifdef CONFIG_GENERIC_TIME @@ -451,7 +457,7 @@ static void acpi_processor_idle(void) #ifdef CONFIG_HOTPLUG_CPU /* Don't do promotion/demotion */ if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && - !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { + !pr->flags.has_cst && !acpi_fadt.plvl2_up) { next_state = cx; goto end; } @@ -621,8 +627,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) * Check for P_LVL2_UP flag before entering C2 and above on * an SMP system. */ - if ((num_online_cpus() > 1) && - !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) + if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up) return -ENODEV; #endif @@ -631,8 +636,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; /* determine latencies from FADT */ - pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency; - pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency; + pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat; + pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "lvl2[0x%08x] lvl3[0x%08x]\n", @@ -878,13 +883,14 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, * WBINVD should be set in fadt, for C3 state to be * supported on when bm_check is not required. */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_WBINVD)) { + if (acpi_fadt.wb_invd != 1) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cache invalidation should work properly" " for C3 to be enabled on SMP systems\n")); return; } - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, + 0, ACPI_MTX_DO_NOT_LOCK); } /* @@ -1090,7 +1096,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", pr->power.states[i].latency, pr->power.states[i].usage, - (unsigned long long)pr->power.states[i].time); + pr->power.states[i].time); } end: @@ -1158,9 +1164,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, if (!pr) return -EINVAL; - if (acpi_gbl_FADT.cst_control && !nocst) { + if (acpi_fadt.cst_cnt && !nocst) { status = - acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8); + acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Notifying BIOS of _CST ability failed")); diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 058f13cf3b79..cbb6f0814ce2 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -352,24 +352,31 @@ int acpi_processor_notify_smm(struct module *calling_module) is_done = -EIO; - /* Can't write pstate_control to smi_command if either value is zero */ - if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n")); + /* Can't write pstate_cnt to smi_cmd if either value is zero */ + if ((!acpi_fadt.smi_cmd) || (!acpi_fadt.pstate_cnt)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_cnt\n")); module_put(calling_module); return 0; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing pstate_control [0x%x] to smi_command [0x%x]\n", - acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command)); + "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", + acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd)); - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.pstate_control, 8); + /* FADT v1 doesn't support pstate_cnt, many BIOS vendors use + * it anyway, so we need to support it... */ + if (acpi_fadt_is_v1) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Using v1.0 FADT reserved value for pstate_cnt\n")); + } + + status = acpi_os_write_port(acpi_fadt.smi_cmd, + (u32) acpi_fadt.pstate_cnt, 8); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "Failed to write pstate_control [0x%x] to " - "smi_command [0x%x]", acpi_gbl_FADT.pstate_control, - acpi_gbl_FADT.smi_command)); + "Failed to write pstate_cnt [0x%x] to " + "smi_cmd [0x%x]", acpi_fadt.pstate_cnt, + acpi_fadt.smi_cmd)); module_put(calling_module); return status; } diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index 89dff3639abe..0ec7dcde0063 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -125,7 +125,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) /* Used to clear all duty_value bits */ duty_mask = pr->throttling.state_count - 1; - duty_mask <<= acpi_gbl_FADT.duty_offset; + duty_mask <<= acpi_fadt.duty_offset; duty_mask = ~duty_mask; } @@ -208,7 +208,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) return 0; } - pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width; + pr->throttling.state_count = 1 << acpi_fadt.duty_width; /* * Compute state values. Note that throttling displays a linear power/ diff --git a/trunk/drivers/acpi/resources/rsaddr.c b/trunk/drivers/acpi/resources/rsaddr.c index 271e61509eeb..8fa3213ce000 100644 --- a/trunk/drivers/acpi/resources/rsaddr.c +++ b/trunk/drivers/acpi/resources/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rscalc.c b/trunk/drivers/acpi/resources/rscalc.c index 8c6d3fdec38a..cf87b0230026 100644 --- a/trunk/drivers/acpi/resources/rscalc.c +++ b/trunk/drivers/acpi/resources/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rscreate.c b/trunk/drivers/acpi/resources/rscreate.c index 1358c06a969c..008058acdd39 100644 --- a/trunk/drivers/acpi/resources/rscreate.c +++ b/trunk/drivers/acpi/resources/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsdump.c b/trunk/drivers/acpi/resources/rsdump.c index de20a5d6decf..9c99a723a860 100644 --- a/trunk/drivers/acpi/resources/rsdump.c +++ b/trunk/drivers/acpi/resources/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsinfo.c b/trunk/drivers/acpi/resources/rsinfo.c index 7e3c335ab320..9e7ae2f8a1d3 100644 --- a/trunk/drivers/acpi/resources/rsinfo.c +++ b/trunk/drivers/acpi/resources/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsio.c b/trunk/drivers/acpi/resources/rsio.c index b297bc3e4419..ea567167c4f2 100644 --- a/trunk/drivers/acpi/resources/rsio.c +++ b/trunk/drivers/acpi/resources/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsirq.c b/trunk/drivers/acpi/resources/rsirq.c index 5657f7b95039..1fa63bc2e36f 100644 --- a/trunk/drivers/acpi/resources/rsirq.c +++ b/trunk/drivers/acpi/resources/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rslist.c b/trunk/drivers/acpi/resources/rslist.c index a92755c8877d..29423ce030ca 100644 --- a/trunk/drivers/acpi/resources/rslist.c +++ b/trunk/drivers/acpi/resources/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsmemory.c b/trunk/drivers/acpi/resources/rsmemory.c index 521eab7dd8df..a5131936d690 100644 --- a/trunk/drivers/acpi/resources/rsmemory.c +++ b/trunk/drivers/acpi/resources/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsmisc.c b/trunk/drivers/acpi/resources/rsmisc.c index 3b63b561b94e..faf6e106b785 100644 --- a/trunk/drivers/acpi/resources/rsmisc.c +++ b/trunk/drivers/acpi/resources/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsutils.c b/trunk/drivers/acpi/resources/rsutils.c index 2442a8f8df57..a9cbee8e8b44 100644 --- a/trunk/drivers/acpi/resources/rsutils.c +++ b/trunk/drivers/acpi/resources/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/resources/rsxface.c b/trunk/drivers/acpi/resources/rsxface.c index 991f8901498c..1999e2ab7daa 100644 --- a/trunk/drivers/acpi/resources/rsxface.c +++ b/trunk/drivers/acpi/resources/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 0de458664642..283d87522c5d 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -1333,7 +1333,7 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) /* * Enumerate all fixed-feature devices. */ - if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { + if (acpi_fadt.pwr_button == 0) { result = acpi_add_single_object(&device, acpi_root, NULL, ACPI_BUS_TYPE_POWER_BUTTON); @@ -1341,7 +1341,7 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) result = acpi_start_single_object(device); } - if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { + if (acpi_fadt.sleep_button == 0) { result = acpi_add_single_object(&device, acpi_root, NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); diff --git a/trunk/drivers/acpi/sleep/proc.c b/trunk/drivers/acpi/sleep/proc.c index ccc11b33d89c..34962578039d 100644 --- a/trunk/drivers/acpi/sleep/proc.c +++ b/trunk/drivers/acpi/sleep/proc.c @@ -73,7 +73,7 @@ acpi_system_write_sleep(struct file *file, static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) { u32 sec, min, hr; - u32 day, mo, yr, cent = 0; + u32 day, mo, yr; unsigned char rtc_control = 0; unsigned long flags; @@ -87,19 +87,20 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) rtc_control = CMOS_READ(RTC_CONTROL); /* If we ever get an FACP with proper values... */ - if (acpi_gbl_FADT.day_alarm) + if (acpi_gbl_FADT->day_alrm) /* ACPI spec: only low 6 its should be cared */ - day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; + day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F; else day = CMOS_READ(RTC_DAY_OF_MONTH); - if (acpi_gbl_FADT.month_alarm) - mo = CMOS_READ(acpi_gbl_FADT.month_alarm); + if (acpi_gbl_FADT->mon_alrm) + mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); else mo = CMOS_READ(RTC_MONTH); - if (acpi_gbl_FADT.century) - cent = CMOS_READ(acpi_gbl_FADT.century); - - yr = CMOS_READ(RTC_YEAR); + if (acpi_gbl_FADT->century) + yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + + CMOS_READ(RTC_YEAR); + else + yr = CMOS_READ(RTC_YEAR); spin_unlock_irqrestore(&rtc_lock, flags); @@ -110,11 +111,10 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) BCD_TO_BIN(day); BCD_TO_BIN(mo); BCD_TO_BIN(yr); - BCD_TO_BIN(cent); } /* we're trusting the FADT (see above) */ - if (!acpi_gbl_FADT.century) + if (!acpi_gbl_FADT->century) /* If we're not trusting the FADT, we should at least make it * right for _this_ century... ehm, what is _this_ century? * @@ -134,8 +134,6 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) * */ yr += 2000; - else - yr += cent * 100; seq_printf(seq, "%4.4u-", yr); (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); @@ -319,12 +317,12 @@ acpi_system_write_alarm(struct file *file, * offsets into the CMOS RAM here -- which for some reason are pointing * to the RTC area of memory. */ - if (acpi_gbl_FADT.day_alarm) - CMOS_WRITE(day, acpi_gbl_FADT.day_alarm); - if (acpi_gbl_FADT.month_alarm) - CMOS_WRITE(mo, acpi_gbl_FADT.month_alarm); - if (acpi_gbl_FADT.century) - CMOS_WRITE(yr / 100, acpi_gbl_FADT.century); + if (acpi_gbl_FADT->day_alrm) + CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); + if (acpi_gbl_FADT->mon_alrm) + CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); + if (acpi_gbl_FADT->century) + CMOS_WRITE(yr / 100, acpi_gbl_FADT->century); /* enable the rtc alarm interrupt */ rtc_control |= RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); diff --git a/trunk/drivers/acpi/system.c b/trunk/drivers/acpi/system.c index 2d425d845821..d86dcb3c2366 100644 --- a/trunk/drivers/acpi/system.c +++ b/trunk/drivers/acpi/system.c @@ -39,6 +39,7 @@ ACPI_MODULE_NAME("acpi_system") #define ACPI_SYSTEM_FILE_EVENT "event" #define ACPI_SYSTEM_FILE_DSDT "dsdt" #define ACPI_SYSTEM_FILE_FADT "fadt" +extern struct fadt_descriptor acpi_fadt; /* -------------------------------------------------------------------------- FS Interface (/proc) @@ -75,16 +76,17 @@ acpi_system_read_dsdt(struct file *file, char __user * buffer, size_t count, loff_t * ppos) { acpi_status status = AE_OK; - struct acpi_table_header *dsdt = NULL; + struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; ssize_t res; - status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); + status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); if (ACPI_FAILURE(status)) return -ENODEV; res = simple_read_from_buffer(buffer, count, ppos, - dsdt, dsdt->length); + dsdt.pointer, dsdt.length); + kfree(dsdt.pointer); return res; } @@ -101,16 +103,17 @@ acpi_system_read_fadt(struct file *file, char __user * buffer, size_t count, loff_t * ppos) { acpi_status status = AE_OK; - struct acpi_table_header *fadt = NULL; + struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL }; ssize_t res; - status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); + status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt); if (ACPI_FAILURE(status)) return -ENODEV; res = simple_read_from_buffer(buffer, count, ppos, - fadt, fadt->length); + fadt.pointer, fadt.length); + kfree(fadt.pointer); return res; } diff --git a/trunk/drivers/acpi/tables.c b/trunk/drivers/acpi/tables.c index ba4cb200314a..ffa30c9fccbf 100644 --- a/trunk/drivers/acpi/tables.c +++ b/trunk/drivers/acpi/tables.c @@ -38,97 +38,154 @@ #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", +}; + static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; -static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; +/* 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 */ -void acpi_table_print_madt_entry(struct acpi_subtable_header * header) +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; + + 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_TYPE_LOCAL_APIC: + case ACPI_MADT_LAPIC: { - struct acpi_madt_local_apic *p = - (struct acpi_madt_local_apic *)header; + struct acpi_table_lapic *p = + (struct acpi_table_lapic *)header; printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", - p->processor_id, p->id, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + p->acpi_id, p->id, + p->flags.enabled ? "enabled" : "disabled"); } break; - case ACPI_MADT_TYPE_IO_APIC: + case ACPI_MADT_IOAPIC: { - struct acpi_madt_io_apic *p = - (struct acpi_madt_io_apic *)header; + struct acpi_table_ioapic *p = + (struct acpi_table_ioapic *)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_TYPE_INTERRUPT_OVERRIDE: + case ACPI_MADT_INT_SRC_OVR: { - struct acpi_madt_interrupt_override *p = - (struct acpi_madt_interrupt_override *)header; + struct acpi_table_int_src_ovr *p = + (struct acpi_table_int_src_ovr *)header; printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", - 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)) + 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) printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n", - p->inti_flags & - ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)); + p->flags.reserved); } break; - case ACPI_MADT_TYPE_NMI_SOURCE: + case ACPI_MADT_NMI_SRC: { - struct acpi_madt_nmi_source *p = - (struct acpi_madt_nmi_source *)header; + struct acpi_table_nmi_src *p = + (struct acpi_table_nmi_src *)header; printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n", - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], p->global_irq); } break; - case ACPI_MADT_TYPE_LOCAL_APIC_NMI: + case ACPI_MADT_LAPIC_NMI: { - struct acpi_madt_local_apic_nmi *p = - (struct acpi_madt_local_apic_nmi *)header; + struct acpi_table_lapic_nmi *p = + (struct acpi_table_lapic_nmi *)header; printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", - 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->acpi_id, + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], p->lint); } break; - case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: + case ACPI_MADT_LAPIC_ADDR_OVR: { - struct acpi_madt_local_apic_override *p = - (struct acpi_madt_local_apic_override *)header; + struct acpi_table_lapic_addr_ovr *p = + (struct acpi_table_lapic_addr_ovr *)header; printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n", (void *)(unsigned long)p->address); } break; - case ACPI_MADT_TYPE_IO_SAPIC: + case ACPI_MADT_IOSAPIC: { - struct acpi_madt_io_sapic *p = - (struct acpi_madt_io_sapic *)header; + struct acpi_table_iosapic *p = + (struct acpi_table_iosapic *)header; printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", p->id, (void *)(unsigned long)p->address, @@ -136,26 +193,26 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header * header) } break; - case ACPI_MADT_TYPE_LOCAL_SAPIC: + case ACPI_MADT_LSAPIC: { - struct acpi_madt_local_sapic *p = - (struct acpi_madt_local_sapic *)header; + struct acpi_table_lsapic *p = + (struct acpi_table_lsapic *)header; printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", - p->processor_id, p->id, p->eid, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + p->acpi_id, p->id, p->eid, + p->flags.enabled ? "enabled" : "disabled"); } break; - case ACPI_MADT_TYPE_INTERRUPT_SOURCE: + case ACPI_MADT_PLAT_INT_SRC: { - struct acpi_madt_interrupt_source *p = - (struct acpi_madt_interrupt_source *)header; + struct acpi_table_plat_int_src *p = + (struct acpi_table_plat_int_src *)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->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, + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], + p->type, p->id, p->eid, p->iosapic_vector, p->global_irq); } break; @@ -168,76 +225,342 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header * header) } } +static int +acpi_table_compute_checksum(void *table_pointer, unsigned long length) +{ + u8 *p = 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_table_parse_madt_family(char *id, +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 fadt_descriptor *fadt = + (struct fadt_descriptor *)*header; + + if (fadt->revision == 3 && fadt->Xdsdt) { + *header = (void *)__acpi_map_table(fadt->Xdsdt, + sizeof(struct + acpi_table_header)); + } else if (fadt->V1_dsdt) { + *header = (void *)__acpi_map_table(fadt->V1_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, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries) { - struct acpi_table_header *madt = NULL; - struct acpi_subtable_header *entry; + void *madt = NULL; + acpi_table_entry_header *entry; unsigned int count = 0; unsigned long madt_end; + unsigned int i; if (!handler) return -EINVAL; /* Locate the MADT (if exists). There should only be one. */ - acpi_get_table(id, 0, &madt); + + 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 "%4.4s not present\n", id); + printk(KERN_WARNING PREFIX "%s not present\n", + acpi_table_signatures[id]); return -ENODEV; } - madt_end = (unsigned long)madt + madt->length; + madt_end = (unsigned long)madt + sdt_entry[i].size; /* Parse all entries looking for a match. */ - entry = (struct acpi_subtable_header *) + entry = (acpi_table_entry_header *) ((unsigned long)madt + madt_size); - while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < + while (((unsigned long)entry) + sizeof(acpi_table_entry_header) < madt_end) { if (entry->type == entry_id && (!max_entries || count++ < max_entries)) if (handler(entry, madt_end)) return -EINVAL; - entry = (struct acpi_subtable_header *) + entry = (acpi_table_entry_header *) ((unsigned long)entry + entry->length); } if (max_entries && count > max_entries) { - printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of " - "%i found\n", id, entry_id, count - max_entries, count); + printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of " + "%i found\n", acpi_table_signatures[id], entry_id, + count - max_entries, count); } return count; } int __init -acpi_table_parse_madt(enum acpi_madt_type id, +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_SIG_MADT, + return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt), id, handler, max_entries); } -int __init acpi_table_parse(char *id, acpi_table_handler handler) +int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler) { - struct acpi_table_header *table = NULL; + int count = 0; + unsigned int i = 0; + if (!handler) return -EINVAL; - acpi_get_table(id, 0, &table); - if (table) { - handler(table); - return 1; - } else - return 0; + 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) && + (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) { + + struct acpi_table_xsdt *mapped_xsdt = NULL; + + sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + + if (!header) { + printk(KERN_WARNING PREFIX + "Unable to map XSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_xsdt = (struct acpi_table_xsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_xsdt) { + printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); + return -ENODEV; + } + header = &mapped_xsdt->header; + + if (strncmp(header->signature, "XSDT", 4)) { + printk(KERN_WARNING PREFIX + "XSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); + return -ENODEV; + } + + 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->entry[i]; + } + + /* Then check RSDT */ + + else if (rsdp->rsdt_address) { + + struct acpi_table_rsdt *mapped_rsdt = NULL; + + sdt_pa = rsdp->rsdt_address; + + /* map in just the header */ + header = (struct acpi_table_header *) + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); + if (!header) { + printk(KERN_WARNING PREFIX + "Unable to map RSDT header\n"); + return -ENODEV; + } + + /* remap in the entire table before processing */ + mapped_rsdt = (struct acpi_table_rsdt *) + __acpi_map_table(sdt_pa, header->length); + if (!mapped_rsdt) { + printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); + return -ENODEV; + } + header = &mapped_rsdt->header; + + if (strncmp(header->signature, "RSDT", 4)) { + printk(KERN_WARNING PREFIX + "RSDT signature incorrect\n"); + return -ENODEV; + } + + if (acpi_table_compute_checksum(header, header->length)) { + printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n"); + return -ENODEV; + } + + 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->entry[i]; + } + + else { + 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; } /* @@ -245,13 +568,54 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) * * find RSDP, find and checksum SDT/XSDT. * checksum all tables, print SDT/XSDT - * + * * result: sdt_entry[] is initialized */ - int __init acpi_table_init(void) { - acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + 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, + sizeof(struct acpi_table_rsdp)); + else + result = + acpi_table_compute_checksum(rsdp, + ((struct acpi20_table_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; + return 0; } diff --git a/trunk/drivers/acpi/tables/Makefile b/trunk/drivers/acpi/tables/Makefile index 0a7d7afac255..aa4c69594d97 100644 --- a/trunk/drivers/acpi/tables/Makefile +++ b/trunk/drivers/acpi/tables/Makefile @@ -2,6 +2,7 @@ # Makefile for all Linux ACPI interpreter subdirectories # -obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o +obj-y := tbconvrt.o tbget.o tbrsdt.o tbxface.o \ + tbgetall.o tbinstal.o tbutils.o tbxfroot.o EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/trunk/drivers/acpi/tables/tbconvrt.c b/trunk/drivers/acpi/tables/tbconvrt.c new file mode 100644 index 000000000000..d697fcb35d52 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbconvrt.c @@ -0,0 +1,622 @@ +/****************************************************************************** + * + * Module Name: tbconvrt - ACPI Table conversion utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, 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. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbconvrt") + +/* Local prototypes */ +static void +acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, + u8 register_bit_width, + acpi_physical_address address); + +static void +acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, + struct fadt_descriptor_rev1 *original_fadt); + +static void +acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, + struct fadt_descriptor *original_fadt); + +u8 acpi_fadt_is_v1; +ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1) + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_count + * + * PARAMETERS: RSDP - Pointer to the RSDP + * RSDT - Pointer to the RSDT/XSDT + * + * RETURN: The number of tables pointed to by the RSDT or XSDT. + * + * DESCRIPTION: Calculate the number of tables. Automatically handles either + * an RSDT or XSDT. + * + ******************************************************************************/ + +u32 +acpi_tb_get_table_count(struct rsdp_descriptor *RSDP, + struct acpi_table_header *RSDT) +{ + u32 pointer_size; + + ACPI_FUNCTION_ENTRY(); + + /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + pointer_size = sizeof(u32); + } else { + pointer_size = sizeof(u64); + } + + /* + * Determine the number of tables pointed to by the RSDT/XSDT. + * This is defined by the ACPI Specification to be the number of + * pointers contained within the RSDT/XSDT. The size of the pointers + * is architecture-dependent. + */ + return ((RSDT->length - + sizeof(struct acpi_table_header)) / pointer_size); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_to_xsdt + * + * PARAMETERS: table_info - Info about the RSDT + * + * RETURN: Status + * + * DESCRIPTION: Convert an RSDT to an XSDT (internal common format) + * + ******************************************************************************/ + +acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) +{ + acpi_size table_size; + u32 i; + struct xsdt_descriptor *new_table; + + ACPI_FUNCTION_ENTRY(); + + /* Compute size of the converted XSDT */ + + table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof(u64)) + + sizeof(struct acpi_table_header); + + /* Allocate an XSDT */ + + new_table = ACPI_ALLOCATE_ZEROED(table_size); + if (!new_table) { + return (AE_NO_MEMORY); + } + + /* Copy the header and set the length */ + + ACPI_MEMCPY(new_table, table_info->pointer, + sizeof(struct acpi_table_header)); + new_table->length = (u32) table_size; + + /* Copy the table pointers */ + + for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { + + /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + ACPI_STORE_ADDRESS(new_table->table_offset_entry[i], + (ACPI_CAST_PTR + (struct rsdt_descriptor, + table_info->pointer))-> + table_offset_entry[i]); + } else { + new_table->table_offset_entry[i] = + (ACPI_CAST_PTR(struct xsdt_descriptor, + table_info->pointer))-> + table_offset_entry[i]; + } + } + + /* Delete the original table (either mapped or in a buffer) */ + + acpi_tb_delete_single_table(table_info); + + /* Point the table descriptor to the new table */ + + table_info->pointer = + ACPI_CAST_PTR(struct acpi_table_header, new_table); + table_info->length = table_size; + table_info->allocation = ACPI_MEM_ALLOCATED; + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_init_generic_address + * + * PARAMETERS: new_gas_struct - GAS struct to be initialized + * register_bit_width - Width of this register + * Address - Address of the register + * + * RETURN: None + * + * DESCRIPTION: Initialize a GAS structure. + * + ******************************************************************************/ + +static void +acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, + u8 register_bit_width, + acpi_physical_address address) +{ + + ACPI_STORE_ADDRESS(new_gas_struct->address, address); + + new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; + new_gas_struct->register_bit_width = register_bit_width; + new_gas_struct->register_bit_offset = 0; + new_gas_struct->access_width = 0; +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_fadt1 + * + * PARAMETERS: local_fadt - Pointer to new FADT + * original_fadt - Pointer to old FADT + * + * RETURN: None, populates local_fadt + * + * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format + * + ******************************************************************************/ + +static void +acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, + struct fadt_descriptor_rev1 *original_fadt) +{ + + /* ACPI 1.0 FACS */ + /* The BIOS stored FADT should agree with Revision 1.0 */ + acpi_fadt_is_v1 = 1; + + /* + * Copy the table header and the common part of the tables. + * + * The 2.0 table is an extension of the 1.0 table, so the entire 1.0 + * table can be copied first, then expand some fields to 64 bits. + */ + ACPI_MEMCPY(local_fadt, original_fadt, + sizeof(struct fadt_descriptor_rev1)); + + /* Convert table pointers to 64-bit fields */ + + ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, + local_fadt->V1_firmware_ctrl); + ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); + + /* + * System Interrupt Model isn't used in ACPI 2.0 + * (local_fadt->Reserved1 = 0;) + */ + + /* + * This field is set by the OEM to convey the preferred power management + * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't + * know what kind of 32-bit system this is, we will use "unspecified". + */ + local_fadt->prefer_PM_profile = PM_UNSPECIFIED; + + /* + * Processor Performance State Control. This is the value OSPM writes to + * the SMI_CMD register to assume processor performance state control + * responsibility. There isn't any equivalence in 1.0, but as many 1.x + * ACPI tables contain _PCT and _PSS we also keep this value, unless + * acpi_strict is set. + */ + if (acpi_strict) + local_fadt->pstate_cnt = 0; + + /* + * Support for the _CST object and C States change notification. + * This data item hasn't any 1.0 equivalence so leave it zero. + */ + local_fadt->cst_cnt = 0; + + /* + * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0. + * It primarily adds the FADT reset mechanism. + */ + if ((original_fadt->revision == 2) && + (original_fadt->length == + sizeof(struct fadt_descriptor_rev2_minus))) { + /* + * Grab the entire generic address struct, plus the 1-byte reset value + * that immediately follows. + */ + ACPI_MEMCPY(&local_fadt->reset_register, + &(ACPI_CAST_PTR(struct fadt_descriptor_rev2_minus, + original_fadt))->reset_register, + sizeof(struct acpi_generic_address) + 1); + } else { + /* + * Since there isn't any equivalence in 1.0 and since it is highly + * likely that a 1.0 system has legacy support. + */ + local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; + } + + /* + * Convert the V1.0 block addresses to V2.0 GAS structures + */ + acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt-> + V1_pm1a_evt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt-> + V1_pm1b_evt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt-> + V1_pm1a_cnt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt-> + V1_pm1b_cnt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, + local_fadt->pm2_cnt_len, + (acpi_physical_address) local_fadt-> + V1_pm2_cnt_blk); + acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, + local_fadt->pm_tm_len, + (acpi_physical_address) local_fadt-> + V1_pm_tmr_blk); + acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, 0, + (acpi_physical_address) local_fadt-> + V1_gpe0_blk); + acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, 0, + (acpi_physical_address) local_fadt-> + V1_gpe1_blk); + + /* Create separate GAS structs for the PM1 Enable registers */ + + acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); + + /* PM1B is optional; leave null if not present */ + + if (local_fadt->xpm1b_evt_blk.address) { + acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1b_evt_blk. + address + + ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len))); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_fadt2 + * + * PARAMETERS: local_fadt - Pointer to new FADT + * original_fadt - Pointer to old FADT + * + * RETURN: None, populates local_fadt + * + * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format. + * Handles optional "X" fields. + * + ******************************************************************************/ + +static void +acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, + struct fadt_descriptor *original_fadt) +{ + + /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ + + ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor)); + + /* + * "X" fields are optional extensions to the original V1.0 fields, so + * we must selectively expand V1.0 fields if the corresponding X field + * is zero. + */ + if (!(local_fadt->xfirmware_ctrl)) { + ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, + local_fadt->V1_firmware_ctrl); + } + + if (!(local_fadt->Xdsdt)) { + ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); + } + + if (!(local_fadt->xpm1a_evt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) + local_fadt->V1_pm1a_evt_blk); + } + + if (!(local_fadt->xpm1b_evt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, + local_fadt->pm1_evt_len, + (acpi_physical_address) + local_fadt->V1_pm1b_evt_blk); + } + + if (!(local_fadt->xpm1a_cnt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) + local_fadt->V1_pm1a_cnt_blk); + } + + if (!(local_fadt->xpm1b_cnt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, + local_fadt->pm1_cnt_len, + (acpi_physical_address) + local_fadt->V1_pm1b_cnt_blk); + } + + if (!(local_fadt->xpm2_cnt_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, + local_fadt->pm2_cnt_len, + (acpi_physical_address) + local_fadt->V1_pm2_cnt_blk); + } + + if (!(local_fadt->xpm_tmr_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, + local_fadt->pm_tm_len, + (acpi_physical_address) + local_fadt->V1_pm_tmr_blk); + } + + if (!(local_fadt->xgpe0_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, + 0, + (acpi_physical_address) + local_fadt->V1_gpe0_blk); + } + + if (!(local_fadt->xgpe1_blk.address)) { + acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, + 0, + (acpi_physical_address) + local_fadt->V1_gpe1_blk); + } + + /* Create separate GAS structs for the PM1 Enable registers */ + + acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); + + acpi_gbl_xpm1a_enable.address_space_id = + local_fadt->xpm1a_evt_blk.address_space_id; + + /* PM1B is optional; leave null if not present */ + + if (local_fadt->xpm1b_evt_blk.address) { + acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len), + (acpi_physical_address) + (local_fadt->xpm1b_evt_blk. + address + + ACPI_DIV_2(acpi_gbl_FADT-> + pm1_evt_len))); + + acpi_gbl_xpm1b_enable.address_space_id = + local_fadt->xpm1b_evt_blk.address_space_id; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_convert_table_fadt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local + * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply + * copied to the local FADT. The ACPI CA software uses this + * local FADT. Thus a significant amount of special #ifdef + * type codeing is saved. + * + ******************************************************************************/ + +acpi_status acpi_tb_convert_table_fadt(void) +{ + struct fadt_descriptor *local_fadt; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE(tb_convert_table_fadt); + + /* + * acpi_gbl_FADT is valid. Validate the FADT length. The table must be + * at least as long as the version 1.0 FADT + */ + if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) { + ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X", + acpi_gbl_FADT->length)); + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + /* Allocate buffer for the ACPI 2.0(+) FADT */ + + local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor)); + if (!local_fadt) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { + if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) { + + /* Length is too short to be a V2.0 table */ + + ACPI_WARNING((AE_INFO, + "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table", + acpi_gbl_FADT->length, + acpi_gbl_FADT->revision)); + + acpi_tb_convert_fadt1(local_fadt, + (void *)acpi_gbl_FADT); + } else { + /* Valid V2.0 table */ + + acpi_tb_convert_fadt2(local_fadt, acpi_gbl_FADT); + } + } else { + /* Valid V1.0 table */ + + acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT); + } + + /* Global FADT pointer will point to the new common V2.0 FADT */ + + acpi_gbl_FADT = local_fadt; + acpi_gbl_FADT->length = sizeof(struct fadt_descriptor); + + /* Free the original table */ + + table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_FADT].next; + acpi_tb_delete_single_table(table_desc); + + /* Install the new table */ + + table_desc->pointer = + ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT); + table_desc->allocation = ACPI_MEM_ALLOCATED; + table_desc->length = sizeof(struct fadt_descriptor); + + /* Dump the entire FADT */ + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, + "Hex dump of common internal FADT, size %d (%X)\n", + acpi_gbl_FADT->length, acpi_gbl_FADT->length)); + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT), + acpi_gbl_FADT->length); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_build_common_facs + * + * PARAMETERS: table_info - Info for currently installed FACS + * + * RETURN: Status + * + * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal + * table format. + * + ******************************************************************************/ + +acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) +{ + + ACPI_FUNCTION_TRACE(tb_build_common_facs); + + /* Absolute minimum length is 24, but the ACPI spec says 64 */ + + if (acpi_gbl_FACS->length < 24) { + ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X", + acpi_gbl_FACS->length)); + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + if (acpi_gbl_FACS->length < 64) { + ACPI_WARNING((AE_INFO, + "FACS is shorter than the ACPI specification allows: 0x%X, using anyway", + acpi_gbl_FACS->length)); + } + + /* Copy fields to the new FACS */ + + acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock); + + if ((acpi_gbl_RSDP->revision < 2) || + (acpi_gbl_FACS->length < 32) || + (!(acpi_gbl_FACS->xfirmware_waking_vector))) { + + /* ACPI 1.0 FACS or short table or optional X_ field is zero */ + + acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64, + & + (acpi_gbl_FACS-> + firmware_waking_vector)); + acpi_gbl_common_fACS.vector_width = 32; + } else { + /* ACPI 2.0 FACS with valid X_ field */ + + acpi_gbl_common_fACS.firmware_waking_vector = + &acpi_gbl_FACS->xfirmware_waking_vector; + acpi_gbl_common_fACS.vector_width = 64; + } + + return_ACPI_STATUS(AE_OK); +} diff --git a/trunk/drivers/acpi/tables/tbfadt.c b/trunk/drivers/acpi/tables/tbfadt.c deleted file mode 100644 index 807c7116e94b..000000000000 --- a/trunk/drivers/acpi/tables/tbfadt.c +++ /dev/null @@ -1,434 +0,0 @@ -/****************************************************************************** - * - * Module Name: tbfadt - FADT table utilities - * - *****************************************************************************/ - -/* - * 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. - */ - -#include -#include - -#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. - * - ******************************************************************************/ - -void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) -{ - - /* - * Check if the FADT is larger than what we know about (ACPI 2.0 version). - * Truncate the table, but make some noise. - */ - 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))); - } - - /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ - - ACPI_MEMSET(&acpi_gbl_FADT, 0, 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; - } - - /* - * Expand the 32-bit V1.0 addresses to the 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 --git a/trunk/drivers/acpi/tables/tbfind.c b/trunk/drivers/acpi/tables/tbfind.c deleted file mode 100644 index 058c064948e1..000000000000 --- a/trunk/drivers/acpi/tables/tbfind.c +++ /dev/null @@ -1,126 +0,0 @@ -/****************************************************************************** - * - * Module Name: tbfind - find table - * - *****************************************************************************/ - -/* - * 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. - */ - -#include -#include - -#define _COMPONENT ACPI_TABLES -ACPI_MODULE_NAME("tbfind") - -/******************************************************************************* - * - * FUNCTION: acpi_tb_find_table - * - * PARAMETERS: Signature - String with ACPI table signature - * oem_id - String with the table OEM ID - * oem_table_id - String with the OEM Table ID - * table_index - Where the table index is returned - * - * RETURN: Status and table index - * - * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the - * Signature, OEM ID and OEM Table ID. Returns an index that can - * be used to get the table header or entire table. - * - ******************************************************************************/ -acpi_status -acpi_tb_find_table(char *signature, - char *oem_id, - char *oem_table_id, acpi_native_uint * table_index) -{ - acpi_native_uint i; - acpi_status status; - - ACPI_FUNCTION_TRACE(tb_find_table); - - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), - signature, ACPI_NAME_SIZE)) { - - /* Not the requested table */ - - continue; - } - - /* Table with matching signature has been found */ - - if (!acpi_gbl_root_table_list.tables[i].pointer) { - - /* Table is not currently mapped, map it */ - - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[i]); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (!acpi_gbl_root_table_list.tables[i].pointer) { - continue; - } - } - - /* Check for table match on all IDs */ - - if (!ACPI_MEMCMP - (acpi_gbl_root_table_list.tables[i].pointer->signature, - signature, ACPI_NAME_SIZE) && (!oem_id[0] - || - !ACPI_MEMCMP - (acpi_gbl_root_table_list. - tables[i].pointer->oem_id, - oem_id, ACPI_OEM_ID_SIZE)) - && (!oem_table_id[0] - || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. - pointer->oem_table_id, oem_table_id, - ACPI_OEM_TABLE_ID_SIZE))) { - *table_index = i; - - ACPI_DEBUG_PRINT((ACPI_DB_TABLES, - "Found table [%4.4s]\n", signature)); - return_ACPI_STATUS(AE_OK); - } - } - - return_ACPI_STATUS(AE_NOT_FOUND); -} diff --git a/trunk/drivers/acpi/tables/tbget.c b/trunk/drivers/acpi/tables/tbget.c new file mode 100644 index 000000000000..11e2d4454e05 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbget.c @@ -0,0 +1,471 @@ +/****************************************************************************** + * + * Module Name: tbget - ACPI Table get* routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, 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. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbget") + +/* Local prototypes */ +static acpi_status +acpi_tb_get_this_table(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +static acpi_status +acpi_tb_table_override(struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * table_info - Where table info is returned + * + * RETURN: None + * + * DESCRIPTION: Get entire table of unknown size. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + ACPI_FUNCTION_TRACE(tb_get_table); + + /* Get the header in order to get signature and table size */ + + status = acpi_tb_get_table_header(address, &header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body(address, &header, table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get ACPI table (size %X)", + header.length)); + return_ACPI_STATUS(status); + } + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_header + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * return_header - Where the table header is returned + * + * RETURN: Status + * + * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table_header(struct acpi_pointer *address, + struct acpi_table_header *return_header) +{ + acpi_status status = AE_OK; + struct acpi_table_header *header = NULL; + + ACPI_FUNCTION_TRACE(tb_get_table_header); + + /* + * Flags contains the current processor mode (Virtual or Physical + * addressing) The pointer_type is either Logical or Physical + */ + switch (address->pointer_type) { + case ACPI_PHYSMODE_PHYSPTR: + case ACPI_LOGMODE_LOGPTR: + + /* Pointer matches processor mode, copy the header */ + + ACPI_MEMCPY(return_header, address->pointer.logical, + sizeof(struct acpi_table_header)); + break; + + case ACPI_LOGMODE_PHYSPTR: + + /* Create a logical address for the physical pointer */ + + status = acpi_os_map_memory(address->pointer.physical, + sizeof(struct acpi_table_header), + (void *)&header); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X%8.8X for table header", + ACPI_FORMAT_UINT64(address->pointer. + physical))); + return_ACPI_STATUS(status); + } + + /* Copy header and delete mapping */ + + ACPI_MEMCPY(return_header, header, + sizeof(struct acpi_table_header)); + acpi_os_unmap_memory(header, sizeof(struct acpi_table_header)); + break; + + default: + + ACPI_ERROR((AE_INFO, "Invalid address flags %X", + address->pointer_type)); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n", + return_header->signature)); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_body + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * Header - Header of the table to retrieve + * table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to + * replace the table with a newer version (table override.) + * Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table_body(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(tb_get_table_body); + + if (!table_info || !address) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Attempt table override. */ + + status = acpi_tb_table_override(header, table_info); + if (ACPI_SUCCESS(status)) { + + /* Table was overridden by the host OS */ + + return_ACPI_STATUS(status); + } + + /* No override, get the original table */ + + status = acpi_tb_get_this_table(address, header, table_info); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_table_override + * + * PARAMETERS: Header - Pointer to table header + * table_info - Return info if table is overridden + * + * RETURN: None + * + * DESCRIPTION: Attempts override of current table with a new one if provided + * by the host OS. + * + ******************************************************************************/ + +static acpi_status +acpi_tb_table_override(struct acpi_table_header *header, + struct acpi_table_desc *table_info) +{ + struct acpi_table_header *new_table; + acpi_status status; + struct acpi_pointer address; + + ACPI_FUNCTION_TRACE(tb_table_override); + + /* + * The OSL will examine the header and decide whether to override this + * table. If it decides to override, a table will be returned in new_table, + * which we will then copy. + */ + status = acpi_os_table_override(header, &new_table); + if (ACPI_FAILURE(status)) { + + /* Some severe error from the OSL, but we basically ignore it */ + + ACPI_EXCEPTION((AE_INFO, status, + "Could not override ACPI table")); + return_ACPI_STATUS(status); + } + + if (!new_table) { + + /* No table override */ + + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* + * We have a new table to override the old one. Get a copy of + * the new one. We know that the new table has a logical pointer. + */ + address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; + address.pointer.logical = new_table; + + status = acpi_tb_get_this_table(&address, new_table, table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table")); + return_ACPI_STATUS(status); + } + + /* Copy the table info */ + + ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS", + table_info->pointer->signature)); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_this_table + * + * PARAMETERS: Address - Address of table to retrieve. Can be + * Logical or Physical + * Header - Header of the table to retrieve + * table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual + * addressing mode. Works with both physical or logical pointers. + * Table is either copied or mapped, depending on the pointer + * type and mode of the processor. + * + ******************************************************************************/ + +static acpi_status +acpi_tb_get_this_table(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info) +{ + struct acpi_table_header *full_table = NULL; + u8 allocation; + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE(tb_get_this_table); + + /* Validate minimum length */ + + if (header->length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, + "Table length (%X) is smaller than minimum (%zX)", + header->length, sizeof(struct acpi_table_header))); + + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + /* + * Flags contains the current processor mode (Virtual or Physical + * addressing) The pointer_type is either Logical or Physical + */ + switch (address->pointer_type) { + case ACPI_PHYSMODE_PHYSPTR: + case ACPI_LOGMODE_LOGPTR: + + /* Pointer matches processor mode, copy the table to a new buffer */ + + full_table = ACPI_ALLOCATE(header->length); + if (!full_table) { + ACPI_ERROR((AE_INFO, + "Could not allocate table memory for [%4.4s] length %X", + header->signature, header->length)); + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Copy the entire table (including header) to the local buffer */ + + ACPI_MEMCPY(full_table, address->pointer.logical, + header->length); + + /* Save allocation type */ + + allocation = ACPI_MEM_ALLOCATED; + break; + + case ACPI_LOGMODE_PHYSPTR: + + /* + * Just map the table's physical memory + * into our address space. + */ + status = acpi_os_map_memory(address->pointer.physical, + (acpi_size) header->length, + ACPI_CAST_PTR(void, &full_table)); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", + header->signature, + ACPI_FORMAT_UINT64(address->pointer. + physical), + header->length)); + return (status); + } + + /* Save allocation type */ + + allocation = ACPI_MEM_MAPPED; + break; + + default: + + ACPI_ERROR((AE_INFO, "Invalid address flags %X", + address->pointer_type)); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* + * Validate checksum for _most_ tables, + * even the ones whose signature we don't recognize + */ + if (table_info->type != ACPI_TABLE_ID_FACS) { + status = acpi_tb_verify_table_checksum(full_table); + +#if (!ACPI_CHECKSUM_ABORT) + if (ACPI_FAILURE(status)) { + + /* Ignore the error if configuration says so */ + + status = AE_OK; + } +#endif + } + + /* Return values */ + + table_info->pointer = full_table; + table_info->length = (acpi_size) header->length; + table_info->allocation = allocation; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", + full_table->signature, + ACPI_FORMAT_UINT64(address->pointer.physical), + full_table)); + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_ptr + * + * PARAMETERS: table_type - one of the defined table types + * Instance - Which table of this type + * return_table - pointer to location to place the pointer for + * return + * + * RETURN: Status + * + * DESCRIPTION: This function is called to get the pointer to an ACPI table. + * + ******************************************************************************/ + +acpi_status +acpi_tb_get_table_ptr(acpi_table_type table_type, + u32 instance, struct acpi_table_header **return_table) +{ + struct acpi_table_desc *table_desc; + u32 i; + + ACPI_FUNCTION_TRACE(tb_get_table_ptr); + + if (table_type > ACPI_TABLE_ID_MAX) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Check for instance out of range of the current table count */ + + if (instance > acpi_gbl_table_lists[table_type].count) { + return_ACPI_STATUS(AE_NOT_EXIST); + } + + /* + * Walk the list to get the desired table + * Note: Instance is one-based + */ + table_desc = acpi_gbl_table_lists[table_type].next; + for (i = 1; i < instance; i++) { + table_desc = table_desc->next; + } + + /* We are now pointing to the requested table's descriptor */ + + *return_table = table_desc->pointer; + return_ACPI_STATUS(AE_OK); +} diff --git a/trunk/drivers/acpi/tables/tbgetall.c b/trunk/drivers/acpi/tables/tbgetall.c new file mode 100644 index 000000000000..ad982112e4c6 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbgetall.c @@ -0,0 +1,311 @@ +/****************************************************************************** + * + * Module Name: tbgetall - Get all required ACPI tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, 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. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbgetall") + +/* Local prototypes */ +static acpi_status +acpi_tb_get_primary_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info); + +static acpi_status +acpi_tb_get_secondary_table(struct acpi_pointer *address, + acpi_string signature, + struct acpi_table_desc *table_info); + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_primary_table + * + * PARAMETERS: Address - Physical address of table to retrieve + * *table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Maps the physical address of table into a logical address + * + ******************************************************************************/ + +static acpi_status +acpi_tb_get_primary_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + ACPI_FUNCTION_TRACE(tb_get_primary_table); + + /* Ignore a NULL address in the RSDT */ + + if (!address->pointer.value) { + return_ACPI_STATUS(AE_OK); + } + + /* Get the header in order to get signature and table size */ + + status = acpi_tb_get_table_header(address, &header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Clear the table_info */ + + ACPI_MEMSET(table_info, 0, sizeof(struct acpi_table_desc)); + + /* + * Check the table signature and make sure it is recognized. + * Also checks the header checksum + */ + table_info->pointer = &header; + status = acpi_tb_recognize_table(table_info, ACPI_TABLE_PRIMARY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body(address, &header, table_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Install the table */ + + status = acpi_tb_install_table(table_info); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_secondary_table + * + * PARAMETERS: Address - Physical address of table to retrieve + * *table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Maps the physical address of table into a logical address + * + ******************************************************************************/ + +static acpi_status +acpi_tb_get_secondary_table(struct acpi_pointer *address, + acpi_string signature, + struct acpi_table_desc *table_info) +{ + acpi_status status; + struct acpi_table_header header; + + ACPI_FUNCTION_TRACE_STR(tb_get_secondary_table, signature); + + /* Get the header in order to match the signature */ + + status = acpi_tb_get_table_header(address, &header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Signature must match request */ + + if (!ACPI_COMPARE_NAME(header.signature, signature)) { + ACPI_ERROR((AE_INFO, + "Incorrect table signature - wanted [%s] found [%4.4s]", + signature, header.signature)); + return_ACPI_STATUS(AE_BAD_SIGNATURE); + } + + /* + * Check the table signature and make sure it is recognized. + * Also checks the header checksum + */ + table_info->pointer = &header; + status = acpi_tb_recognize_table(table_info, ACPI_TABLE_SECONDARY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the entire table */ + + status = acpi_tb_get_table_body(address, &header, table_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Install the table */ + + status = acpi_tb_install_table(table_info); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_required_tables + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must + * already be loaded and validated. + * + * Get the minimum set of ACPI tables, namely: + * + * 1) FADT (via RSDT in loop below) + * 2) FACS (via FADT) + * 3) DSDT (via FADT) + * + ******************************************************************************/ + +acpi_status acpi_tb_get_required_tables(void) +{ + acpi_status status = AE_OK; + u32 i; + struct acpi_table_desc table_info; + struct acpi_pointer address; + + ACPI_FUNCTION_TRACE(tb_get_required_tables); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n", + acpi_gbl_rsdt_table_count)); + + address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; + + /* + * Loop through all table pointers found in RSDT. + * This will NOT include the FACS and DSDT - we must get + * them after the loop. + * + * The only tables we are interested in getting here is the FADT and + * any SSDTs. + */ + for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { + + /* Get the table address from the common internal XSDT */ + + address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i]; + + /* + * Get the tables needed by this subsystem (FADT and any SSDTs). + * NOTE: All other tables are completely ignored at this time. + */ + status = acpi_tb_get_primary_table(&address, &table_info); + if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { + ACPI_WARNING((AE_INFO, + "%s, while getting table at %8.8X%8.8X", + acpi_format_exception(status), + ACPI_FORMAT_UINT64(address.pointer. + value))); + } + } + + /* We must have a FADT to continue */ + + if (!acpi_gbl_FADT) { + ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* + * Convert the FADT to a common format. This allows earlier revisions of + * the table to coexist with newer versions, using common access code. + */ + status = acpi_tb_convert_table_fadt(); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not convert FADT to internal common format")); + return_ACPI_STATUS(status); + } + + /* Get the FACS (Pointed to by the FADT) */ + + address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl; + + status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get/install the FACS")); + return_ACPI_STATUS(status); + } + + /* + * Create the common FACS pointer table + * (Contains pointers to the original table) + */ + status = acpi_tb_build_common_facs(&table_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get/install the DSDT (Pointed to by the FADT) */ + + address.pointer.value = acpi_gbl_FADT->Xdsdt; + + status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, "Could not get/install the DSDT")); + return_ACPI_STATUS(status); + } + + /* Set Integer Width (32/64) based upon DSDT revision */ + + acpi_ut_set_integer_width(acpi_gbl_DSDT->revision); + + /* Dump the entire DSDT */ + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, + "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n", + acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, + acpi_gbl_integer_bit_width)); + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT), + acpi_gbl_DSDT->length); + + /* Always delete the RSDP mapping, we are done with it */ + + acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_RSDP); + return_ACPI_STATUS(status); +} diff --git a/trunk/drivers/acpi/tables/tbinstal.c b/trunk/drivers/acpi/tables/tbinstal.c index 0e7b121a99ce..1668a232fb67 100644 --- a/trunk/drivers/acpi/tables/tbinstal.c +++ b/trunk/drivers/acpi/tables/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,498 +42,510 @@ */ #include -#include #include #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbinstal") -/****************************************************************************** +/* Local prototypes */ +static acpi_status +acpi_tb_match_signature(char *signature, + struct acpi_table_desc *table_info, u8 search_type); + +/******************************************************************************* * - * FUNCTION: acpi_tb_verify_table + * FUNCTION: acpi_tb_match_signature * - * PARAMETERS: table_desc - table + * PARAMETERS: Signature - Table signature to match + * table_info - Return data + * search_type - Table type to match (primary/secondary) * * RETURN: Status * - * DESCRIPTION: this function is called to verify and map table + * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" + * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match. * - *****************************************************************************/ -acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) + ******************************************************************************/ + +static acpi_status +acpi_tb_match_signature(char *signature, + struct acpi_table_desc *table_info, u8 search_type) { - acpi_status status = AE_OK; + acpi_native_uint i; - ACPI_FUNCTION_TRACE(tb_verify_table); + ACPI_FUNCTION_TRACE(tb_match_signature); - /* Map the table if necessary */ + /* Search for a signature match among the known table types */ - 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); + for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + if (!(acpi_gbl_table_data[i].flags & search_type)) { + continue; } - } - /* FACS is the odd table, has no standard ACPI header and no checksum */ + if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, + acpi_gbl_table_data[i].sig_length)) { + + /* Found a signature match, return index if requested */ - if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { + if (table_info) { + table_info->type = (u8) i; + } - /* Always calculate checksum, ignore bad checksum if requested */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", + (char *)acpi_gbl_table_data[i]. + signature)); - status = - acpi_tb_verify_checksum(table_desc->pointer, - table_desc->length); + return_ACPI_STATUS(AE_OK); + } } - return_ACPI_STATUS(status); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", + (char *)signature)); + + return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED); } /******************************************************************************* * - * FUNCTION: acpi_tb_add_table + * FUNCTION: acpi_tb_install_table * - * PARAMETERS: table_desc - Table descriptor - * table_index - Where the table index is returned + * PARAMETERS: table_info - Return value from acpi_tb_get_table_body * * RETURN: Status * - * DESCRIPTION: This function is called to add the ACPI table + * DESCRIPTION: Install the table into the global data structures. * ******************************************************************************/ -acpi_status -acpi_tb_add_table(struct acpi_table_desc *table_desc, - acpi_native_uint * table_index) +acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) { - acpi_native_uint i; - acpi_native_uint length; - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE(tb_add_table); + acpi_status status; - if (!table_desc->pointer) { - status = acpi_tb_verify_table(table_desc); - if (ACPI_FAILURE(status) || !table_desc->pointer) { - return_ACPI_STATUS(status); - } - } - - /* The table must be either an SSDT or a PSDT */ - - if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) - && - (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))) - { - ACPI_ERROR((AE_INFO, - "Table has invalid signature [%4.4s], must be SSDT or PSDT", - table_desc->pointer->signature)); - return_ACPI_STATUS(AE_BAD_SIGNATURE); - } + ACPI_FUNCTION_TRACE(tb_install_table); - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + /* Lock tables while installing */ - /* Check if table is already registered */ - - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if (!acpi_gbl_root_table_list.tables[i].pointer) { - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[i]); - if (ACPI_FAILURE(status) - || !acpi_gbl_root_table_list.tables[i].pointer) { - continue; - } - } - - length = ACPI_MIN(table_desc->length, - acpi_gbl_root_table_list.tables[i].length); - if (ACPI_MEMCMP(table_desc->pointer, - acpi_gbl_root_table_list.tables[i].pointer, - length)) { - continue; - } - - /* Table is already registered */ - - acpi_tb_delete_table(table_desc); - *table_index = i; - goto release; + status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not acquire table mutex")); + return_ACPI_STATUS(status); } /* - * Add the table to the global table list + * Ignore a table that is already installed. For example, some BIOS + * ASL code will repeatedly attempt to load the same SSDT. */ - status = acpi_tb_store_table(table_desc->address, table_desc->pointer, - table_desc->length, table_desc->flags, - table_index); + status = acpi_tb_is_table_installed(table_info); + if (ACPI_FAILURE(status)) { + goto unlock_and_exit; + } + + /* Install the table into the global data structure */ + + status = acpi_tb_init_table_descriptor(table_info->type, table_info); if (ACPI_FAILURE(status)) { - goto release; + ACPI_EXCEPTION((AE_INFO, status, + "Could not install table [%4.4s]", + table_info->pointer->signature)); } - acpi_tb_print_table_header(table_desc->address, table_desc->pointer); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", + acpi_gbl_table_data[table_info->type].name, + table_info->pointer)); - release: + unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_tb_resize_root_table_list + * FUNCTION: acpi_tb_recognize_table * - * PARAMETERS: None + * PARAMETERS: table_info - Return value from acpi_tb_get_table_body + * search_type - Table type to match (primary/secondary) * * RETURN: Status * - * DESCRIPTION: Expand the size of global table array + * DESCRIPTION: Check a table signature for a match against known table types + * + * NOTE: All table pointers are validated as follows: + * 1) Table pointer must point to valid physical memory + * 2) Signature must be 4 ASCII chars, even if we don't recognize the + * name + * 3) Table must be readable for length specified in the header + * 4) Table checksum must be valid (with the exception of the FACS + * which has no checksum for some odd reason) * ******************************************************************************/ -acpi_status acpi_tb_resize_root_table_list(void) +acpi_status +acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type) { - struct acpi_table_desc *tables; + struct acpi_table_header *table_header; + acpi_status status; - ACPI_FUNCTION_TRACE(tb_resize_root_table_list); + ACPI_FUNCTION_TRACE(tb_recognize_table); - /* allow_resize flag is a parameter to acpi_initialize_tables */ + /* Ensure that we have a valid table pointer */ - 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); + table_header = (struct acpi_table_header *)table_info->pointer; + if (!table_header) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* 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); + /* + * We only "recognize" a limited number of ACPI tables -- namely, the + * ones that are used by the subsystem (DSDT, FADT, etc.) + * + * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. + * This can be any one of many valid ACPI tables, it just isn't one of + * the tables that is consumed by the core subsystem + */ + status = acpi_tb_match_signature(table_header->signature, + table_info, search_type); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* 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); - } + status = acpi_tb_validate_table_header(table_header); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - 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 the table type and length via the info struct */ - return_ACPI_STATUS(AE_OK); + table_info->length = (acpi_size) table_header->length; + return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_tb_store_table + * FUNCTION: acpi_tb_init_table_descriptor * - * PARAMETERS: Address - Table address - * Table - Table header - * Length - Table length - * Flags - flags + * PARAMETERS: table_type - The type of the table + * table_info - A table info struct * - * RETURN: Status and table index. + * RETURN: None. * - * DESCRIPTION: Add an ACPI table to the global table list + * DESCRIPTION: Install a table into the global data structs. * ******************************************************************************/ acpi_status -acpi_tb_store_table(acpi_physical_address address, - struct acpi_table_header *table, - u32 length, u8 flags, acpi_native_uint * table_index) +acpi_tb_init_table_descriptor(acpi_table_type table_type, + struct acpi_table_desc *table_info) { - acpi_status status = AE_OK; + struct acpi_table_list *list_head; + struct acpi_table_desc *table_desc; + acpi_status status; - /* Ensure that there is room for the table in the Root Table List */ + ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type); - if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { - status = acpi_tb_resize_root_table_list(); - if (ACPI_FAILURE(status)) { - return (status); - } + /* Allocate a descriptor for this table */ + + table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); + if (!table_desc) { + return_ACPI_STATUS(AE_NO_MEMORY); } - /* Initialize added table */ - - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. - address = address; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. - pointer = table; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = - length; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. - owner_id = 0; - acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = - flags; - - ACPI_MOVE_32_TO_32(& - (acpi_gbl_root_table_list. - tables[acpi_gbl_root_table_list.count].signature), - table->signature); - - *table_index = acpi_gbl_root_table_list.count; - acpi_gbl_root_table_list.count++; - return (status); -} + /* Get a new owner ID for the table */ -/******************************************************************************* - * - * FUNCTION: acpi_tb_delete_table - * - * PARAMETERS: table_index - Table index - * - * RETURN: None - * - * DESCRIPTION: Delete one internal ACPI table - * - ******************************************************************************/ - -void acpi_tb_delete_table(struct acpi_table_desc *table_desc) -{ - /* Table must be mapped or allocated */ - if (!table_desc->pointer) { - return; - } - switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { - case ACPI_TABLE_ORIGIN_MAPPED: - acpi_os_unmap_memory(table_desc->pointer, table_desc->length); - break; - case ACPI_TABLE_ORIGIN_ALLOCATED: - ACPI_FREE(table_desc->pointer); - break; - default:; + status = acpi_ut_allocate_owner_id(&table_desc->owner_id); + if (ACPI_FAILURE(status)) { + goto error_exit1; } - table_desc->pointer = NULL; -} + /* Install the table into the global data structure */ -/******************************************************************************* - * - * FUNCTION: acpi_tb_terminate - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Delete all internal ACPI tables - * - ******************************************************************************/ + list_head = &acpi_gbl_table_lists[table_type]; -void acpi_tb_terminate(void) -{ - acpi_native_uint i; + /* + * Two major types of tables: 1) Only one instance is allowed. This + * includes most ACPI tables such as the DSDT. 2) Multiple instances of + * the table are allowed. This includes SSDT and PSDTs. + */ + if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { + /* + * Only one table allowed, and a table has alread been installed + * at this location, so return an error. + */ + if (list_head->next) { + status = AE_ALREADY_EXISTS; + goto error_exit2; + } - ACPI_FUNCTION_TRACE(tb_terminate); + table_desc->next = list_head->next; + list_head->next = table_desc; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (table_desc->next) { + table_desc->next->prev = table_desc; + } - /* Delete the individual tables */ + list_head->count++; + } else { + /* + * Link the new table in to the list of tables of this type. + * Insert at the end of the list, order IS IMPORTANT. + * + * table_desc->Prev & Next are already NULL from calloc() + */ + list_head->count++; + + if (!list_head->next) { + list_head->next = table_desc; + } else { + table_desc->next = list_head->next; + + while (table_desc->next->next) { + table_desc->next = table_desc->next->next; + } - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); + table_desc->next->next = table_desc; + table_desc->prev = table_desc->next; + table_desc->next = NULL; + } } + /* Finish initialization of the table descriptor */ + + table_desc->loaded_into_namespace = FALSE; + table_desc->type = (u8) table_type; + table_desc->pointer = table_info->pointer; + table_desc->length = table_info->length; + table_desc->allocation = table_info->allocation; + table_desc->aml_start = (u8 *) (table_desc->pointer + 1), + table_desc->aml_length = (u32) + (table_desc->length - (u32) sizeof(struct acpi_table_header)); + /* - * Delete the root table array if allocated locally. Array cannot be - * mapped, so we don't need to check for that flag. + * Set the appropriate global pointer (if there is one) to point to the + * newly installed table */ - if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { - ACPI_FREE(acpi_gbl_root_table_list.tables); + if (acpi_gbl_table_data[table_type].global_ptr) { + *(acpi_gbl_table_data[table_type].global_ptr) = + table_info->pointer; } - acpi_gbl_root_table_list.tables = NULL; - acpi_gbl_root_table_list.flags = 0; - acpi_gbl_root_table_list.count = 0; + /* Return Data */ - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + table_info->owner_id = table_desc->owner_id; + table_info->installed_desc = table_desc; + return_ACPI_STATUS(AE_OK); + + /* Error exit with cleanup */ + + error_exit2: + + acpi_ut_release_owner_id(&table_desc->owner_id); + + error_exit1: + + ACPI_FREE(table_desc); + return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_tb_delete_namespace_by_owner + * FUNCTION: acpi_tb_delete_all_tables * - * PARAMETERS: table_index - Table index + * PARAMETERS: None. * - * RETURN: None + * RETURN: None. * - * DESCRIPTION: Delete all namespace objects created when this table was loaded. + * DESCRIPTION: Delete all internal ACPI tables * ******************************************************************************/ -void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) +void acpi_tb_delete_all_tables(void) { - acpi_owner_id owner_id; + acpi_table_type type; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - owner_id = - acpi_gbl_root_table_list.tables[table_index].owner_id; - } else { - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return; + /* + * Free memory allocated for ACPI tables + * Memory can either be mapped or allocated + */ + for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { + acpi_tb_delete_tables_by_type(type); } - - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - acpi_ns_delete_namespace_by_owner(owner_id); } /******************************************************************************* * - * FUNCTION: acpi_tb_allocate_owner_id + * FUNCTION: acpi_tb_delete_tables_by_type * - * PARAMETERS: table_index - Table index + * PARAMETERS: Type - The table type to be deleted * - * RETURN: Status + * RETURN: None. * - * DESCRIPTION: Allocates owner_id in table_desc + * DESCRIPTION: Delete an internal ACPI table + * Locks the ACPI table mutex * ******************************************************************************/ -acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) +void acpi_tb_delete_tables_by_type(acpi_table_type type) { - acpi_status status = AE_BAD_PARAMETER; + struct acpi_table_desc *table_desc; + u32 count; + u32 i; - ACPI_FUNCTION_TRACE(tb_allocate_owner_id); + ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type); - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - status = acpi_ut_allocate_owner_id - (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); + if (type > ACPI_TABLE_ID_MAX) { + return_VOID; } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); -} + if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) { + return; + } -/******************************************************************************* - * - * FUNCTION: acpi_tb_release_owner_id - * - * PARAMETERS: table_index - Table index - * - * RETURN: Status - * - * DESCRIPTION: Releases owner_id in table_desc - * - ******************************************************************************/ + /* Clear the appropriate "typed" global table pointer */ -acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) -{ - acpi_status status = AE_BAD_PARAMETER; + switch (type) { + case ACPI_TABLE_ID_RSDP: + acpi_gbl_RSDP = NULL; + break; + + case ACPI_TABLE_ID_DSDT: + acpi_gbl_DSDT = NULL; + break; - ACPI_FUNCTION_TRACE(tb_release_owner_id); + case ACPI_TABLE_ID_FADT: + acpi_gbl_FADT = NULL; + break; + + case ACPI_TABLE_ID_FACS: + acpi_gbl_FACS = NULL; + break; + + case ACPI_TABLE_ID_XSDT: + acpi_gbl_XSDT = NULL; + break; + + case ACPI_TABLE_ID_SSDT: + case ACPI_TABLE_ID_PSDT: + default: + break; + } + + /* + * Free the table + * 1) Get the head of the list + */ + table_desc = acpi_gbl_table_lists[type].next; + count = acpi_gbl_table_lists[type].count; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - acpi_ut_release_owner_id(& - (acpi_gbl_root_table_list. - tables[table_index].owner_id)); - status = AE_OK; + /* + * 2) Walk the entire list, deleting both the allocated tables + * and the table descriptors + */ + for (i = 0; i < count; i++) { + table_desc = acpi_tb_uninstall_table(table_desc); } (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); + return_VOID; } /******************************************************************************* * - * FUNCTION: acpi_tb_get_owner_id + * FUNCTION: acpi_tb_delete_single_table * - * PARAMETERS: table_index - Table index - * owner_id - Where the table owner_id is returned + * PARAMETERS: table_info - A table info struct * - * RETURN: Status + * RETURN: None. * - * DESCRIPTION: returns owner_id for the ACPI table + * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where + * the table was allocated a buffer or was mapped. * ******************************************************************************/ -acpi_status -acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) +void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) { - acpi_status status = AE_BAD_PARAMETER; - ACPI_FUNCTION_TRACE(tb_get_owner_id); + /* Must have a valid table descriptor and pointer */ - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - *owner_id = - acpi_gbl_root_table_list.tables[table_index].owner_id; - status = AE_OK; + if ((!table_desc) || (!table_desc->pointer)) { + return; } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); -} + /* Valid table, determine type of memory allocation */ -/******************************************************************************* - * - * FUNCTION: acpi_tb_is_table_loaded - * - * PARAMETERS: table_index - Table index - * - * RETURN: Table Loaded Flag - * - ******************************************************************************/ + switch (table_desc->allocation) { + case ACPI_MEM_NOT_ALLOCATED: + break; -u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) -{ - u8 is_loaded = FALSE; + case ACPI_MEM_ALLOCATED: - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - is_loaded = (u8) - (acpi_gbl_root_table_list.tables[table_index]. - flags & ACPI_TABLE_IS_LOADED); - } + ACPI_FREE(table_desc->pointer); + break; - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return (is_loaded); + case ACPI_MEM_MAPPED: + + acpi_os_unmap_memory(table_desc->pointer, table_desc->length); + break; + + default: + break; + } } /******************************************************************************* * - * FUNCTION: acpi_tb_set_table_loaded_flag + * FUNCTION: acpi_tb_uninstall_table * - * PARAMETERS: table_index - Table index - * is_loaded - TRUE if table is loaded, FALSE otherwise + * PARAMETERS: table_info - A table info struct * - * RETURN: None + * RETURN: Pointer to the next table in the list (of same type) * - * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. + * DESCRIPTION: Free the memory associated with an internal ACPI table that + * is either installed or has never been installed. + * Table mutex should be locked. * ******************************************************************************/ -void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded) +struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc + *table_desc) { + struct acpi_table_desc *next_desc; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (table_index < acpi_gbl_root_table_list.count) { - if (is_loaded) { - acpi_gbl_root_table_list.tables[table_index].flags |= - ACPI_TABLE_IS_LOADED; - } else { - acpi_gbl_root_table_list.tables[table_index].flags &= - ~ACPI_TABLE_IS_LOADED; - } + ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); + + if (!table_desc) { + return_PTR(NULL); } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + /* Unlink the descriptor from the doubly linked list */ + + if (table_desc->prev) { + table_desc->prev->next = table_desc->next; + } else { + /* Is first on list, update list head */ + + acpi_gbl_table_lists[table_desc->type].next = table_desc->next; + } + + if (table_desc->next) { + table_desc->next->prev = table_desc->prev; + } + + /* Free the memory allocated for the table itself */ + + acpi_tb_delete_single_table(table_desc); + + /* Free the owner ID associated with this table */ + + acpi_ut_release_owner_id(&table_desc->owner_id); + + /* Free the table descriptor */ + + next_desc = table_desc->next; + ACPI_FREE(table_desc); + + /* Return pointer to the next descriptor */ + + return_PTR(next_desc); } diff --git a/trunk/drivers/acpi/tables/tbrsdt.c b/trunk/drivers/acpi/tables/tbrsdt.c new file mode 100644 index 000000000000..86a5fca9b739 --- /dev/null +++ b/trunk/drivers/acpi/tables/tbrsdt.c @@ -0,0 +1,307 @@ +/****************************************************************************** + * + * Module Name: tbrsdt - ACPI RSDT table utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, 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. + */ + +#include +#include + +#define _COMPONENT ACPI_TABLES +ACPI_MODULE_NAME("tbrsdt") + +/******************************************************************************* + * + * FUNCTION: acpi_tb_verify_rsdp + * + * PARAMETERS: Address - RSDP (Pointer to RSDT) + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ +acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) +{ + struct acpi_table_desc table_info; + acpi_status status; + struct rsdp_descriptor *rsdp; + + ACPI_FUNCTION_TRACE(tb_verify_rsdp); + + switch (address->pointer_type) { + case ACPI_LOGICAL_POINTER: + + rsdp = address->pointer.logical; + break; + + case ACPI_PHYSICAL_POINTER: + /* + * Obtain access to the RSDP structure + */ + status = acpi_os_map_memory(address->pointer.physical, + sizeof(struct rsdp_descriptor), + ACPI_CAST_PTR(void, &rsdp)); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + break; + + default: + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Verify RSDP signature and checksum */ + + status = acpi_tb_validate_rsdp(rsdp); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* RSDP is ok. Init the table info */ + + table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); + table_info.length = sizeof(struct rsdp_descriptor); + + if (address->pointer_type == ACPI_PHYSICAL_POINTER) { + table_info.allocation = ACPI_MEM_MAPPED; + } else { + table_info.allocation = ACPI_MEM_NOT_ALLOCATED; + } + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* Save the RSDP in a global for easy access */ + + acpi_gbl_RSDP = + ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer); + return_ACPI_STATUS(status); + + /* Error exit */ + cleanup: + + if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { + acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor)); + } + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_rsdt_address + * + * PARAMETERS: out_address - Where the address is returned + * + * RETURN: None, Address + * + * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the + * version of the RSDP and whether the XSDT pointer is valid + * + ******************************************************************************/ + +void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address) +{ + + ACPI_FUNCTION_ENTRY(); + + out_address->pointer_type = + acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; + + /* Use XSDT if it is present */ + + if ((acpi_gbl_RSDP->revision >= 2) && + acpi_gbl_RSDP->xsdt_physical_address) { + out_address->pointer.value = + acpi_gbl_RSDP->xsdt_physical_address; + acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT; + } else { + /* No XSDT, use the RSDT */ + + out_address->pointer.value = + acpi_gbl_RSDP->rsdt_physical_address; + acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_validate_rsdt + * + * PARAMETERS: table_ptr - Addressable pointer to the RSDT. + * + * RETURN: Status + * + * DESCRIPTION: Validate signature for the RSDT or XSDT + * + ******************************************************************************/ + +acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) +{ + char *signature; + + ACPI_FUNCTION_ENTRY(); + + /* Validate minimum length */ + + if (table_ptr->length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, + "RSDT/XSDT length (%X) is smaller than minimum (%zX)", + table_ptr->length, + sizeof(struct acpi_table_header))); + + return (AE_INVALID_TABLE_LENGTH); + } + + /* Search for appropriate signature, RSDT or XSDT */ + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + signature = RSDT_SIG; + } else { + signature = XSDT_SIG; + } + + if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) { + + /* Invalid RSDT or XSDT signature */ + + ACPI_ERROR((AE_INFO, + "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:")); + + ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); + + ACPI_ERROR((AE_INFO, + "RSDT/XSDT signature at %X is invalid", + acpi_gbl_RSDP->rsdt_physical_address)); + + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + ACPI_ERROR((AE_INFO, "Looking for RSDT")); + } else { + ACPI_ERROR((AE_INFO, "Looking for XSDT")); + } + + ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48); + return (AE_BAD_SIGNATURE); + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_get_table_rsdt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +acpi_status acpi_tb_get_table_rsdt(void) +{ + struct acpi_table_desc table_info; + acpi_status status; + struct acpi_pointer address; + + ACPI_FUNCTION_TRACE(tb_get_table_rsdt); + + /* Get the RSDT/XSDT via the RSDP */ + + acpi_tb_get_rsdt_address(&address); + + table_info.type = ACPI_TABLE_ID_XSDT; + status = acpi_tb_get_table(&address, &table_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get the RSDT/XSDT")); + return_ACPI_STATUS(status); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n", + acpi_gbl_RSDP, + ACPI_FORMAT_UINT64(address.pointer.value))); + + /* Check the RSDT or XSDT signature */ + + status = acpi_tb_validate_rsdt(table_info.pointer); + if (ACPI_FAILURE(status)) { + goto error_cleanup; + } + + /* Get the number of tables defined in the RSDT or XSDT */ + + acpi_gbl_rsdt_table_count = acpi_tb_get_table_count(acpi_gbl_RSDP, + table_info.pointer); + + /* Convert and/or copy to an XSDT structure */ + + status = acpi_tb_convert_to_xsdt(&table_info); + if (ACPI_FAILURE(status)) { + goto error_cleanup; + } + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); + if (ACPI_FAILURE(status)) { + goto error_cleanup; + } + + acpi_gbl_XSDT = + ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); + return_ACPI_STATUS(status); + + error_cleanup: + + /* Free table allocated by acpi_tb_get_table */ + + acpi_tb_delete_single_table(&table_info); + + return_ACPI_STATUS(status); +} diff --git a/trunk/drivers/acpi/tables/tbutils.c b/trunk/drivers/acpi/tables/tbutils.c index 4a2f99e2fc44..209a401801e3 100644 --- a/trunk/drivers/acpi/tables/tbutils.c +++ b/trunk/drivers/acpi/tables/tbutils.c @@ -1,11 +1,11 @@ /****************************************************************************** * - * Module Name: tbutils - table utilities + * Module Name: tbutils - Table manipulation utilities * *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,119 +48,137 @@ 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); +#ifdef ACPI_OBSOLETE_FUNCTIONS +acpi_status +acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc); +#endif /******************************************************************************* * - * FUNCTION: acpi_tb_tables_loaded + * FUNCTION: acpi_tb_is_table_installed + * + * PARAMETERS: new_table_desc - Descriptor for new table being installed * - * PARAMETERS: None + * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed * - * RETURN: TRUE if required ACPI tables are loaded + * DESCRIPTION: Determine if an ACPI table is already installed * - * DESCRIPTION: Determine if the minimum required ACPI tables are present - * (FADT, FACS, DSDT) + * MUTEX: Table data structures should be locked * ******************************************************************************/ -u8 acpi_tb_tables_loaded(void) +acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) { + struct acpi_table_desc *table_desc; - if (acpi_gbl_root_table_list.count >= 3) { - return (TRUE); - } + ACPI_FUNCTION_TRACE(tb_is_table_installed); - return (FALSE); -} + /* Get the list descriptor and first table descriptor */ -/******************************************************************************* - * - * 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. - * - ******************************************************************************/ + table_desc = acpi_gbl_table_lists[new_table_desc->type].next; -void -acpi_tb_print_table_header(acpi_physical_address address, - struct acpi_table_header *header) -{ + /* Examine all installed tables of this type */ - 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 @ 0x%p/0x%04X", - header->signature, ACPI_CAST_PTR(void, address), - header->length)); - } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { - - /* RSDP has no common fields */ - - ACPI_INFO((AE_INFO, "RSDP @ 0x%p/0x%04X (v%3.3d %6.6s)", - ACPI_CAST_PTR(void, 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 @ 0x%p/0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)", - header->signature, ACPI_CAST_PTR(void, address), - header->length, header->revision, header->oem_id, - header->oem_table_id, header->oem_revision, - header->asl_compiler_id, - header->asl_compiler_revision)); + while (table_desc) { + /* + * If the table lengths match, perform a full bytewise compare. This + * means that we will allow tables with duplicate oem_table_id(s), as + * long as the tables are different in some way. + * + * Checking if the table has been loaded into the namespace means that + * we don't check for duplicate tables during the initial installation + * of tables within the RSDT/XSDT. + */ + if ((table_desc->loaded_into_namespace) && + (table_desc->pointer->length == + new_table_desc->pointer->length) + && + (!ACPI_MEMCMP + (table_desc->pointer, new_table_desc->pointer, + new_table_desc->pointer->length))) { + + /* Match: this table is already installed */ + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, + "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", + new_table_desc->pointer->signature, + new_table_desc->pointer->revision, + new_table_desc->pointer-> + oem_table_id)); + + new_table_desc->owner_id = table_desc->owner_id; + new_table_desc->installed_desc = table_desc; + + return_ACPI_STATUS(AE_ALREADY_EXISTS); + } + + /* Get next table on the list */ + + table_desc = table_desc->next; } + + return_ACPI_STATUS(AE_OK); } /******************************************************************************* * - * FUNCTION: acpi_tb_validate_checksum + * FUNCTION: acpi_tb_validate_table_header * - * PARAMETERS: Table - ACPI table to verify - * Length - Length of entire table + * PARAMETERS: table_header - Logical pointer to the table * * RETURN: Status * - * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns - * exception on bad checksum. + * DESCRIPTION: Check an ACPI table header for validity + * + * NOTE: Table pointers are validated as follows: + * 1) Table pointer must point to valid physical memory + * 2) Signature must be 4 ASCII chars, even if we don't recognize the + * name + * 3) Table must be readable for length specified in the header + * 4) Table checksum must be valid (with the exception of the FACS + * which has no checksum because it contains variable fields) * ******************************************************************************/ -acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) +acpi_status +acpi_tb_validate_table_header(struct acpi_table_header *table_header) { - u8 checksum; + acpi_name signature; - /* Compute the checksum on the table */ + ACPI_FUNCTION_ENTRY(); + + /* Verify that this is a valid address */ - checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); + if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { + ACPI_ERROR((AE_INFO, + "Cannot read table header at %p", table_header)); + + return (AE_BAD_ADDRESS); + } - /* Checksum ok? (should be zero) */ + /* Ensure that the signature is 4 ASCII characters */ - 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))); + ACPI_MOVE_32_TO_32(&signature, table_header->signature); + if (!acpi_ut_valid_acpi_name(signature)) { + ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", + signature)); -#if (ACPI_CHECKSUM_ABORT) + ACPI_DUMP_BUFFER(table_header, + sizeof(struct acpi_table_header)); + return (AE_BAD_SIGNATURE); + } - return (AE_BAD_CHECKSUM); -#endif + /* Validate the table length */ + + if (table_header->length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, + "Invalid length 0x%X in table with signature %4.4s", + (u32) table_header->length, + ACPI_CAST_PTR(char, &signature))); + + ACPI_DUMP_BUFFER(table_header, + sizeof(struct acpi_table_header)); + return (AE_BAD_HEADER); } return (AE_OK); @@ -168,320 +186,157 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) /******************************************************************************* * - * FUNCTION: acpi_tb_checksum + * FUNCTION: acpi_tb_sum_table * - * PARAMETERS: Buffer - Pointer to memory region to be checked - * Length - Length of this memory region + * PARAMETERS: Buffer - Buffer to sum + * Length - Size of the buffer * - * RETURN: Checksum (u8) + * RETURN: 8 bit sum of buffer * - * DESCRIPTION: Calculates circular checksum of memory region. + * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. * ******************************************************************************/ -u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) +u8 acpi_tb_sum_table(void *buffer, u32 length) { + acpi_native_uint i; u8 sum = 0; - u8 *end = buffer + length; - while (buffer < end) { - sum = (u8) (sum + *(buffer++)); + if (!buffer || !length) { + return (0); } - return sum; + for (i = 0; i < length; i++) { + sum = (u8) (sum + ((u8 *) buffer)[i]); + } + return (sum); } /******************************************************************************* * - * FUNCTION: acpi_tb_install_table + * FUNCTION: acpi_tb_generate_checksum * - * 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 + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) * - * RETURN: None + * RETURN: 8 bit checksum of buffer * - * DESCRIPTION: Install an ACPI table into the global data structure. + * DESCRIPTION: Computes an 8 bit checksum of the table. * ******************************************************************************/ -void -acpi_tb_install_table(acpi_physical_address address, - u8 flags, char *signature, acpi_native_uint table_index) +u8 acpi_tb_generate_checksum(struct acpi_table_header * table) { - 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; + u8 checksum; - ACPI_MOVE_32_TO_32(& - (acpi_gbl_root_table_list.tables[table_index]. - signature), table->signature); + /* Sum the entire table as-is */ - acpi_tb_print_table_header(address, table); + checksum = acpi_tb_sum_table(table, table->length); - if (table_index == ACPI_TABLE_INDEX_DSDT) { + /* Subtract off the existing checksum value in the table */ - /* Global integer width is based upon revision of the DSDT */ + checksum = (u8) (checksum - table->checksum); - acpi_ut_set_integer_width(table->revision); - } + /* Compute the final checksum */ - unmap_and_exit: - acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + checksum = (u8) (0 - checksum); + return (checksum); } /******************************************************************************* * - * FUNCTION: acpi_tb_get_root_table_entry + * FUNCTION: acpi_tb_set_checksum * - * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry - * table_entry_size - sizeof 32 or 64 (RSDT or XSDT) + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) * - * RETURN: Physical address extracted from the root table + * RETURN: None. Sets the table checksum field * - * 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. + * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the + * checksum into the table header. * ******************************************************************************/ -static acpi_physical_address -acpi_tb_get_root_table_entry(u8 * table_entry, - acpi_native_uint table_entry_size) +void acpi_tb_set_checksum(struct acpi_table_header *table) { - 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)); - } + table->checksum = acpi_tb_generate_checksum(table); } /******************************************************************************* * - * FUNCTION: acpi_tb_parse_root_table - * - * PARAMETERS: Rsdp - Pointer to the RSDP - * Flags - Flags + * FUNCTION: acpi_tb_verify_table_checksum * - * RETURN: Status + * PARAMETERS: *table_header - ACPI table to verify * - * DESCRIPTION: This function is called to parse the Root System Description - * Table (RSDT or XSDT) + * RETURN: 8 bit checksum of table * - * 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. + * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares + * it to the existing checksum value. * ******************************************************************************/ -acpi_status __init -acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) +acpi_status +acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) { - 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; - 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 */ + u8 checksum; - 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); - } else { - /* Root table is an RSDT (32-bit physical addresses) */ + ACPI_FUNCTION_TRACE(tb_verify_table_checksum); - address = (acpi_physical_address) rsdp->rsdt_physical_address; - table_entry_size = sizeof(u32); - } + /* Compute the checksum on the table */ - /* - * 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)); + checksum = acpi_tb_generate_checksum(table_header); - /* Map the RSDT/XSDT table header to get the full table length */ + /* Checksum ok? */ - table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); - if (!table) { - return_ACPI_STATUS(AE_NO_MEMORY); + if (checksum == table_header->checksum) { + return_ACPI_STATUS(AE_OK); } - acpi_tb_print_table_header(address, table); - - /* Get the length of the full table, verify length and map entire table */ + ACPI_WARNING((AE_INFO, + "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", + table_header->signature, table_header->checksum, + checksum)); - 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); - } + return_ACPI_STATUS(AE_BAD_CHECKSUM); +} - table = acpi_os_map_memory(address, length); - if (!table) { - return_ACPI_STATUS(AE_NO_MEMORY); - } +#ifdef ACPI_OBSOLETE_FUNCTIONS +/******************************************************************************* + * + * FUNCTION: acpi_tb_handle_to_object + * + * PARAMETERS: table_id - Id for which the function is searching + * table_desc - Pointer to return the matching table + * descriptor. + * + * RETURN: Search the tables to find one with a matching table_id and + * return a pointer to that table descriptor. + * + ******************************************************************************/ - /* Validate the root table checksum */ +acpi_status +acpi_tb_handle_to_object(u16 table_id, + struct acpi_table_desc **return_table_desc) +{ + u32 i; + struct acpi_table_desc *table_desc; - status = acpi_tb_verify_checksum(table, length); - if (ACPI_FAILURE(status)) { - acpi_os_unmap_memory(table, length); - return_ACPI_STATUS(status); - } + ACPI_FUNCTION_NAME(tb_handle_to_object); - /* 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; + for (i = 0; i < ACPI_TABLE_MAX; i++) { + table_desc = acpi_gbl_table_lists[i].next; + while (table_desc) { + if (table_desc->table_id == table_id) { + *return_table_desc = table_desc; + return (AE_OK); } - } - - /* 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); + table_desc = table_desc->next; } } - return_ACPI_STATUS(AE_OK); + ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); + return (AE_BAD_PARAMETER); } +#endif diff --git a/trunk/drivers/acpi/tables/tbxface.c b/trunk/drivers/acpi/tables/tbxface.c index 807978d5381a..5ba9303293ad 100644 --- a/trunk/drivers/acpi/tables/tbxface.c +++ b/trunk/drivers/acpi/tables/tbxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,158 +49,80 @@ #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbxface") -/* Local prototypes */ -static acpi_status acpi_tb_load_namespace(void); - /******************************************************************************* * - * FUNCTION: acpi_allocate_root_table + * FUNCTION: acpi_load_tables * - * PARAMETERS: initial_table_count - Size of initial_table_array, in number of - * struct acpi_table_desc structures + * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and - * acpi_initialize_tables. + * DESCRIPTION: This function is called to load the ACPI tables from the + * provided RSDT * ******************************************************************************/ - -acpi_status acpi_allocate_root_table(u32 initial_table_count) +acpi_status acpi_load_tables(void) { + struct acpi_pointer rsdp_address; + acpi_status status; - acpi_gbl_root_table_list.size = initial_table_count; - acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; + ACPI_FUNCTION_TRACE(acpi_load_tables); - return (acpi_tb_resize_root_table_list()); -} + /* Get the RSDP */ -/******************************************************************************* - * - * 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. - * - ******************************************************************************/ + status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, + &rsdp_address); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); + goto error_exit; + } -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; + /* Map and validate the RSDP */ - ACPI_FUNCTION_TRACE(acpi_initialize_tables); + acpi_gbl_table_flags = rsdp_address.pointer_type; - /* - * 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; - } + status = acpi_tb_verify_rsdp(&rsdp_address); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); + goto error_exit; } - /* Get the address of the RSDP */ + /* Get the RSDT via the RSDP */ - rsdp_address = acpi_os_get_root_pointer(); - if (!rsdp_address) { - return_ACPI_STATUS(AE_NOT_FOUND); + status = acpi_tb_get_table_rsdt(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); + goto error_exit; } - /* - * 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); + /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ - /* - * 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); + status = acpi_tb_get_required_tables(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not get all required tables (DSDT/FADT/FACS)")); + goto error_exit; } - new_size = - (acpi_gbl_root_table_list.count + - ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); + ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); - /* Create new array and copy the old array */ + /* Load the namespace from the tables */ - tables = ACPI_ALLOCATE_ZEROED(new_size); - if (!tables) { - return_ACPI_STATUS(AE_NO_MEMORY); + status = acpi_ns_load_namespace(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); + goto error_exit; } - 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); + + error_exit: + ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); + return_ACPI_STATUS(status); } + +ACPI_EXPORT_SYMBOL(acpi_load_tables) + /******************************************************************************* * * FUNCTION: acpi_load_table @@ -219,405 +141,342 @@ acpi_status acpi_reallocate_root_table(void) acpi_status acpi_load_table(struct acpi_table_header *table_ptr) { acpi_status status; - acpi_native_uint table_index; - struct acpi_table_desc table_desc; + struct acpi_table_desc table_info; + struct acpi_pointer address; - if (!table_ptr) - return AE_BAD_PARAMETER; + ACPI_FUNCTION_TRACE(acpi_load_table); - ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); - table_desc.pointer = table_ptr; - table_desc.length = table_ptr->length; - table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; + if (!table_ptr) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - /* - * Install the new table into the local data structures - */ - status = acpi_tb_add_table(&table_desc, &table_index); + /* Copy the table to a local buffer */ + + address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; + address.pointer.logical = table_ptr; + + status = acpi_tb_get_table_body(&address, table_ptr, &table_info); if (ACPI_FAILURE(status)) { - return status; + return_ACPI_STATUS(status); } - status = acpi_ns_load_table(table_index, acpi_gbl_root_node); - return status; -} -ACPI_EXPORT_SYMBOL(acpi_load_table) + /* Check signature for a valid table type */ -/****************************************************************************** - * - * FUNCTION: acpi_get_table_header - * - * PARAMETERS: Signature - ACPI signature of needed table - * Instance - Which instance (for SSDTs) - * out_table_header - The pointer to the table header to fill - * - * RETURN: Status and pointer to mapped table header - * - * DESCRIPTION: Finds an ACPI table header. - * - * NOTE: Caller is responsible in unmapping the header with - * acpi_os_unmap_memory - * - *****************************************************************************/ -acpi_status -acpi_get_table_header(char *signature, - acpi_native_uint instance, - struct acpi_table_header *out_table_header) -{ - acpi_native_uint i; - acpi_native_uint j; - struct acpi_table_header *header; + status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - /* Parameter validation */ + /* Install the new table into the local data structures */ - if (!signature || !out_table_header) { - return (AE_BAD_PARAMETER); - } + status = acpi_tb_install_table(&table_info); + if (ACPI_FAILURE(status)) { + if (status == AE_ALREADY_EXISTS) { - /* - * 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; - } + /* Table already exists, no error */ - if (++j < instance) { - continue; + status = AE_OK; } - if (!acpi_gbl_root_table_list.tables[i].pointer) { - if ((acpi_gbl_root_table_list.tables[i]. - flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) { - header = - acpi_os_map_memory(acpi_gbl_root_table_list. - tables[i].address, - sizeof(struct - acpi_table_header)); - if (!header) { - return AE_NO_MEMORY; - } - ACPI_MEMCPY(out_table_header, header, - sizeof(struct acpi_table_header)); - acpi_os_unmap_memory(header, - sizeof(struct - acpi_table_header)); - } else { - return AE_NOT_FOUND; - } - } else { - ACPI_MEMCPY(out_table_header, - acpi_gbl_root_table_list.tables[i].pointer, - sizeof(struct acpi_table_header)); - } - return (AE_OK); + /* Free table allocated by acpi_tb_get_table_body */ + + acpi_tb_delete_single_table(&table_info); + return_ACPI_STATUS(status); } - return (AE_NOT_FOUND); -} + /* Convert the table to common format if necessary */ -ACPI_EXPORT_SYMBOL(acpi_get_table_header) + switch (table_info.type) { + case ACPI_TABLE_ID_FADT: + status = acpi_tb_convert_table_fadt(); + break; -/****************************************************************************** + case ACPI_TABLE_ID_FACS: + + status = acpi_tb_build_common_facs(&table_info); + break; + + default: + /* Load table into namespace if it contains executable AML */ + + status = + acpi_ns_load_table(table_info.installed_desc, + acpi_gbl_root_node); + break; + } + + if (ACPI_FAILURE(status)) { + + /* Uninstall table and free the buffer */ + + (void)acpi_tb_uninstall_table(table_info.installed_desc); + } + + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_load_table) + +/******************************************************************************* * * FUNCTION: acpi_unload_table_id * - * PARAMETERS: id - Owner ID of the table to be removed. + * PARAMETERS: table_type - Type of table to be unloaded + * id - Owner ID of the table to be removed. * * RETURN: Status * * DESCRIPTION: This routine is used to force the unload of a table (by id) * ******************************************************************************/ -acpi_status acpi_unload_table_id(acpi_owner_id id) +acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) { - int i; - acpi_status status = AE_NOT_EXIST; + struct acpi_table_desc *table_desc; + acpi_status status; ACPI_FUNCTION_TRACE(acpi_unload_table); + /* Parameter validation */ + if (table_type > ACPI_TABLE_ID_MAX) + return_ACPI_STATUS(AE_BAD_PARAMETER); + /* Find table from the requested type list */ - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if (id != acpi_gbl_root_table_list.tables[i].owner_id) { - continue; - } - /* - * Delete all namespace objects owned by this table. Note that these - * objects can appear anywhere in the namespace by virtue of the AML - * "Scope" operator. Thus, we need to track ownership by an ID, not - * simply a position within the hierarchy - */ - acpi_tb_delete_namespace_by_owner(i); - acpi_tb_release_owner_id(i); - acpi_tb_set_table_loaded_flag(i, FALSE); - } - return_ACPI_STATUS(status); + table_desc = acpi_gbl_table_lists[table_type].next; + while (table_desc && table_desc->owner_id != id) + table_desc = table_desc->next; + + if (!table_desc) + return_ACPI_STATUS(AE_NOT_EXIST); + + /* + * Delete all namespace objects owned by this table. Note that these + * objects can appear anywhere in the namespace by virtue of the AML + * "Scope" operator. Thus, we need to track ownership by an ID, not + * simply a position within the hierarchy + */ + acpi_ns_delete_namespace_by_owner(table_desc->owner_id); + + status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + + (void)acpi_tb_uninstall_table(table_desc); + + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_unload_table_id) +#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * - * FUNCTION: acpi_get_table + * FUNCTION: acpi_unload_table * - * PARAMETERS: Signature - ACPI signature of needed table - * Instance - Which instance (for SSDTs) - * out_table - Where the pointer to the table is returned + * PARAMETERS: table_type - Type of table to be unloaded * - * RETURN: Status and pointer to table + * RETURN: Status * - * DESCRIPTION: Finds and verifies an ACPI table. + * DESCRIPTION: This routine is used to force the unload of a table * - *****************************************************************************/ -acpi_status -acpi_get_table(char *signature, - acpi_native_uint instance, struct acpi_table_header ** out_table) + ******************************************************************************/ +acpi_status acpi_unload_table(acpi_table_type table_type) { - acpi_native_uint i; - acpi_native_uint j; - acpi_status status; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE(acpi_unload_table); /* Parameter validation */ - if (!signature || !out_table) { - return (AE_BAD_PARAMETER); + if (table_type > ACPI_TABLE_ID_MAX) { + return_ACPI_STATUS(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; - } + /* Find all tables of the requested type */ - if (!acpi_gbl_permanent_mmap) { - acpi_gbl_root_table_list.tables[i].pointer = 0; - } + table_desc = acpi_gbl_table_lists[table_type].next; + if (!table_desc) { + return_ACPI_STATUS(AE_NOT_EXIST); + } - return (status); + while (table_desc) { + /* + * Delete all namespace objects owned by this table. Note that these + * objects can appear anywhere in the namespace by virtue of the AML + * "Scope" operator. Thus, we need to track ownership by an ID, not + * simply a position within the hierarchy + */ + acpi_ns_delete_namespace_by_owner(table_desc->owner_id); + table_desc = table_desc->next; } - return (AE_NOT_FOUND); + /* Delete (or unmap) all tables of this type */ + + acpi_tb_delete_tables_by_type(table_type); + return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_get_table) +ACPI_EXPORT_SYMBOL(acpi_unload_table) /******************************************************************************* * - * FUNCTION: acpi_get_table_by_index + * FUNCTION: acpi_get_table_header * - * PARAMETERS: table_index - Table index - * Table - Where the pointer to the table is returned + * PARAMETERS: table_type - one of the defined table types + * Instance - the non zero instance of the table, allows + * support for multiple tables of the same type + * see acpi_gbl_acpi_table_flag + * out_table_header - pointer to the struct acpi_table_header if successful * - * RETURN: Status and pointer to the table + * DESCRIPTION: This function is called to get an ACPI table header. The caller + * supplies an pointer to a data area sufficient to contain an ACPI + * struct acpi_table_header structure. * - * DESCRIPTION: Obtain a table by an index into the global table list. + * The header contains a length field that can be used to determine + * the size of the buffer needed to contain the entire table. This + * function is not valid for the RSD PTR table since it does not + * have a standard header and is fixed length. * ******************************************************************************/ acpi_status -acpi_get_table_by_index(acpi_native_uint table_index, - struct acpi_table_header ** table) +acpi_get_table_header(acpi_table_type table_type, + u32 instance, struct acpi_table_header *out_table_header) { + struct acpi_table_header *tbl_ptr; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_get_table_by_index); - - /* Parameter validation */ + ACPI_FUNCTION_TRACE(acpi_get_table_header); - if (!table) { + if ((instance == 0) || + (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - - /* Validate index */ + /* Check the table type and instance */ - if (table_index >= acpi_gbl_root_table_list.count) { - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + if ((table_type > ACPI_TABLE_ID_MAX) || + (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && + instance > 1)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - if (!acpi_gbl_root_table_list.tables[table_index].pointer) { + /* Get a pointer to the entire table */ - /* Table is not mapped, map it */ + status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[table_index]); - if (ACPI_FAILURE(status)) { - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); - } + /* The function will return a NULL pointer if the table is not loaded */ + + if (tbl_ptr == NULL) { + return_ACPI_STATUS(AE_NOT_EXIST); } - *table = acpi_gbl_root_table_list.tables[table_index].pointer; - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(AE_OK); + /* Copy the header to the caller's buffer */ + + ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), + ACPI_CAST_PTR(void, tbl_ptr), + sizeof(struct acpi_table_header)); + + return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) +ACPI_EXPORT_SYMBOL(acpi_get_table_header) +#endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* * - * FUNCTION: acpi_tb_load_namespace + * FUNCTION: acpi_get_table * - * PARAMETERS: None + * PARAMETERS: table_type - one of the defined table types + * Instance - the non zero instance of the table, allows + * support for multiple tables of the same type + * see acpi_gbl_acpi_table_flag + * ret_buffer - pointer to a structure containing a buffer to + * receive the table * * RETURN: Status * - * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in - * the RSDT/XSDT. + * DESCRIPTION: This function is called to get an ACPI table. The caller + * supplies an out_buffer large enough to contain the entire ACPI + * table. The caller should call the acpi_get_table_header function + * first to determine the buffer size needed. Upon completion + * the out_buffer->Length field will indicate the number of bytes + * copied into the out_buffer->buf_ptr buffer. This table will be + * a complete table including the header. * ******************************************************************************/ -static acpi_status acpi_tb_load_namespace(void) +acpi_status +acpi_get_table(acpi_table_type table_type, + u32 instance, struct acpi_buffer *ret_buffer) { + struct acpi_table_header *tbl_ptr; acpi_status status; - struct acpi_table_header *table; - acpi_native_uint i; - - ACPI_FUNCTION_TRACE(tb_load_namespace); + acpi_size table_length; - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + ACPI_FUNCTION_TRACE(acpi_get_table); - /* - * Load the namespace. The DSDT is required, but any SSDT and PSDT tables - * are optional. - */ - if (!acpi_gbl_root_table_list.count || - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT].signature), - ACPI_SIG_DSDT) - || - ACPI_FAILURE(acpi_tb_verify_table - (&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]))) { - status = AE_NO_ACPI_TABLES; - goto unlock_and_exit; - } + /* Parameter validation */ - /* - * Find DSDT table - */ - status = - acpi_os_table_override(acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT].pointer, - &table); - if (ACPI_SUCCESS(status) && table) { - /* - * DSDT table has been found - */ - acpi_tb_delete_table(&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]); - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = - table; - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = - table->length; - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = - ACPI_TABLE_ORIGIN_UNKNOWN; - - ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); - acpi_tb_print_table_header(0, table); + if (instance == 0) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = - acpi_tb_verify_table(&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]); + status = acpi_ut_validate_buffer(ret_buffer); if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - /* A valid DSDT is required */ + /* Check the table type and instance */ - status = AE_NO_ACPI_TABLES; - goto unlock_and_exit; + if ((table_type > ACPI_TABLE_ID_MAX) || + (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && + instance > 1)) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + /* Get a pointer to the entire table */ - /* - * Load and parse tables. - */ - status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); + status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* - * Load any SSDT or PSDT tables. Note: Loop leaves tables locked + * acpi_tb_get_table_ptr will return a NULL pointer if the + * table is not loaded. */ - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { - if ((!ACPI_COMPARE_NAME - (&(acpi_gbl_root_table_list.tables[i].signature), - ACPI_SIG_SSDT) - && - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list.tables[i]. - signature), ACPI_SIG_PSDT)) - || - ACPI_FAILURE(acpi_tb_verify_table - (&acpi_gbl_root_table_list.tables[i]))) { - continue; - } - - /* Ignore errors while loading tables, get as many as possible */ - - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - (void)acpi_ns_load_table(i, acpi_gbl_root_node); - (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (tbl_ptr == NULL) { + return_ACPI_STATUS(AE_NOT_EXIST); } - ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); + /* Get the table length */ - unlock_and_exit: - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); -} + if (table_type == ACPI_TABLE_ID_RSDP) { -/******************************************************************************* - * - * FUNCTION: acpi_load_tables - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT - * - ******************************************************************************/ + /* RSD PTR is the only "table" without a header */ -acpi_status acpi_load_tables(void) -{ - acpi_status status; + table_length = sizeof(struct rsdp_descriptor); + } else { + table_length = (acpi_size) tbl_ptr->length; + } - ACPI_FUNCTION_TRACE(acpi_load_tables); + /* Validate/Allocate/Clear caller buffer */ - /* - * Load the namespace from the tables - */ - status = acpi_tb_load_namespace(); + status = acpi_ut_initialize_buffer(ret_buffer, table_length); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "While loading namespace from ACPI tables")); + return_ACPI_STATUS(status); } - return_ACPI_STATUS(status); + /* Copy the table to the buffer */ + + ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer), + ACPI_CAST_PTR(void, tbl_ptr), table_length); + + return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_load_tables) +ACPI_EXPORT_SYMBOL(acpi_get_table) diff --git a/trunk/drivers/acpi/tables/tbxfroot.c b/trunk/drivers/acpi/tables/tbxfroot.c index cf8fa514189f..da2648bbdbc0 100644 --- a/trunk/drivers/acpi/tables/tbxfroot.c +++ b/trunk/drivers/acpi/tables/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,15 +48,16 @@ ACPI_MODULE_NAME("tbxfroot") /* Local prototypes */ -static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); +static acpi_status +acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags); -static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); +static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); /******************************************************************************* * * FUNCTION: acpi_tb_validate_rsdp * - * PARAMETERS: Rsdp - Pointer to unvalidated RSDP + * PARAMETERS: Rsdp - Pointer to unvalidated RSDP * * RETURN: Status * @@ -64,18 +65,14 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); * ******************************************************************************/ -static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) +acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *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. + * The signature and checksum must both be correct */ - if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) - != 0) { + if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { /* Nope, BAD Signature */ @@ -84,14 +81,14 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) /* Check the standard checksum */ - if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { + if (acpi_tb_sum_table(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)) { + (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { return (AE_BAD_CHECKSUM); } @@ -100,123 +97,314 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) /******************************************************************************* * - * FUNCTION: acpi_tb_find_rsdp + * FUNCTION: acpi_tb_find_table * - * PARAMETERS: table_address - Where the table pointer is returned + * PARAMETERS: Signature - String with ACPI table signature + * oem_id - String with the table OEM ID + * oem_table_id - String with the OEM Table ID + * table_ptr - Where the table pointer is returned * - * RETURN: Status, RSDP physical address + * RETURN: Status * - * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. + * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the + * Signature, OEM ID and OEM Table ID. * - * 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. + ******************************************************************************/ + +acpi_status +acpi_tb_find_table(char *signature, + char *oem_id, + char *oem_table_id, struct acpi_table_header ** table_ptr) +{ + acpi_status status; + struct acpi_table_header *table; + + ACPI_FUNCTION_TRACE(tb_find_table); + + /* Validate string lengths */ + + if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) || + (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) || + (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) { + return_ACPI_STATUS(AE_AML_STRING_LIMIT); + } + + if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) { + /* + * The DSDT pointer is contained in the FADT, not the RSDT. + * This code should suffice, because the only code that would perform + * a "find" on the DSDT is the data_table_region() AML opcode -- in + * which case, the DSDT is guaranteed to be already loaded. + * If this becomes insufficient, the FADT will have to be found first. + */ + if (!acpi_gbl_DSDT) { + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + table = acpi_gbl_DSDT; + } else { + /* Find the table */ + + status = acpi_get_firmware_table(signature, 1, + ACPI_LOGICAL_ADDRESSING, + &table); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + + /* Check oem_id and oem_table_id */ + + if ((oem_id[0] && + ACPI_STRNCMP(oem_id, table->oem_id, + sizeof(table->oem_id))) || + (oem_table_id[0] && + ACPI_STRNCMP(oem_table_id, table->oem_table_id, + sizeof(table->oem_table_id)))) { + return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND); + } + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n", + table->signature)); + + *table_ptr = table; + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* * - * NOTE2: This function is always available, regardless of the - * initialization state of the rest of ACPI. + * FUNCTION: acpi_get_firmware_table + * + * PARAMETERS: Signature - Any ACPI table signature + * Instance - the non zero instance of the table, allows + * support for multiple tables of the same type + * Flags - Physical/Virtual support + * table_pointer - Where a buffer containing the table is + * returned + * + * RETURN: Status + * + * DESCRIPTION: This function is called to get an ACPI table. A buffer is + * allocated for the table and returned in table_pointer. + * This table will be a complete table including the header. * ******************************************************************************/ -acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) +acpi_status +acpi_get_firmware_table(acpi_string signature, + u32 instance, + u32 flags, struct acpi_table_header **table_pointer) { - u8 *table_ptr; - u8 *mem_rover; - u32 physical_address; + acpi_status status; + struct acpi_pointer address; + struct acpi_table_header *header = NULL; + struct acpi_table_desc *table_info = NULL; + struct acpi_table_desc *rsdt_info; + u32 table_count; + u32 i; + u32 j; - ACPI_FUNCTION_TRACE(acpi_find_root_pointer); + ACPI_FUNCTION_TRACE(acpi_get_firmware_table); - /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ + /* + * Ensure that at least the table manager is initialized. We don't + * require that the entire ACPI subsystem is up for this interface. + * If we have a buffer, we must have a length too + */ + if ((instance == 0) || (!signature) || (!table_pointer)) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Ensure that we have a RSDP */ - 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)); + if (!acpi_gbl_RSDP) { + /* Get the RSDP */ + + status = acpi_os_get_root_pointer(flags, &address); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n")); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + /* Map and validate the RSDP */ + + if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { + status = acpi_os_map_memory(address.pointer.physical, + sizeof(struct + rsdp_descriptor), + (void *)&acpi_gbl_RSDP); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } else { + acpi_gbl_RSDP = address.pointer.logical; + } + + /* The RDSP signature and checksum must both be correct */ + + status = acpi_tb_validate_rsdp(acpi_gbl_RSDP); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + + /* Get the RSDT address via the RSDP */ + + acpi_tb_get_rsdt_address(&address); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "RSDP located at %p, RSDT physical=%8.8X%8.8X\n", + acpi_gbl_RSDP, + ACPI_FORMAT_UINT64(address.pointer.value))); + + /* Insert processor_mode flags */ + + address.pointer_type |= flags; + + /* Get and validate the RSDT */ + + rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); + if (!rsdt_info) { return_ACPI_STATUS(AE_NO_MEMORY); } - ACPI_MOVE_16_TO_32(&physical_address, table_ptr); + status = acpi_tb_get_table(&address, rsdt_info); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + status = acpi_tb_validate_rsdt(rsdt_info->pointer); + if (ACPI_FAILURE(status)) { + goto cleanup; + } - /* Convert segment part to physical address */ + /* Allocate a scratch table header and table descriptor */ - physical_address <<= 4; - acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); + header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); + if (!header) { + status = AE_NO_MEMORY; + goto cleanup; + } - /* EBDA present? */ + table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); + if (!table_info) { + status = AE_NO_MEMORY; + goto cleanup; + } - if (physical_address > 0x400) { + /* Get the number of table pointers within the RSDT */ + + table_count = + acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer); + address.pointer_type = acpi_gbl_table_flags | flags; + + /* + * Search the RSDT/XSDT for the correct instance of the + * requested table + */ + for (i = 0, j = 0; i < table_count; i++) { /* - * 1b) Search EBDA paragraphs (EBDA is required to be a - * minimum of 1_k length) + * Get the next table pointer, handle RSDT vs. XSDT + * RSDT pointers are 32 bits, XSDT pointers are 64 bits */ - 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)); + if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { + address.pointer.value = + (ACPI_CAST_PTR + (struct rsdt_descriptor, + rsdt_info->pointer))->table_offset_entry[i]; + } else { + address.pointer.value = + (ACPI_CAST_PTR + (struct xsdt_descriptor, + rsdt_info->pointer))->table_offset_entry[i]; + } + + /* Get the table header */ - return_ACPI_STATUS(AE_NO_MEMORY); + status = acpi_tb_get_table_header(&address, header); + if (ACPI_FAILURE(status)) { + goto cleanup; } - mem_rover = - acpi_tb_scan_memory_for_rsdp(table_ptr, - ACPI_EBDA_WINDOW_SIZE); - acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); + /* Compare table signatures and table instance */ - if (mem_rover) { + if (ACPI_COMPARE_NAME(header->signature, signature)) { - /* Return the physical address */ + /* An instance of the table was found */ - physical_address += - (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); + j++; + if (j >= instance) { - *table_address = physical_address; - return_ACPI_STATUS(AE_OK); + /* Found the correct instance, get the entire table */ + + status = + acpi_tb_get_table_body(&address, header, + table_info); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + *table_pointer = table_info->pointer; + goto cleanup; + } } } - /* - * 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); + /* Did not find the table */ - 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)); + status = AE_NOT_EXIST; - return_ACPI_STATUS(AE_NO_MEMORY); + cleanup: + if (rsdt_info->pointer) { + acpi_os_unmap_memory(rsdt_info->pointer, + (acpi_size) rsdt_info->pointer->length); } + ACPI_FREE(rsdt_info); - 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 (header) { + ACPI_FREE(header); + } + if (table_info) { + ACPI_FREE(table_info); + } + return_ACPI_STATUS(status); +} - if (mem_rover) { +ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) - /* Return the physical address */ +/* TBD: Move to a new file */ +#if ACPI_MACHINE_WIDTH != 16 +/******************************************************************************* + * + * FUNCTION: acpi_find_root_pointer + * + * PARAMETERS: Flags - Logical/Physical addressing + * rsdp_address - Where to place the RSDP address + * + * RETURN: Status, Physical address of the RSDP + * + * DESCRIPTION: Find the RSDP + * + ******************************************************************************/ +acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) +{ + struct acpi_table_desc table_info; + acpi_status status; - physical_address = (u32) - (ACPI_HI_RSDP_WINDOW_BASE + - ACPI_PTR_DIFF(mem_rover, table_ptr)); + ACPI_FUNCTION_TRACE(acpi_find_root_pointer); - *table_address = physical_address; - return_ACPI_STATUS(AE_OK); - } + /* Get the RSDP */ - /* A valid RSDP was not found */ + status = acpi_tb_find_rsdp(&table_info, flags); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "RSDP structure not found - Flags=%X", flags)); - ACPI_ERROR((AE_INFO, "A valid RSDP was not found")); - return_ACPI_STATUS(AE_NOT_FOUND); + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } + + rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; + rsdp_address->pointer.physical = table_info.physical_address; + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) @@ -252,7 +440,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) status = acpi_tb_validate_rsdp(ACPI_CAST_PTR - (struct acpi_table_rsdp, mem_rover)); + (struct rsdp_descriptor, mem_rover)); if (ACPI_SUCCESS(status)) { /* Sig and checksum valid, we have found a real RSDP */ @@ -273,3 +461,189 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) start_address)); return_PTR(NULL); } + +/******************************************************************************* + * + * FUNCTION: acpi_tb_find_rsdp + * + * PARAMETERS: table_info - Where the table info is returned + * Flags - Current memory mode (logical vs. + * physical addressing) + * + * 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. + * + ******************************************************************************/ + +static acpi_status +acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) +{ + u8 *table_ptr; + u8 *mem_rover; + u32 physical_address; + acpi_status status; + + ACPI_FUNCTION_TRACE(tb_find_rsdp); + + /* + * Scan supports either logical addressing or physical addressing + */ + if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { + + /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ + + status = acpi_os_map_memory((acpi_physical_address) + ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH, + (void *)&table_ptr); + if (ACPI_FAILURE(status)) { + 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(status); + } + + 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) + */ + status = acpi_os_map_memory((acpi_physical_address) + physical_address, + ACPI_EBDA_WINDOW_SIZE, + (void *)&table_ptr); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not map memory at %8.8X for length %X", + physical_address, + ACPI_EBDA_WINDOW_SIZE)); + + return_ACPI_STATUS(status); + } + + 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_info->physical_address = + (acpi_physical_address) physical_address; + return_ACPI_STATUS(AE_OK); + } + } + + /* + * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh + */ + status = acpi_os_map_memory((acpi_physical_address) + ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE, + (void *)&table_ptr); + + if (ACPI_FAILURE(status)) { + 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(status); + } + + 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_info->physical_address = + (acpi_physical_address) physical_address; + return_ACPI_STATUS(AE_OK); + } + } + + /* + * Physical addressing + */ + else { + /* 1a) Get the location of the EBDA */ + + ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION); + physical_address <<= 4; /* Convert segment to physical address */ + + /* EBDA present? */ + + if (physical_address > 0x400) { + /* + * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of + * 1_k length) + */ + mem_rover = + acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR + (physical_address), + ACPI_EBDA_WINDOW_SIZE); + if (mem_rover) { + + /* Return the physical address */ + + table_info->physical_address = + ACPI_TO_INTEGER(mem_rover); + return_ACPI_STATUS(AE_OK); + } + } + + /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ + + mem_rover = + acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR + (ACPI_HI_RSDP_WINDOW_BASE), + ACPI_HI_RSDP_WINDOW_SIZE); + if (mem_rover) { + + /* Found it, return the physical address */ + + table_info->physical_address = + ACPI_TO_INTEGER(mem_rover); + return_ACPI_STATUS(AE_OK); + } + } + + /* A valid RSDP was not found */ + + ACPI_ERROR((AE_INFO, "No valid RSDP was found")); + return_ACPI_STATUS(AE_NOT_FOUND); +} + +#endif diff --git a/trunk/drivers/acpi/utilities/utalloc.c b/trunk/drivers/acpi/utilities/utalloc.c index 55a764807499..f6cbc0b1bfd0 100644 --- a/trunk/drivers/acpi/utilities/utalloc.c +++ b/trunk/drivers/acpi/utilities/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,7 +42,6 @@ */ #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utalloc") @@ -143,14 +142,6 @@ acpi_status acpi_ut_create_caches(void) acpi_status acpi_ut_delete_caches(void) { -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - char buffer[7]; - - if (acpi_gbl_display_final_mem_stats) { - ACPI_STRCPY(buffer, "MEMORY"); - acpi_db_display_statistics(buffer); - } -#endif (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); acpi_gbl_namespace_cache = NULL; diff --git a/trunk/drivers/acpi/utilities/utcache.c b/trunk/drivers/acpi/utilities/utcache.c index 870f6edeb5f2..1a1f8109159c 100644 --- a/trunk/drivers/acpi/utilities/utcache.c +++ b/trunk/drivers/acpi/utilities/utcache.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -289,14 +289,6 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) ACPI_MEM_TRACKING(cache->total_allocated++); -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - if ((cache->total_allocated - cache->total_freed) > - cache->max_occupied) { - cache->max_occupied = - cache->total_allocated - cache->total_freed; - } -#endif - /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ status = acpi_ut_release_mutex(ACPI_MTX_CACHES); diff --git a/trunk/drivers/acpi/utilities/utcopy.c b/trunk/drivers/acpi/utilities/utcopy.c index 84d529db0a66..5e1a80d1bc36 100644 --- a/trunk/drivers/acpi/utilities/utcopy.c +++ b/trunk/drivers/acpi/utilities/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -719,15 +719,6 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, acpi_ut_add_reference(source_desc->reference.object); break; - case ACPI_TYPE_REGION: - /* - * We copied the Region Handler, so we now must add a reference - */ - if (dest_desc->region.handler) { - acpi_ut_add_reference(dest_desc->region.handler); - } - break; - default: /* Nothing to do for other simple objects */ break; diff --git a/trunk/drivers/acpi/utilities/utdebug.c b/trunk/drivers/acpi/utilities/utdebug.c index 61ad4f2daee2..9e9054e155c1 100644 --- a/trunk/drivers/acpi/utilities/utdebug.c +++ b/trunk/drivers/acpi/utilities/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -181,7 +181,8 @@ acpi_ut_debug_print(u32 requested_debug_level, if (ACPI_LV_THREADS & acpi_dbg_level) { acpi_os_printf ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", - (unsigned long)acpi_gbl_prev_thread_id, (unsigned long)thread_id); + (unsigned long) acpi_gbl_prev_thread_id, + (unsigned long) thread_id); } acpi_gbl_prev_thread_id = thread_id; @@ -194,7 +195,7 @@ acpi_ut_debug_print(u32 requested_debug_level, acpi_os_printf("%8s-%04ld ", module_name, line_number); if (ACPI_LV_THREADS & acpi_dbg_level) { - acpi_os_printf("[%04lX] ", (unsigned long)thread_id); + acpi_os_printf("[%04lX] ", thread_id); } acpi_os_printf("[%02ld] %-22.22s: ", diff --git a/trunk/drivers/acpi/utilities/utdelete.c b/trunk/drivers/acpi/utilities/utdelete.c index f777cebdc46d..9d3f1149ba21 100644 --- a/trunk/drivers/acpi/utilities/utdelete.c +++ b/trunk/drivers/acpi/utilities/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -158,20 +158,16 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) "***** Mutex %p, OS Mutex %p\n", object, object->mutex.os_mutex)); - if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) { - - /* Global Lock has extra semaphore */ + if (object->mutex.os_mutex != ACPI_GLOBAL_LOCK) { + acpi_ex_unlink_mutex(object); + acpi_os_delete_mutex(object->mutex.os_mutex); + } else { + /* Global Lock "mutex" is actually a counting semaphore */ (void) acpi_os_delete_semaphore (acpi_gbl_global_lock_semaphore); acpi_gbl_global_lock_semaphore = NULL; - - acpi_os_delete_mutex(object->mutex.os_mutex); - acpi_gbl_global_lock_mutex = NULL; - } else { - acpi_ex_unlink_mutex(object); - acpi_os_delete_mutex(object->mutex.os_mutex); } break; diff --git a/trunk/drivers/acpi/utilities/uteval.c b/trunk/drivers/acpi/utilities/uteval.c index 13d5879cd98b..d6d7121583c0 100644 --- a/trunk/drivers/acpi/utilities/uteval.c +++ b/trunk/drivers/acpi/utilities/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utglobal.c b/trunk/drivers/acpi/utilities/utglobal.c index af33358a964b..014030af8b50 100644 --- a/trunk/drivers/acpi/utilities/utglobal.c +++ b/trunk/drivers/acpi/utilities/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,9 +46,89 @@ #include #include -ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) #define _COMPONENT ACPI_UTILITIES - ACPI_MODULE_NAME("utglobal") +ACPI_MODULE_NAME("utglobal") + +/******************************************************************************* + * + * 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. + * + ******************************************************************************/ +const char *acpi_format_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; + } + + if (!exception) { + + /* Exception code was not recognized */ + + ACPI_ERROR((AE_INFO, + "Unknown exception code: 0x%8.8X", status)); + + exception = "UNKNOWN_STATUS_CODE"; + } + + return (ACPI_CAST_PTR(const char, exception)); +} /******************************************************************************* * @@ -83,6 +163,8 @@ u32 acpi_gbl_startup_flags = 0; u8 acpi_gbl_shutdown = TRUE; +const u8 acpi_gbl_decode_to8bit[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; + const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { "\\_S0_", "\\_S1_", @@ -99,47 +181,12 @@ const char *acpi_gbl_highest_dstate_names[4] = { "_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"; - } - - return (ACPI_CAST_PTR(const char, exception)); -} - -ACPI_EXPORT_SYMBOL(acpi_format_exception) - /******************************************************************************* * * Namespace globals * ******************************************************************************/ + /* * Predefined ACPI Names (Built-in to the Interpreter) * @@ -233,6 +280,53 @@ char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); } +/******************************************************************************* + * + * Table name globals + * + * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. + * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables + * that are not used by the subsystem are simply ignored. + * + * Do NOT add any table to this list that is not consumed directly by this + * subsystem (No MADT, ECDT, SBST, etc.) + * + ******************************************************************************/ + +struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1]; + +struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = { + /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ + + /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof(RSDP_SIG) - 1, + ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} + , + /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *)&acpi_gbl_DSDT, + sizeof(DSDT_SIG) - 1, + ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE | + ACPI_TABLE_EXECUTABLE} + , + /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *)&acpi_gbl_FADT, + sizeof(FADT_SIG) - 1, + ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE} + , + /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *)&acpi_gbl_FACS, + sizeof(FACS_SIG) - 1, + ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE} + , + /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof(PSDT_SIG) - 1, + ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | + ACPI_TABLE_EXECUTABLE} + , + /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof(SSDT_SIG) - 1, + ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | + ACPI_TABLE_EXECUTABLE} + , + /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof(RSDT_SIG) - 1, + ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} + , +}; + /****************************************************************************** * * Event and Hardware globals @@ -518,7 +612,7 @@ char *acpi_ut_get_node_name(void *object) /* Name must be a valid ACPI name */ if (!acpi_ut_valid_acpi_name(node->name.integer)) { - node->name.integer = acpi_ut_repair_name(node->name.ascii); + node->name.integer = acpi_ut_repair_name(node->name.integer); } /* Return the name */ @@ -657,6 +751,13 @@ void acpi_ut_init_globals(void) return; } + /* ACPI table structure */ + + for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + acpi_gbl_table_lists[i].next = NULL; + acpi_gbl_table_lists[i].count = 0; + } + /* Mutex locked flags */ for (i = 0; i < ACPI_NUM_MUTEX; i++) { @@ -672,7 +773,6 @@ void acpi_ut_init_globals(void) /* GPE support */ - acpi_gpe_count = 0; acpi_gbl_gpe_xrupt_list_head = NULL; acpi_gbl_gpe_fadt_blocks[0] = NULL; acpi_gbl_gpe_fadt_blocks[1] = NULL; @@ -684,15 +784,25 @@ void acpi_ut_init_globals(void) acpi_gbl_exception_handler = NULL; acpi_gbl_init_handler = NULL; + /* Global "typed" ACPI table pointers */ + + acpi_gbl_RSDP = NULL; + acpi_gbl_XSDT = NULL; + acpi_gbl_FACS = NULL; + acpi_gbl_FADT = NULL; + acpi_gbl_DSDT = 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_thread_count = 0; acpi_gbl_global_lock_handle = 0; /* Miscellaneous variables */ + acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER; + acpi_gbl_rsdp_original_location = 0; acpi_gbl_cm_single_step = FALSE; acpi_gbl_db_terminate_threads = FALSE; acpi_gbl_shutdown = FALSE; @@ -727,13 +837,8 @@ void acpi_ut_init_globals(void) acpi_gbl_lowest_stack_pointer = 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) -ACPI_EXPORT_SYMBOL(acpi_gpe_count) diff --git a/trunk/drivers/acpi/utilities/utinit.c b/trunk/drivers/acpi/utilities/utinit.c index ad3c0d0a5cf8..ff76055eb7d6 100644 --- a/trunk/drivers/acpi/utilities/utinit.c +++ b/trunk/drivers/acpi/utilities/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,14 +44,119 @@ #include #include #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utinit") /* Local prototypes */ +static void +acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset); + static void acpi_ut_terminate(void); +/******************************************************************************* + * + * FUNCTION: acpi_ut_fadt_register_error + * + * PARAMETERS: register_name - Pointer to string identifying register + * Value - Actual register contents value + * Offset - Byte offset in the FADT + * + * RETURN: AE_BAD_VALUE + * + * DESCRIPTION: Display failure message + * + ******************************************************************************/ + +static void +acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset) +{ + + ACPI_WARNING((AE_INFO, + "Invalid FADT value %s=%X at offset %X FADT=%p", + register_name, value, offset, acpi_gbl_FADT)); +} + +/****************************************************************************** + * + * FUNCTION: acpi_ut_validate_fadt + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Validate various ACPI registers in the FADT + * + ******************************************************************************/ + +acpi_status acpi_ut_validate_fadt(void) +{ + + /* + * Verify Fixed ACPI Description Table fields, + * but don't abort on any problems, just display error + */ + if (acpi_gbl_FADT->pm1_evt_len < 4) { + acpi_ut_fadt_register_error("PM1_EVT_LEN", + (u32) acpi_gbl_FADT->pm1_evt_len, + ACPI_FADT_OFFSET(pm1_evt_len)); + } + + if (!acpi_gbl_FADT->pm1_cnt_len) { + acpi_ut_fadt_register_error("PM1_CNT_LEN", 0, + ACPI_FADT_OFFSET(pm1_cnt_len)); + } + + if (!acpi_gbl_FADT->xpm1a_evt_blk.address) { + acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0, + ACPI_FADT_OFFSET(xpm1a_evt_blk. + address)); + } + + if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) { + acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0, + ACPI_FADT_OFFSET(xpm1a_cnt_blk. + address)); + } + + if (!acpi_gbl_FADT->xpm_tmr_blk.address) { + acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0, + ACPI_FADT_OFFSET(xpm_tmr_blk. + address)); + } + + if ((acpi_gbl_FADT->xpm2_cnt_blk.address && + !acpi_gbl_FADT->pm2_cnt_len)) { + acpi_ut_fadt_register_error("PM2_CNT_LEN", + (u32) acpi_gbl_FADT->pm2_cnt_len, + ACPI_FADT_OFFSET(pm2_cnt_len)); + } + + if (acpi_gbl_FADT->pm_tm_len < 4) { + acpi_ut_fadt_register_error("PM_TM_LEN", + (u32) acpi_gbl_FADT->pm_tm_len, + ACPI_FADT_OFFSET(pm_tm_len)); + } + + /* Length of GPE blocks must be a multiple of 2 */ + + if (acpi_gbl_FADT->xgpe0_blk.address && + (acpi_gbl_FADT->gpe0_blk_len & 1)) { + acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN", + (u32) acpi_gbl_FADT->gpe0_blk_len, + ACPI_FADT_OFFSET(gpe0_blk_len)); + } + + if (acpi_gbl_FADT->xgpe1_blk.address && + (acpi_gbl_FADT->gpe1_blk_len & 1)) { + acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN", + (u32) acpi_gbl_FADT->gpe1_blk_len, + ACPI_FADT_OFFSET(gpe1_blk_len)); + } + + return (AE_OK); +} + /****************************************************************************** * * FUNCTION: acpi_ut_terminate @@ -73,6 +178,7 @@ static void acpi_ut_terminate(void) ACPI_FUNCTION_TRACE(ut_terminate); + /* Free global tables, etc. */ /* Free global GPE blocks and related info structures */ gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; @@ -133,10 +239,6 @@ void acpi_ut_subsystem_shutdown(void) acpi_ns_terminate(); - /* Delete the ACPI tables */ - - acpi_tb_terminate(); - /* Close the globals */ acpi_ut_terminate(); diff --git a/trunk/drivers/acpi/utilities/utmath.c b/trunk/drivers/acpi/utilities/utmath.c index 0c56a0d20b29..19d74bedce27 100644 --- a/trunk/drivers/acpi/utilities/utmath.c +++ b/trunk/drivers/acpi/utilities/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utmisc.c b/trunk/drivers/acpi/utilities/utmisc.c index 50133fffe420..6d8a8211be90 100644 --- a/trunk/drivers/acpi/utilities/utmisc.c +++ b/trunk/drivers/acpi/utilities/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,78 +49,6 @@ #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_is_aml_table @@ -134,15 +62,14 @@ const char *acpi_ut_validate_exception(acpi_status status) * data tables that do not contain AML code. * ******************************************************************************/ - u8 acpi_ut_is_aml_table(struct acpi_table_header *table) { /* These are the only tables that contain executable AML */ - if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { + if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) || + ACPI_COMPARE_NAME(table->signature, PSDT_SIG) || + ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) { return (TRUE); } @@ -491,7 +418,7 @@ u32 acpi_ut_dword_byte_swap(u32 value) void acpi_ut_set_integer_width(u8 revision) { - if (revision < 2) { + if (revision <= 1) { /* 32-bit case */ @@ -655,25 +582,26 @@ u8 acpi_ut_valid_acpi_name(u32 name) * ******************************************************************************/ -acpi_name acpi_ut_repair_name(char *name) +acpi_name acpi_ut_repair_name(acpi_name name) { - acpi_native_uint i; + char *name_ptr = ACPI_CAST_PTR(char, &name); char new_name[ACPI_NAME_SIZE]; + acpi_native_uint i; for (i = 0; i < ACPI_NAME_SIZE; i++) { - new_name[i] = name[i]; + new_name[i] = name_ptr[i]; /* * Replace a bad character with something printable, yet technically * still invalid. This prevents any collisions with existing "good" * names in the namespace. */ - if (!acpi_ut_valid_acpi_char(name[i], i)) { + if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) { new_name[i] = '*'; } } - return (*(u32 *) new_name); + return (*ACPI_CAST_PTR(u32, new_name)); } /******************************************************************************* @@ -1068,13 +996,9 @@ 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: "); + acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf("\n"); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); } diff --git a/trunk/drivers/acpi/utilities/utmutex.c b/trunk/drivers/acpi/utilities/utmutex.c index cbad2ef5987d..180e73ceb6e2 100644 --- a/trunk/drivers/acpi/utilities/utmutex.c +++ b/trunk/drivers/acpi/utilities/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utobject.c b/trunk/drivers/acpi/utilities/utobject.c index 4696124759e1..ba7d8ac702df 100644 --- a/trunk/drivers/acpi/utilities/utobject.c +++ b/trunk/drivers/acpi/utilities/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utresrc.c b/trunk/drivers/acpi/utilities/utresrc.c index e8fe1ba6cc24..5a2de92831d3 100644 --- a/trunk/drivers/acpi/utilities/utresrc.c +++ b/trunk/drivers/acpi/utilities/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utstate.c b/trunk/drivers/acpi/utilities/utstate.c index edcaafad0a31..eaa13d05c859 100644 --- a/trunk/drivers/acpi/utilities/utstate.c +++ b/trunk/drivers/acpi/utilities/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/drivers/acpi/utilities/utxface.c b/trunk/drivers/acpi/utilities/utxface.c index de3276f4f468..3538f69c82a1 100644 --- a/trunk/drivers/acpi/utilities/utxface.c +++ b/trunk/drivers/acpi/utilities/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,7 +67,6 @@ acpi_status acpi_initialize_subsystem(void) ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); - acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE; ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); /* Initialize the OS-Dependent layer */ @@ -128,6 +127,20 @@ acpi_status acpi_enable_subsystem(u32 flags) ACPI_FUNCTION_TRACE(acpi_enable_subsystem); + /* + * We must initialize the hardware before we can enable ACPI. + * The values from the FADT are validated here. + */ + if (!(flags & ACPI_NO_HARDWARE_INIT)) { + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "[Init] Initializing ACPI hardware\n")); + + status = acpi_hw_initialize(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + /* Enable ACPI mode */ if (!(flags & ACPI_NO_ACPI_ENABLE)) { @@ -385,6 +398,7 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) { struct acpi_system_info *info_ptr; acpi_status status; + u32 i; ACPI_FUNCTION_TRACE(acpi_get_system_info); @@ -417,7 +431,9 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) /* Timer resolution - 24 or 32 bits */ - if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) { + if (!acpi_gbl_FADT) { + info_ptr->timer_resolution = 0; + } else if (acpi_gbl_FADT->tmr_val_ext == 0) { info_ptr->timer_resolution = 24; } else { info_ptr->timer_resolution = 32; @@ -433,6 +449,13 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) info_ptr->debug_layer = acpi_dbg_layer; info_ptr->debug_level = acpi_dbg_level; + /* Current status of the ACPI tables, per table type */ + + info_ptr->num_table_types = ACPI_TABLE_ID_MAX + 1; + for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; + } + return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index a695aeb8b2a7..3d54680d0333 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -32,7 +32,6 @@ #include #include -#include #include #include @@ -57,12 +56,6 @@ #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) #define ACPI_VIDEO_HEAD_END (~0u) -#define MAX_NAME_LEN 20 - -#define ACPI_VIDEO_DISPLAY_CRT 1 -#define ACPI_VIDEO_DISPLAY_TV 2 -#define ACPI_VIDEO_DISPLAY_DVI 3 -#define ACPI_VIDEO_DISPLAY_LCD 4 #define _COMPONENT ACPI_VIDEO_COMPONENT ACPI_MODULE_NAME("acpi_video") @@ -140,21 +133,20 @@ struct acpi_video_device_flags { u8 crt:1; u8 lcd:1; u8 tvout:1; - u8 dvi:1; u8 bios:1; u8 unknown:1; - u8 reserved:2; + u8 reserved:3; }; struct acpi_video_device_cap { u8 _ADR:1; /*Return the unique ID */ u8 _BCL:1; /*Query list of brightness control levels supported */ u8 _BCM:1; /*Set the brightness level */ - u8 _BQC:1; /* Get current brightness level */ u8 _DDC:1; /*Return the EDID for this device */ u8 _DCS:1; /*Return status of output device */ u8 _DGS:1; /*Query graphics state */ u8 _DSS:1; /*Device state set */ + u8 _reserved:1; }; struct acpi_video_device_brightness { @@ -171,8 +163,6 @@ struct acpi_video_device { struct acpi_video_bus *video; struct acpi_device *dev; struct acpi_video_device_brightness *brightness; - struct backlight_device *backlight; - struct backlight_properties *data; }; /* bus */ @@ -267,35 +257,11 @@ static void acpi_video_device_bind(struct acpi_video_bus *video, struct acpi_video_device *device); static int acpi_video_device_enumerate(struct acpi_video_bus *video); static int acpi_video_switch_output(struct acpi_video_bus *video, int event); -static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, - int level); -static int acpi_video_device_lcd_get_level_current( - struct acpi_video_device *device, - unsigned long *level); static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event); static void acpi_video_switch_brightness(struct acpi_video_device *device, int event); -/*backlight device sysfs support*/ -static int acpi_video_get_brightness(struct backlight_device *bd) -{ - unsigned long cur_level; - struct acpi_video_device *vd = - (struct acpi_video_device *)class_get_devdata(&bd->class_dev); - acpi_video_device_lcd_get_level_current(vd, &cur_level); - return (int) cur_level; -} - -static int acpi_video_set_brightness(struct backlight_device *bd) -{ - int request_level = bd->props->brightness; - struct acpi_video_device *vd = - (struct acpi_video_device *)class_get_devdata(&bd->class_dev); - acpi_video_device_lcd_set_level(vd, request_level); - return 0; -} - /* -------------------------------------------------------------------------- Video Management -------------------------------------------------------------------------- */ @@ -533,7 +499,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) acpi_integer status; acpi_handle h_dummy1; int i; - u32 max_level = 0; union acpi_object *obj = NULL; struct acpi_video_device_brightness *br = NULL; @@ -549,8 +514,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { device->cap._BCM = 1; } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) - device->cap._BQC = 1; if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { device->cap._DDC = 1; } @@ -587,8 +550,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) continue; } br->levels[count] = (u32) o->integer.value; - if (br->levels[count] > max_level) - max_level = br->levels[count]; count++; } out: @@ -607,37 +568,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) kfree(obj); - if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ - unsigned long tmp; - static int count = 0; - char *name; - struct backlight_properties *acpi_video_data; - - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); - if (!name) - return; - - acpi_video_data = kzalloc( - sizeof(struct backlight_properties), - GFP_KERNEL); - if (!acpi_video_data){ - kfree(name); - return; - } - acpi_video_data->owner = THIS_MODULE; - acpi_video_data->get_brightness = - acpi_video_get_brightness; - acpi_video_data->update_status = - acpi_video_set_brightness; - sprintf(name, "acpi_video%d", count++); - device->data = acpi_video_data; - acpi_video_data->max_brightness = max_level; - acpi_video_device_lcd_get_level_current(device, &tmp); - acpi_video_data->brightness = (int)tmp; - device->backlight = backlight_device_register(name, - NULL, device, acpi_video_data); - kfree(name); - } return; } @@ -738,8 +668,6 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) seq_printf(seq, "LCD\n"); else if (dev->flags.tvout) seq_printf(seq, "TVOUT\n"); - else if (dev->flags.dvi) - seq_printf(seq, "DVI\n"); else seq_printf(seq, "UNKNOWN\n"); @@ -1314,16 +1242,6 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) -------------------------------------------------------------------------- */ /* device interface */ -static struct acpi_video_device_attrib* -acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) -{ - int count; - - for(count = 0; count < video->attached_count; count++) - if((video->attached_array[count].value.int_val & 0xffff) == device_id) - return &(video->attached_array[count].value.attrib); - return NULL; -} static int acpi_video_bus_get_one_device(struct acpi_device *device, @@ -1332,7 +1250,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, unsigned long device_id; int status; struct acpi_video_device *data; - struct acpi_video_device_attrib* attribute; + if (!device || !video) return -EINVAL; @@ -1353,30 +1271,20 @@ acpi_video_bus_get_one_device(struct acpi_device *device, data->video = video; data->dev = device; - attribute = acpi_video_get_device_attr(video, device_id); - - if((attribute != NULL) && attribute->device_id_scheme) { - switch (attribute->display_type) { - case ACPI_VIDEO_DISPLAY_CRT: - data->flags.crt = 1; - break; - case ACPI_VIDEO_DISPLAY_TV: - data->flags.tvout = 1; - break; - case ACPI_VIDEO_DISPLAY_DVI: - data->flags.dvi = 1; - break; - case ACPI_VIDEO_DISPLAY_LCD: - data->flags.lcd = 1; - break; - default: - data->flags.unknown = 1; - break; - } - if(attribute->bios_can_detect) - data->flags.bios = 1; - } else + switch (device_id & 0xffff) { + case 0x0100: + data->flags.crt = 1; + break; + case 0x0400: + data->flags.lcd = 1; + break; + case 0x0200: + data->flags.tvout = 1; + break; + default: data->flags.unknown = 1; + break; + } acpi_video_device_bind(video, data); acpi_video_device_find_cap(data); @@ -1680,10 +1588,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) status = acpi_remove_notify_handler(device->dev->handle, ACPI_DEVICE_NOTIFY, acpi_video_device_notify); - if (device->backlight){ - backlight_device_unregister(device->backlight); - kfree(device->data); - } + return 0; } diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index a7b33d2f5991..f1afd26a509f 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -1802,7 +1802,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) return -ENODEV; } - if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) addr_space = IPMI_MEM_ADDR_SPACE; else addr_space = IPMI_IO_ADDR_SPACE; @@ -1848,19 +1848,19 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) info->irq_setup = NULL; } - if (spmi->addr.bit_width) { + if (spmi->addr.register_bit_width) { /* A (hopefully) properly formed register bit width. */ - info->io.regspacing = spmi->addr.bit_width / 8; + info->io.regspacing = spmi->addr.register_bit_width / 8; } else { info->io.regspacing = DEFAULT_REGSPACING; } info->io.regsize = info->io.regspacing; - info->io.regshift = spmi->addr.bit_offset; + info->io.regshift = spmi->addr.register_bit_offset; - if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { info->io_setup = mem_setup; info->io.addr_type = IPMI_IO_ADDR_SPACE; - } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) { info->io_setup = port_setup; info->io.addr_type = IPMI_MEM_ADDR_SPACE; } else { @@ -1888,8 +1888,10 @@ static __devinit void acpi_find_bmc(void) return; for (i = 0; ; i++) { - status = acpi_get_table(ACPI_SIG_SPMI, i+1, - (struct acpi_table_header **)&spmi); + status = acpi_get_firmware_table("SPMI", i+1, + ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) + &spmi); if (status != AE_OK) return; diff --git a/trunk/drivers/char/tpm/tpm_bios.c b/trunk/drivers/char/tpm/tpm_bios.c index 7fca5f470beb..a611972024e6 100644 --- a/trunk/drivers/char/tpm/tpm_bios.c +++ b/trunk/drivers/char/tpm/tpm_bios.c @@ -372,8 +372,10 @@ static int read_log(struct tpm_bios_log *log) } /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ - status = acpi_get_table(ACPI_SIG_TCPA, 1, - (struct acpi_table_header **)&buff); + status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1, + ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) + &buff); if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n", @@ -407,7 +409,7 @@ static int read_log(struct tpm_bios_log *log) log->bios_event_log_end = log->bios_event_log + len; - virt = acpi_os_map_memory(start, len); + acpi_os_map_memory(start, len, (void *) &virt); memcpy(log->bios_event_log, virt, len); diff --git a/trunk/drivers/firmware/pcdp.c b/trunk/drivers/firmware/pcdp.c index 2b4b76e8bd72..c2ad72fefd9d 100644 --- a/trunk/drivers/firmware/pcdp.c +++ b/trunk/drivers/firmware/pcdp.c @@ -26,7 +26,7 @@ setup_serial_console(struct pcdp_uart *uart) static char options[64], *p = options; char parity; - mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); + mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); p += sprintf(p, "console=uart,%s,0x%lx", mmio ? "mmio" : "io", uart->addr.address); if (uart->baud) { diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index fca978fb158e..bd1faebf61a0 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -773,13 +773,13 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base) goto out; table = obj->buffer.pointer; - switch (((struct acpi_subtable_header *)table)->type) { - case ACPI_MADT_TYPE_IO_SAPIC: - *gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base; + switch (((acpi_table_entry_header *)table)->type) { + case ACPI_MADT_IOSAPIC: + *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base; result = 0; break; - case ACPI_MADT_TYPE_IO_APIC: - *gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base; + case ACPI_MADT_IOAPIC: + *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base; result = 0; break; default: diff --git a/trunk/drivers/pci/hotplug/sgi_hotplug.c b/trunk/drivers/pci/hotplug/sgi_hotplug.c index 78cf0711d1fa..5d188c558386 100644 --- a/trunk/drivers/pci/hotplug/sgi_hotplug.c +++ b/trunk/drivers/pci/hotplug/sgi_hotplug.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include "../pci.h" @@ -37,17 +35,14 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver"); - -/* SAL call error codes. Keep in sync with prom header io/include/pcibr.h */ +#define PCIIO_ASIC_TYPE_TIOCA 4 #define PCI_SLOT_ALREADY_UP 2 /* slot already up */ #define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */ #define PCI_L1_ERR 7 /* L1 console command error */ #define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */ - - -#define PCIIO_ASIC_TYPE_TIOCA 4 #define PCI_L1_QSIZE 128 /* our L1 message buffer size */ #define SN_MAX_HP_SLOTS 32 /* max hotplug slots */ +#define SGI_HOTPLUG_PROM_REV 0x0430 /* Min. required PROM version */ #define SN_SLOT_NAME_SIZE 33 /* size of name string */ /* internal list head */ @@ -232,7 +227,7 @@ static void sn_bus_free_data(struct pci_dev *dev) } static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, - int device_num, char **ssdt) + int device_num) { struct slot *slot = bss_hotplug_slot->private; struct pcibus_info *pcibus_info; @@ -245,8 +240,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, * Power-on and initialize the slot in the SN * PCI infrastructure. */ - rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp, ssdt); - + rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp); if (rc == PCI_SLOT_ALREADY_UP) { dev_dbg(slot->pci_bus->self, "is already active\n"); @@ -341,7 +335,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) int func, num_funcs; int new_ppb = 0; int rc; - char *ssdt = NULL; void pcibios_fixup_device_resources(struct pci_dev *); /* Serialize the Linux PCI infrastructure */ @@ -349,29 +342,14 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) /* * Power-on and initialize the slot in the SN - * PCI infrastructure. Also, retrieve the ACPI SSDT - * table for the slot (if ACPI capable PROM). + * PCI infrastructure. */ - rc = sn_slot_enable(bss_hotplug_slot, slot->device_num, &ssdt); + rc = sn_slot_enable(bss_hotplug_slot, slot->device_num); if (rc) { mutex_unlock(&sn_hotplug_mutex); return rc; } - if (ssdt) - ssdt = __va(ssdt); - /* Add the new SSDT for the slot to the ACPI namespace */ - if (SN_ACPI_BASE_SUPPORT() && ssdt) { - acpi_status ret; - - ret = acpi_load_table((struct acpi_table_header *)ssdt); - if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_load_table failed (0x%x)\n", - __FUNCTION__, ret); - /* try to continue on */ - } - } - num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num + 1, 0)); if (!num_funcs) { @@ -396,10 +374,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) * pdi_host_pcidev_info). */ pcibios_fixup_device_resources(dev); - if (SN_ACPI_BASE_SUPPORT()) - sn_acpi_slot_fixup(dev); - else - sn_io_slot_fixup(dev); + sn_pci_fixup_slot(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { unsigned char sec_bus; pci_read_config_byte(dev, PCI_SECONDARY_BUS, @@ -413,63 +388,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) } } - /* - * Add the slot's devices to the ACPI infrastructure */ - if (SN_ACPI_BASE_SUPPORT() && ssdt) { - unsigned long adr; - struct acpi_device *pdevice; - struct acpi_device *device; - acpi_handle phandle; - acpi_handle chandle = NULL; - acpi_handle rethandle; - acpi_status ret; - - phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; - - if (acpi_bus_get_device(phandle, &pdevice)) { - dev_dbg(slot->pci_bus->self, - "no parent device, assuming NULL\n"); - pdevice = NULL; - } - - /* - * Walk the rootbus node's immediate children looking for - * the slot's device node(s). There can be more than - * one for multifunction devices. - */ - for (;;) { - rethandle = NULL; - ret = acpi_get_next_object(ACPI_TYPE_DEVICE, - phandle, chandle, - &rethandle); - - if (ret == AE_NOT_FOUND || rethandle == NULL) - break; - - chandle = rethandle; - - ret = acpi_evaluate_integer(chandle, METHOD_NAME__ADR, - NULL, &adr); - - if (ACPI_SUCCESS(ret) && - (adr>>16) == (slot->device_num + 1)) { - - ret = acpi_bus_add(&device, pdevice, chandle, - ACPI_BUS_TYPE_DEVICE); - if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_bus_add " - "failed (0x%x) for slot %d " - "func %d\n", __FUNCTION__, - ret, (int)(adr>>16), - (int)(adr&0xffff)); - /* try to continue on */ - } else { - acpi_bus_start(device); - } - } - } - } - /* Call the driver for the new device */ pci_bus_add_devices(slot->pci_bus); /* Call the drivers for the new devices subordinate to PPB */ @@ -494,7 +412,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) struct pci_dev *dev; int func; int rc; - acpi_owner_id ssdt_id = 0; /* Acquire update access to the bus */ mutex_lock(&sn_hotplug_mutex); @@ -505,52 +422,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) if (rc) goto leaving; - /* free the ACPI resources for the slot */ - if (SN_ACPI_BASE_SUPPORT() && - PCI_CONTROLLER(slot->pci_bus)->acpi_handle) { - unsigned long adr; - struct acpi_device *device; - acpi_handle phandle; - acpi_handle chandle = NULL; - acpi_handle rethandle; - acpi_status ret; - - /* Get the rootbus node pointer */ - phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; - - /* - * Walk the rootbus node's immediate children looking for - * the slot's device node(s). There can be more than - * one for multifunction devices. - */ - for (;;) { - rethandle = NULL; - ret = acpi_get_next_object(ACPI_TYPE_DEVICE, - phandle, chandle, - &rethandle); - - if (ret == AE_NOT_FOUND || rethandle == NULL) - break; - - chandle = rethandle; - - ret = acpi_evaluate_integer(chandle, - METHOD_NAME__ADR, - NULL, &adr); - if (ACPI_SUCCESS(ret) && - (adr>>16) == (slot->device_num + 1)) { - /* retain the owner id */ - acpi_get_id(chandle, &ssdt_id); - - ret = acpi_bus_get_device(chandle, - &device); - if (ACPI_SUCCESS(ret)) - acpi_bus_trim(device, 1); - } - } - - } - /* Free the SN resources assigned to the Linux device.*/ for (func = 0; func < 8; func++) { dev = pci_get_slot(slot->pci_bus, @@ -563,18 +434,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) } } - /* Remove the SSDT for the slot from the ACPI namespace */ - if (SN_ACPI_BASE_SUPPORT() && ssdt_id) { - acpi_status ret; - ret = acpi_unload_table_id(ssdt_id); - if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_unload_table_id " - "failed (0x%x) for id %d\n", - __FUNCTION__, ret, ssdt_id); - /* try to continue on */ - } - } - /* free the collected sysdata pointers */ sn_bus_free_sysdata(); diff --git a/trunk/include/acpi/acconfig.h b/trunk/include/acpi/acconfig.h index 422f29c06c77..ebc1f697615a 100644 --- a/trunk/include/acpi/acconfig.h +++ b/trunk/include/acpi/acconfig.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20070126 +#define ACPI_CA_VERSION 0x20060707 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, @@ -115,10 +115,6 @@ #define ACPI_NUM_OWNERID_MASKS 8 -/* Size of the root table array is increased by this increment */ - -#define ACPI_ROOT_TABLE_SIZE_INCREMENT 4 - /****************************************************************************** * * ACPI Specification constants (Do not change unless the specification changes) @@ -156,11 +152,6 @@ #define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */ #define ACPI_PATH_SEPARATOR '.' -/* Sizes for ACPI table headers */ - -#define ACPI_OEM_ID_SIZE 6 -#define ACPI_OEM_TABLE_ID_SIZE 8 - /* Constants used in searching for the RSDP in low memory */ #define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */ diff --git a/trunk/include/acpi/acdebug.h b/trunk/include/acpi/acdebug.h index d626bb1d2973..d8167095caf3 100644 --- a/trunk/include/acpi/acdebug.h +++ b/trunk/include/acpi/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -159,10 +159,6 @@ void acpi_db_create_execution_threads(char *num_threads_arg, char *num_loops_arg, char *method_name_arg); -#ifdef ACPI_DBG_TRACK_ALLOCATIONS -u32 acpi_db_get_cache_info(struct acpi_memory_list *cache); -#endif - /* * dbfileio - Debugger file I/O commands */ @@ -218,6 +214,4 @@ void acpi_db_prep_namestring(char *name); struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name); -void acpi_db_uint32_to_hex_string(u32 value, char *buffer); - #endif /* __ACDEBUG_H__ */ diff --git a/trunk/include/acpi/acdisasm.h b/trunk/include/acpi/acdisasm.h index 389d772c7d5b..9a7d6921f534 100644 --- a/trunk/include/acpi/acdisasm.h +++ b/trunk/include/acpi/acdisasm.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -97,11 +97,9 @@ typedef const struct acpi_dmtable_info { #define ACPI_DMT_CHKSUM 20 #define ACPI_DMT_SPACEID 21 #define ACPI_DMT_GAS 22 -#define ACPI_DMT_DMAR 23 -#define ACPI_DMT_MADT 24 -#define ACPI_DMT_SRAT 25 -#define ACPI_DMT_EXIT 26 -#define ACPI_DMT_SIG 27 +#define ACPI_DMT_MADT 23 +#define ACPI_DMT_SRAT 24 +#define ACPI_DMT_EXIT 25 typedef void (*ACPI_TABLE_HANDLER) (struct acpi_table_header * table); @@ -110,7 +108,6 @@ struct acpi_dmtable_data { char *signature; struct acpi_dmtable_info *table_info; ACPI_TABLE_HANDLER table_handler; - char *name; }; struct acpi_op_walk_info { @@ -142,9 +139,7 @@ extern const char *acpi_gbl_match_ops[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf0[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf1[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf1a[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf2[]; -extern struct acpi_dmtable_info acpi_dm_table_info_asf2a[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf3[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf4[]; extern struct acpi_dmtable_info acpi_dm_table_info_asf_hdr[]; @@ -152,11 +147,6 @@ extern struct acpi_dmtable_info acpi_dm_table_info_boot[]; extern struct acpi_dmtable_info acpi_dm_table_info_cpep[]; extern struct acpi_dmtable_info acpi_dm_table_info_cpep0[]; extern struct acpi_dmtable_info acpi_dm_table_info_dbgp[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[]; -extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[]; extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; extern struct acpi_dmtable_info acpi_dm_table_info_facs[]; extern struct acpi_dmtable_info acpi_dm_table_info_fadt1[]; @@ -211,8 +201,6 @@ void acpi_dm_dump_asf(struct acpi_table_header *table); void acpi_dm_dump_cpep(struct acpi_table_header *table); -void acpi_dm_dump_dmar(struct acpi_table_header *table); - void acpi_dm_dump_fadt(struct acpi_table_header *table); void acpi_dm_dump_srat(struct acpi_table_header *table); @@ -326,7 +314,7 @@ acpi_dm_resource_template(struct acpi_op_walk_info *info, union acpi_parse_object *op, u8 * byte_data, u32 byte_count); -acpi_status acpi_dm_is_resource_template(union acpi_parse_object *op); +u8 acpi_dm_is_resource_template(union acpi_parse_object *op); void acpi_dm_indent(u32 level); diff --git a/trunk/include/acpi/acdispat.h b/trunk/include/acpi/acdispat.h index cb8d2868c8ac..a22fe9cf8493 100644 --- a/trunk/include/acpi/acdispat.h +++ b/trunk/include/acpi/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -210,7 +210,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state); * dsinit */ acpi_status -acpi_ds_initialize_objects(acpi_native_uint table_index, +acpi_ds_initialize_objects(struct acpi_table_desc *table_desc, struct acpi_namespace_node *start_node); /* diff --git a/trunk/include/acpi/acevents.h b/trunk/include/acpi/acevents.h index d23cdf326808..234142828e1a 100644 --- a/trunk/include/acpi/acevents.h +++ b/trunk/include/acpi/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acexcep.h b/trunk/include/acpi/acexcep.h index b73f18a48785..797ca1ea5214 100644 --- a/trunk/include/acpi/acexcep.h +++ b/trunk/include/acpi/acexcep.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -178,10 +178,8 @@ #define AE_CTRL_BREAK (acpi_status) (0x0009 | AE_CODE_CONTROL) #define AE_CTRL_CONTINUE (acpi_status) (0x000A | AE_CODE_CONTROL) #define AE_CTRL_SKIP (acpi_status) (0x000B | AE_CODE_CONTROL) -#define AE_CTRL_PARSE_CONTINUE (acpi_status) (0x000C | AE_CODE_CONTROL) -#define AE_CTRL_PARSE_PENDING (acpi_status) (0x000D | AE_CODE_CONTROL) -#define AE_CODE_CTRL_MAX 0x000D +#define AE_CODE_CTRL_MAX 0x000B #ifdef DEFINE_ACPI_GLOBALS @@ -293,9 +291,7 @@ char const *acpi_gbl_exception_names_ctrl[] = { "AE_CTRL_TRANSFER", "AE_CTRL_BREAK", "AE_CTRL_CONTINUE", - "AE_CTRL_SKIP", - "AE_CTRL_PARSE_CONTINUE", - "AE_CTRL_PARSE_PENDING" + "AE_CTRL_SKIP" }; #endif /* ACPI GLOBALS */ diff --git a/trunk/include/acpi/acglobal.h b/trunk/include/acpi/acglobal.h index 24c3f05ab367..06972e6637de 100644 --- a/trunk/include/acpi/acglobal.h +++ b/trunk/include/acpi/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -58,6 +58,37 @@ #define ACPI_INIT_GLOBAL(a,b) a #endif +/* + * Keep local copies of these FADT-based registers. NOTE: These globals + * are first in this file for alignment reasons on 64-bit systems. + */ +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; + +/***************************************************************************** + * + * Debug support + * + ****************************************************************************/ + +/* Runtime configuration of debug print levels */ + +extern u32 acpi_dbg_level; +extern u32 acpi_dbg_layer; + +/* Procedure nesting level for debug output */ + +extern u32 acpi_gbl_nesting_level; + +/* Support for dynamic control method tracing mechanism */ + +ACPI_EXTERN u32 acpi_gbl_original_dbg_level; +ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; +ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; +ACPI_EXTERN u32 acpi_gbl_trace_flags; + /***************************************************************************** * * Runtime configuration (static defaults that can be overriden at runtime) @@ -102,34 +133,6 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); */ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); -/***************************************************************************** - * - * Debug support - * - ****************************************************************************/ - -/* Runtime configuration of debug print levels */ - -extern u32 acpi_dbg_level; -extern u32 acpi_dbg_layer; - -/* Procedure nesting level for debug output */ - -extern u32 acpi_gbl_nesting_level; - -/* Event counters */ - -ACPI_EXTERN u32 acpi_gpe_count; - -/* Support for dynamic control method tracing mechanism */ - -ACPI_EXTERN u32 acpi_gbl_original_dbg_level; -ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; -ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; -ACPI_EXTERN u32 acpi_gbl_trace_flags; - /***************************************************************************** * * ACPI Table globals @@ -137,29 +140,47 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; ****************************************************************************/ /* - * acpi_gbl_root_table_list is the master list of ACPI tables found in the - * RSDT/XSDT. + * Table pointers. + * Although these pointers are somewhat redundant with the global acpi_table, + * they are convenient because they are typed pointers. * - * acpi_gbl_FADT is a local copy of the FADT, converted to a common format. + * These tables are single-table only; meaning that there can be at most one + * of each in the system. Each global points to the actual table. + */ +ACPI_EXTERN u32 acpi_gbl_table_flags; +ACPI_EXTERN u32 acpi_gbl_rsdt_table_count; +ACPI_EXTERN struct rsdp_descriptor *acpi_gbl_RSDP; +ACPI_EXTERN struct xsdt_descriptor *acpi_gbl_XSDT; +ACPI_EXTERN struct fadt_descriptor *acpi_gbl_FADT; +ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; +ACPI_EXTERN struct facs_descriptor *acpi_gbl_FACS; +ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; +/* + * Since there may be multiple SSDTs and PSDTs, a single pointer is not + * sufficient; Therefore, there isn't one! */ -ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; -ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; -extern acpi_native_uint acpi_gbl_permanent_mmap; -/* These addresses are calculated from FADT address values */ +/* The root table can be either an RSDT or an XSDT */ -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; +ACPI_EXTERN u8 acpi_gbl_root_table_type; +#define ACPI_TABLE_TYPE_RSDT 'R' +#define ACPI_TABLE_TYPE_XSDT 'X' /* - * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is - * determined by the revision of the DSDT: If the DSDT revision is less than - * 2, use only the lower 32 bits of the internal 64-bit Integer. + * Handle both ACPI 1.0 and ACPI 2.0 Integer widths: + * If we are executing a method that exists in a 32-bit ACPI table, + * use only the lower 32 bits of the (internal) 64-bit Integer. */ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; ACPI_EXTERN u8 acpi_gbl_integer_byte_width; ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; +/* + * ACPI Table info arrays + */ +extern struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1]; +extern struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1]; + /***************************************************************************** * * Mutual exlusion within ACPICA subsystem @@ -167,7 +188,7 @@ ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; ****************************************************************************/ /* - * Predefined mutex objects. This array contains the + * Predefined mutex objects. This array contains the * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs. * (The table maps local handles to the real OS handles) */ @@ -176,7 +197,6 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; /* * Global lock semaphore works in conjunction with the actual HW global lock */ -ACPI_EXTERN acpi_mutex acpi_gbl_global_lock_mutex; ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; /* @@ -200,7 +220,6 @@ ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE regis ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list; ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list; -ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats; #endif /* Object caches */ @@ -221,6 +240,7 @@ ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; /* Misc */ +ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count; ACPI_EXTERN u32 acpi_gbl_original_mode; ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; @@ -240,19 +260,12 @@ ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_startup_flags; +extern const u8 acpi_gbl_decode_to8bit[8]; extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; extern const char *acpi_gbl_highest_dstate_names[4]; extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; -/* Exception codes */ - -extern char const *acpi_gbl_exception_names_env[]; -extern char const *acpi_gbl_exception_names_pgm[]; -extern char const *acpi_gbl_exception_names_tbl[]; -extern char const *acpi_gbl_exception_names_aml[]; -extern char const *acpi_gbl_exception_names_ctrl[]; - /***************************************************************************** * * Namespace globals diff --git a/trunk/include/acpi/achware.h b/trunk/include/acpi/achware.h index 9df275cf7bc1..29b60a8c0593 100644 --- a/trunk/include/acpi/achware.h +++ b/trunk/include/acpi/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,6 +61,8 @@ /* * hwacpi - high level functions */ +acpi_status acpi_hw_initialize(void); + acpi_status acpi_hw_set_mode(u32 mode); u32 acpi_hw_get_mode(void); @@ -82,7 +84,7 @@ acpi_hw_low_level_read(u32 width, acpi_status acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address *reg); -acpi_status acpi_hw_clear_acpi_status(void); +acpi_status acpi_hw_clear_acpi_status(u32 flags); /* * hwgpe - GPE support diff --git a/trunk/include/acpi/acinterp.h b/trunk/include/acpi/acinterp.h index ce7c9d653910..91586d0d5bb5 100644 --- a/trunk/include/acpi/acinterp.h +++ b/trunk/include/acpi/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -277,6 +277,12 @@ acpi_status acpi_ex_system_do_suspend(acpi_integer time); acpi_status acpi_ex_system_do_stall(u32 time); +acpi_status +acpi_ex_system_acquire_mutex(union acpi_operand_object *time, + union acpi_operand_object *obj_desc); + +acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc); + acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc); acpi_status @@ -445,14 +451,10 @@ acpi_ex_copy_integer_to_buffer_field(union acpi_operand_object *source_desc, /* * exutils - interpreter/scanner utilities */ -void acpi_ex_enter_interpreter(void); +acpi_status acpi_ex_enter_interpreter(void); void acpi_ex_exit_interpreter(void); -void acpi_ex_reacquire_interpreter(void); - -void acpi_ex_relinquish_interpreter(void); - void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc); u8 acpi_ex_acquire_global_lock(u32 rule); diff --git a/trunk/include/acpi/aclocal.h b/trunk/include/acpi/aclocal.h index 6f83ddbed3af..063c4b54290f 100644 --- a/trunk/include/acpi/aclocal.h +++ b/trunk/include/acpi/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,8 +80,8 @@ union acpi_parse_object; * table below also! */ #define ACPI_MTX_INTERPRETER 0 /* AML Interpreter, main lock */ -#define ACPI_MTX_NAMESPACE 1 /* ACPI Namespace */ -#define ACPI_MTX_TABLES 2 /* Data for ACPI tables */ +#define ACPI_MTX_TABLES 1 /* Data for ACPI tables */ +#define ACPI_MTX_NAMESPACE 2 /* ACPI Namespace */ #define ACPI_MTX_EVENTS 3 /* Data for ACPI events */ #define ACPI_MTX_CACHES 4 /* Internal caches, general purposes */ #define ACPI_MTX_MEMORY 5 /* Debug memory tracking lists */ @@ -162,7 +162,7 @@ struct acpi_mutex_info { typedef enum { ACPI_IMODE_LOAD_PASS1 = 0x01, ACPI_IMODE_LOAD_PASS2 = 0x02, - ACPI_IMODE_EXECUTE = 0x03 + ACPI_IMODE_EXECUTE = 0x0E } acpi_interpreter_mode; union acpi_name_union { @@ -204,7 +204,7 @@ struct acpi_namespace_node { /* Namespace Node flags */ #define ANOBJ_END_OF_PEER_LIST 0x01 /* End-of-list, Peer field points to parent */ -#define ANOBJ_TEMPORARY 0x02 /* Node is create by a method and is temporary */ +#define ANOBJ_RESERVED 0x02 /* Available for future use */ #define ANOBJ_METHOD_ARG 0x04 /* Node is a method argument */ #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ @@ -219,42 +219,25 @@ struct acpi_namespace_node { * ACPI Table Descriptor. One per ACPI table */ struct acpi_table_desc { - acpi_physical_address address; + struct acpi_table_desc *prev; + struct acpi_table_desc *next; + struct acpi_table_desc *installed_desc; struct acpi_table_header *pointer; - u32 length; /* Length fixed at 32 bits */ - union acpi_name_union signature; + u8 *aml_start; + u64 physical_address; + acpi_size length; + u32 aml_length; acpi_owner_id owner_id; - u8 flags; + u8 type; + u8 allocation; + u8 loaded_into_namespace; }; -/* Flags for above */ - -#define ACPI_TABLE_ORIGIN_UNKNOWN (0) -#define ACPI_TABLE_ORIGIN_MAPPED (1) -#define ACPI_TABLE_ORIGIN_ALLOCATED (2) -#define ACPI_TABLE_ORIGIN_MASK (3) -#define ACPI_TABLE_IS_LOADED (4) - -/* One internal RSDT for table management */ - -struct acpi_internal_rsdt { - struct acpi_table_desc *tables; +struct acpi_table_list { + struct acpi_table_desc *next; u32 count; - u32 size; - u8 flags; }; -/* Flags for above */ - -#define ACPI_ROOT_ORIGIN_UNKNOWN (0) /* ~ORIGIN_ALLOCATED */ -#define ACPI_ROOT_ORIGIN_ALLOCATED (1) -#define ACPI_ROOT_ALLOW_RESIZE (2) - -/* Predefined (fixed) table indexes */ - -#define ACPI_TABLE_INDEX_DSDT (0) -#define ACPI_TABLE_INDEX_FACS (1) - struct acpi_find_context { char *search_for; acpi_handle *list; @@ -367,7 +350,7 @@ struct acpi_gpe_event_info { union acpi_gpe_dispatch_info dispatch; /* Either Method or Handler */ struct acpi_gpe_register_info *register_info; /* Backpointer to register info */ u8 flags; /* Misc info about this GPE */ - u8 gpe_number; /* This GPE */ + u8 register_bit; /* This GPE bit within the register */ }; /* Information about a GPE register pair, one per each status/enable pair in an array */ @@ -872,30 +855,12 @@ struct acpi_bit_register_info { ****************************************************************************/ struct acpi_db_method_info { - acpi_handle main_thread_gate; - acpi_handle thread_complete_gate; - u32 *threads; - u32 num_threads; - u32 num_created; - u32 num_completed; - + acpi_handle thread_gate; char *name; + char **args; u32 flags; u32 num_loops; char pathname[128]; - char **args; - - /* - * Arguments to be passed to method for the command - * Threads - - * the Number of threads, ID of current thread and - * Index of current thread inside all them created. - */ - char init_args; - char *arguments[4]; - char num_threads_str[11]; - char id_of_thread_str[11]; - char index_of_thread_str[11]; }; struct acpi_integrity_info { @@ -954,8 +919,6 @@ struct acpi_memory_list { u32 total_allocated; u32 total_freed; - u32 max_occupied; - u32 total_size; u32 current_total_size; u32 requests; u32 hits; diff --git a/trunk/include/acpi/acmacros.h b/trunk/include/acpi/acmacros.h index 8948a6461834..192fa095a515 100644 --- a/trunk/include/acpi/acmacros.h +++ b/trunk/include/acpi/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,12 +55,25 @@ #define ACPI_SET_BIT(target,bit) ((target) |= (bit)) #define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) #define ACPI_MIN(a,b) (((a)<(b))?(a):(b)) -#define ACPI_MAX(a,b) (((a)>(b))?(a):(b)) /* Size calculation */ #define ACPI_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) +#if ACPI_MACHINE_WIDTH == 16 + +/* + * For 16-bit addresses, we have to assume that the upper 32 bits + * (out of 64) are zero. + */ +#define ACPI_LODWORD(l) ((u32)(l)) +#define ACPI_HIDWORD(l) ((u32)(0)) + +#define ACPI_GET_ADDRESS(a) ((a).lo) +#define ACPI_STORE_ADDRESS(a,b) {(a).hi=0;(a).lo=(u32)(b);} +#define ACPI_VALID_ADDRESS(a) ((a).hi | (a).lo) + +#else #ifdef ACPI_NO_INTEGER64_SUPPORT /* * acpi_integer is 32-bits, no 64-bit support on this platform @@ -68,6 +81,10 @@ #define ACPI_LODWORD(l) ((u32)(l)) #define ACPI_HIDWORD(l) ((u32)(0)) +#define ACPI_GET_ADDRESS(a) (a) +#define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) +#define ACPI_VALID_ADDRESS(a) (a) + #else /* @@ -75,6 +92,11 @@ */ #define ACPI_LODWORD(l) ((u32)(u64)(l)) #define ACPI_HIDWORD(l) ((u32)(((*(struct uint64_struct *)(void *)(&l))).hi)) + +#define ACPI_GET_ADDRESS(a) (a) +#define ACPI_STORE_ADDRESS(a,b) ((a)=(acpi_physical_address)(b)) +#define ACPI_VALID_ADDRESS(a) (a) +#endif #endif /* @@ -112,8 +134,15 @@ #define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i) #define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) #define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) + +#if ACPI_MACHINE_WIDTH == 16 +#define ACPI_STORE_POINTER(d,s) ACPI_MOVE_32_TO_32(d,s) +#define ACPI_PHYSADDR_TO_PTR(i) (void *)(i) +#define ACPI_PTR_TO_PHYSADDR(i) (u32) ACPI_CAST_PTR (u8,(i)) +#else #define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) #define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) +#endif #ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED #define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32,(a)) == *ACPI_CAST_PTR (u32,(b))) @@ -194,6 +223,28 @@ /* The hardware supports unaligned transfers, just do the little-endian move */ +#if ACPI_MACHINE_WIDTH == 16 + +/* No 64-bit integers */ +/* 16-bit source, 16/32/64 destination */ + +#define ACPI_MOVE_16_TO_16(d,s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_16_TO_32(d,s) *(u32 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_16_TO_64(d,s) ACPI_MOVE_16_TO_32(d,s) + +/* 32-bit source, 16/32/64 destination */ + +#define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ +#define ACPI_MOVE_32_TO_32(d,s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s) +#define ACPI_MOVE_32_TO_64(d,s) ACPI_MOVE_32_TO_32(d,s) + +/* 64-bit source, 16/32/64 destination */ + +#define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ +#define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */ +#define ACPI_MOVE_64_TO_64(d,s) ACPI_MOVE_32_TO_32(d,s) + +#else /* 16-bit source, 16/32/64 destination */ #define ACPI_MOVE_16_TO_16(d,s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) @@ -211,6 +262,7 @@ #define ACPI_MOVE_64_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ #define ACPI_MOVE_64_TO_32(d,s) ACPI_MOVE_32_TO_32(d,s) /* Truncate to 32 */ #define ACPI_MOVE_64_TO_64(d,s) *(u64 *)(void *)(d) = *(u64 *)(void *)(s) +#endif #else /* @@ -255,7 +307,10 @@ /* Macros based on machine integer width */ -#if ACPI_MACHINE_WIDTH == 32 +#if ACPI_MACHINE_WIDTH == 16 +#define ACPI_MOVE_SIZE_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) + +#elif ACPI_MACHINE_WIDTH == 32 #define ACPI_MOVE_SIZE_TO_16(d,s) ACPI_MOVE_32_TO_16(d,s) #elif ACPI_MACHINE_WIDTH == 64 @@ -640,6 +695,16 @@ #define ACPI_DEBUGGER_EXEC(a) #endif +/* + * For 16-bit code, we want to shrink some things even though + * we are using ACPI_DEBUG_OUTPUT to get the debug output + */ +#if ACPI_MACHINE_WIDTH == 16 +#undef ACPI_DEBUG_ONLY_MEMBERS +#undef _VERBOSE_STRUCTURES +#define ACPI_DEBUG_ONLY_MEMBERS(a) +#endif + #ifdef ACPI_DEBUG_OUTPUT /* * 1) Set name to blanks diff --git a/trunk/include/acpi/acnames.h b/trunk/include/acpi/acnames.h index 34bfae8a05f3..b67da3636899 100644 --- a/trunk/include/acpi/acnames.h +++ b/trunk/include/acpi/acnames.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acnamesp.h b/trunk/include/acpi/acnamesp.h index 535b7e1c41bc..83b52f9f899a 100644 --- a/trunk/include/acpi/acnamesp.h +++ b/trunk/include/acpi/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,13 +65,9 @@ #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 +#define ACPI_NS_WALK_UNLOCK TRUE +#define ACPI_NS_WALK_NO_UNLOCK FALSE /* * nsinit - Namespace initialization @@ -86,7 +82,7 @@ acpi_status acpi_ns_initialize_devices(void); acpi_status acpi_ns_load_namespace(void); acpi_status -acpi_ns_load_table(acpi_native_uint table_index, +acpi_ns_load_table(struct acpi_table_desc *table_desc, struct acpi_namespace_node *node); /* @@ -96,7 +92,7 @@ acpi_status acpi_ns_walk_namespace(acpi_object_type type, acpi_handle start_object, u32 max_depth, - u32 flags, + u8 unlock_before_callback, acpi_walk_callback user_function, void *context, void **return_value); @@ -110,12 +106,11 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, * nsparse - table parsing */ acpi_status -acpi_ns_parse_table(acpi_native_uint table_index, - struct acpi_namespace_node *start_node); +acpi_ns_parse_table(struct acpi_table_desc *table_desc, + struct acpi_namespace_node *scope); acpi_status -acpi_ns_one_complete_parse(acpi_native_uint pass_number, - acpi_native_uint table_index); +acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc); /* * nsaccess - Top-level namespace access diff --git a/trunk/include/acpi/acobject.h b/trunk/include/acpi/acobject.h index 04e9735a6742..8fdee31119f3 100644 --- a/trunk/include/acpi/acobject.h +++ b/trunk/include/acpi/acobject.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,15 +52,7 @@ * to the interpreter, and to keep track of the various handlers such as * address space handlers and notify handlers. The object is a constant * size in order to allow it to be cached and reused. - * - * Note: The object is optimized to be aligned and will not work if it is - * byte-packed. */ -#if ACPI_MACHINE_WIDTH == 64 -#pragma pack(8) -#else -#pragma pack(4) -#endif /******************************************************************************* * @@ -109,8 +101,7 @@ struct acpi_object_common { ACPI_OBJECT_COMMON_HEADER}; struct acpi_object_integer { - ACPI_OBJECT_COMMON_HEADER u8 fill[3]; /* Prevent warning on some compilers */ - acpi_integer value; + ACPI_OBJECT_COMMON_HEADER acpi_integer value; }; /* @@ -212,9 +203,7 @@ struct acpi_object_power_resource { }; struct acpi_object_processor { - ACPI_OBJECT_COMMON_HEADER - /* The next two fields take advantage of the 3-byte space before NOTIFY_INFO */ - u8 proc_id; + ACPI_OBJECT_COMMON_HEADER u8 proc_id; u8 length; ACPI_COMMON_NOTIFY_INFO acpi_io_address address; }; @@ -417,6 +406,4 @@ union acpi_descriptor { union acpi_parse_object op; }; -#pragma pack() - #endif /* _ACOBJECT_H */ diff --git a/trunk/include/acpi/acopcode.h b/trunk/include/acpi/acopcode.h index e6f76a280a94..7659a46bc432 100644 --- a/trunk/include/acpi/acopcode.h +++ b/trunk/include/acpi/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -257,7 +257,7 @@ #define ARGI_LLESSEQUAL_OP ARGI_INVALID_OPCODE #define ARGI_LNOT_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_LNOTEQUAL_OP ARGI_INVALID_OPCODE -#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION_OR_BUFFER,ARGI_TARGETREF) +#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION_OR_FIELD,ARGI_TARGETREF) #define ARGI_LOAD_TABLE_OP ARGI_LIST6 (ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_ANYTYPE) #define ARGI_LOCAL0 ARG_NONE #define ARGI_LOCAL1 ARG_NONE diff --git a/trunk/include/acpi/acoutput.h b/trunk/include/acpi/acoutput.h index 7812267b577f..8d5039d0b430 100644 --- a/trunk/include/acpi/acoutput.h +++ b/trunk/include/acpi/acoutput.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acparser.h b/trunk/include/acpi/acparser.h index 85c358e21014..9d49d3c41cd9 100644 --- a/trunk/include/acpi/acparser.h +++ b/trunk/include/acpi/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acpi.h b/trunk/include/acpi/acpi.h index 2e5f00d3ea0d..b9a39d1009bd 100644 --- a/trunk/include/acpi/acpi.h +++ b/trunk/include/acpi/acpi.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index aef0e55253a9..fdd10953b2b6 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -59,6 +59,7 @@ acpi_evaluate_reference(acpi_handle handle, #define ACPI_BUS_FILE_ROOT "acpi" extern struct proc_dir_entry *acpi_root_dir; +extern struct fadt_descriptor acpi_fadt; enum acpi_bus_removal_type { ACPI_BUS_REMOVAL_NORMAL = 0, diff --git a/trunk/include/acpi/acpi_drivers.h b/trunk/include/acpi/acpi_drivers.h index baaa734b1098..6a5bdcefec64 100644 --- a/trunk/include/acpi/acpi_drivers.h +++ b/trunk/include/acpi/acpi_drivers.h @@ -37,7 +37,7 @@ /* _HID definitions */ #define ACPI_POWER_HID "ACPI_PWR" -#define ACPI_PROCESSOR_HID "ACPI0007" +#define ACPI_PROCESSOR_HID "ACPI_CPU" #define ACPI_SYSTEM_HID "ACPI_SYS" #define ACPI_THERMAL_HID "ACPI_THM" #define ACPI_BUTTON_HID_POWERF "ACPI_FPB" diff --git a/trunk/include/acpi/acpiosxf.h b/trunk/include/acpi/acpiosxf.h index 781394b9efe0..0cd63bce0ae4 100644 --- a/trunk/include/acpi/acpiosxf.h +++ b/trunk/include/acpi/acpiosxf.h @@ -8,7 +8,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,7 +85,7 @@ acpi_status acpi_os_terminate(void); /* * ACPI Table interfaces */ -acpi_physical_address acpi_os_get_root_pointer(void); +acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *address); acpi_status acpi_os_predefined_override(const struct acpi_predefined_names *init_val, @@ -143,7 +143,9 @@ void acpi_os_release_mutex(acpi_mutex handle); */ void *acpi_os_allocate(acpi_size size); -void __iomem *acpi_os_map_memory(acpi_physical_address where, acpi_native_uint length); +acpi_status +acpi_os_map_memory(acpi_physical_address physical_address, + acpi_size size, void __iomem ** logical_address); void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size); diff --git a/trunk/include/acpi/acpixf.h b/trunk/include/acpi/acpixf.h index e08f7df85a4f..81458767a90e 100644 --- a/trunk/include/acpi/acpixf.h +++ b/trunk/include/acpi/acpixf.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,10 +51,6 @@ /* * Global interfaces */ -acpi_status -acpi_initialize_tables(struct acpi_table_desc *initial_storage, - u32 initial_table_count, u8 allow_resize); - acpi_status acpi_initialize_subsystem(void); acpi_status acpi_enable_subsystem(u32 flags); @@ -96,28 +92,30 @@ void acpi_free(void *address); /* * ACPI table manipulation interfaces */ -acpi_status acpi_reallocate_root_table(void); - -acpi_status acpi_find_root_pointer(acpi_native_uint * rsdp_address); +acpi_status +acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address); acpi_status acpi_load_tables(void); acpi_status acpi_load_table(struct acpi_table_header *table_ptr); -acpi_status acpi_unload_table_id(acpi_owner_id id); +acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id); +#ifdef ACPI_FUTURE_USAGE +acpi_status acpi_unload_table(acpi_table_type table_type); acpi_status -acpi_get_table_header(acpi_string signature, - acpi_native_uint instance, - struct acpi_table_header *out_table_header); +acpi_get_table_header(acpi_table_type table_type, + u32 instance, struct acpi_table_header *out_table_header); +#endif /* ACPI_FUTURE_USAGE */ acpi_status -acpi_get_table(acpi_string signature, - acpi_native_uint instance, struct acpi_table_header **out_table); +acpi_get_table(acpi_table_type table_type, + u32 instance, struct acpi_buffer *ret_buffer); acpi_status -acpi_get_table_by_index(acpi_native_uint table_index, - struct acpi_table_header **out_table); +acpi_get_firmware_table(acpi_string signature, + u32 instance, + u32 flags, struct acpi_table_header **table_pointer); /* * Namespace and name interfaces @@ -312,9 +310,9 @@ acpi_resource_to_address64(struct acpi_resource *resource, /* * Hardware (ACPI device) interfaces */ -acpi_status acpi_get_register(u32 register_id, u32 * return_value); +acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags); -acpi_status acpi_set_register(u32 register_id, u32 value); +acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags); acpi_status acpi_set_firmware_waking_vector(acpi_physical_address physical_address); diff --git a/trunk/include/acpi/acresrc.h b/trunk/include/acpi/acresrc.h index 9486ab266a5e..80a3b33571b4 100644 --- a/trunk/include/acpi/acresrc.h +++ b/trunk/include/acpi/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/acstruct.h b/trunk/include/acpi/acstruct.h index aeb4498e5e06..5e8095f0f78f 100644 --- a/trunk/include/acpi/acstruct.h +++ b/trunk/include/acpi/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -139,8 +139,7 @@ struct acpi_init_walk_info { u16 buffer_init; u16 package_init; u16 object_count; - acpi_owner_id owner_id; - acpi_native_uint table_index; + struct acpi_table_desc *table_desc; }; struct acpi_get_devices_info { diff --git a/trunk/include/acpi/actables.h b/trunk/include/acpi/actables.h index 2b9f46f9da4d..4dbaf02fe526 100644 --- a/trunk/include/acpi/actables.h +++ b/trunk/include/acpi/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,75 +44,105 @@ #ifndef __ACTABLES_H__ #define __ACTABLES_H__ -acpi_status acpi_allocate_root_table(u32 initial_table_count); +/* Used in acpi_tb_map_acpi_table for size parameter if table header is to be used */ + +#define SIZE_IN_HEADER 0 /* - * tbfadt - FADT parse/convert/validate + * tbconvrt - Table conversion routines */ -void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags); +acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info); + +acpi_status acpi_tb_convert_table_fadt(void); -void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); +acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info); + +u32 +acpi_tb_get_table_count(struct rsdp_descriptor *RSDP, + struct acpi_table_header *RSDT); /* - * tbfind - find ACPI table + * tbget - Table "get" routines */ acpi_status -acpi_tb_find_table(char *signature, - char *oem_id, - char *oem_table_id, acpi_native_uint * table_index); +acpi_tb_get_table(struct acpi_pointer *address, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_table_header(struct acpi_pointer *address, + struct acpi_table_header *return_header); + +acpi_status +acpi_tb_get_table_body(struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_table_ptr(acpi_table_type table_type, + u32 instance, struct acpi_table_header **table_ptr_loc); + +acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address); + +void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address); + +acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr); /* - * tbinstal - Table removal and deletion + * tbgetall - get multiple required tables */ -acpi_status acpi_tb_resize_root_table_list(void); +acpi_status acpi_tb_get_required_tables(void); -acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); +/* + * tbinstall - Table installation + */ +acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info); acpi_status -acpi_tb_add_table(struct acpi_table_desc *table_desc, - acpi_native_uint * table_index); +acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type); acpi_status -acpi_tb_store_table(acpi_physical_address address, - struct acpi_table_header *table, - u32 length, u8 flags, acpi_native_uint * table_index); +acpi_tb_init_table_descriptor(acpi_table_type table_type, + struct acpi_table_desc *table_info); -void acpi_tb_delete_table(struct acpi_table_desc *table_desc); - -void acpi_tb_terminate(void); +/* + * tbremove - Table removal and deletion + */ +void acpi_tb_delete_all_tables(void); -void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index); +void acpi_tb_delete_tables_by_type(acpi_table_type type); -acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index); +void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc); -acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index); +struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc + *table_desc); +/* + * tbxfroot - RSDP, RSDT utilities + */ acpi_status -acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id); +acpi_tb_find_table(char *signature, + char *oem_id, + char *oem_table_id, struct acpi_table_header **table_ptr); -u8 acpi_tb_is_table_loaded(acpi_native_uint table_index); +acpi_status acpi_tb_get_table_rsdt(void); -void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded); +acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp); /* - * tbutils - table manager utilities + * tbutils - common table utilities */ -u8 acpi_tb_tables_loaded(void); +acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc); -void -acpi_tb_print_table_header(acpi_physical_address address, - struct acpi_table_header *header); +acpi_status +acpi_tb_verify_table_checksum(struct acpi_table_header *table_header); -u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length); +u8 acpi_tb_sum_table(void *buffer, u32 length); -acpi_status -acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length); +u8 acpi_tb_generate_checksum(struct acpi_table_header *table); -void -acpi_tb_install_table(acpi_physical_address address, - u8 flags, char *signature, acpi_native_uint table_index); +void acpi_tb_set_checksum(struct acpi_table_header *table); acpi_status -acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags); +acpi_tb_validate_table_header(struct acpi_table_header *table_header); #endif /* __ACTABLES_H__ */ diff --git a/trunk/include/acpi/actbl.h b/trunk/include/acpi/actbl.h index 09469e7db6a5..b125ceed9cb7 100644 --- a/trunk/include/acpi/actbl.h +++ b/trunk/include/acpi/actbl.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,15 +48,15 @@ * Values for description table header signatures. Useful because they make * it more difficult to inadvertently type in the wrong signature. */ -#define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */ -#define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */ -#define ACPI_SIG_FACS "FACS" /* Firmware ACPI Control Structure */ -#define ACPI_SIG_PSDT "PSDT" /* Persistent System Description Table */ -#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Pointer */ -#define ACPI_SIG_RSDT "RSDT" /* Root System Description Table */ -#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */ -#define ACPI_SIG_SSDT "SSDT" /* Secondary System Description Table */ -#define ACPI_RSDP_NAME "RSDP" /* Short name for RSDP, not signature */ +#define DSDT_SIG "DSDT" /* Differentiated System Description Table */ +#define FADT_SIG "FACP" /* Fixed ACPI Description Table */ +#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ +#define PSDT_SIG "PSDT" /* Persistent System Description Table */ +#define RSDP_SIG "RSD PTR " /* Root System Description Pointer */ +#define RSDT_SIG "RSDT" /* Root System Description Table */ +#define XSDT_SIG "XSDT" /* Extended System Description Table */ +#define SSDT_SIG "SSDT" /* Secondary System Description Table */ +#define RSDP_NAME "RSDP" /* * All tables and structures must be byte-packed to match the ACPI @@ -83,29 +83,27 @@ * ******************************************************************************/ +#define ACPI_TABLE_HEADER_DEF \ + char signature[4]; /* ASCII table signature */\ + u32 length; /* Length of table in bytes, including this header */\ + u8 revision; /* ACPI Specification minor version # */\ + u8 checksum; /* To make sum of entire table == 0 */\ + char oem_id[6]; /* ASCII OEM identification */\ + char oem_table_id[8]; /* ASCII OEM table identification */\ + u32 oem_revision; /* OEM revision number */\ + char asl_compiler_id[4]; /* ASCII ASL compiler vendor ID */\ + u32 asl_compiler_revision; /* ASL compiler version */ + struct acpi_table_header { - char signature[ACPI_NAME_SIZE]; /* ASCII table signature */ - u32 length; /* Length of table in bytes, including this header */ - u8 revision; /* ACPI Specification minor version # */ - u8 checksum; /* To make sum of entire table == 0 */ - char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */ - char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */ - u32 oem_revision; /* OEM revision number */ - char asl_compiler_id[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */ - u32 asl_compiler_revision; /* ASL compiler version */ -}; +ACPI_TABLE_HEADER_DEF}; /* * GAS - Generic Address Structure (ACPI 2.0+) - * - * Note: Since this structure is used in the ACPI tables, it is byte aligned. - * If misalignment is not supported, access to the Address field must be - * performed with care. */ struct acpi_generic_address { - u8 space_id; /* Address space where struct or register exists */ - u8 bit_width; /* Size in bits of given register */ - u8 bit_offset; /* Bit offset within the register */ + u8 address_space_id; /* Address space where struct or register exists */ + u8 register_bit_width; /* Size in bits of given register */ + u8 register_bit_offset; /* Bit offset within the register */ u8 access_width; /* Minimum Access size (ACPI 3.0) */ u64 address; /* 64-bit address of struct or register */ }; @@ -116,10 +114,10 @@ struct acpi_generic_address { * ******************************************************************************/ -struct acpi_table_rsdp { +struct rsdp_descriptor { char signature[8]; /* ACPI signature, contains "RSD PTR " */ u8 checksum; /* ACPI 1.0 checksum */ - char oem_id[ACPI_OEM_ID_SIZE]; /* OEM identification */ + char oem_id[6]; /* OEM identification */ u8 revision; /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */ u32 rsdt_physical_address; /* 32-bit physical address of the RSDT */ u32 length; /* Table length in bytes, including header (ACPI 2.0+) */ @@ -136,14 +134,12 @@ struct acpi_table_rsdp { * ******************************************************************************/ -struct acpi_table_rsdt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */ +struct rsdt_descriptor { + ACPI_TABLE_HEADER_DEF u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */ }; -struct acpi_table_xsdt { - struct acpi_table_header header; /* Common ACPI table header */ - u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ +struct xsdt_descriptor { + ACPI_TABLE_HEADER_DEF u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ }; /******************************************************************************* @@ -152,27 +148,36 @@ struct acpi_table_xsdt { * ******************************************************************************/ -struct acpi_table_facs { +struct facs_descriptor { char signature[4]; /* ASCII table signature */ u32 length; /* Length of structure, in bytes */ u32 hardware_signature; /* Hardware configuration signature */ u32 firmware_waking_vector; /* 32-bit physical address of the Firmware Waking Vector */ u32 global_lock; /* Global Lock for shared hardware resources */ - u32 flags; + + /* Flags (32 bits) */ + + u8 S4bios_f:1; /* 00: S4BIOS support is present */ + u8:7; /* 01-07: Reserved, must be zero */ + u8 reserved1[3]; /* 08-31: Reserved, must be zero */ + u64 xfirmware_waking_vector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */ u8 version; /* Version of this table (ACPI 2.0+) */ u8 reserved[31]; /* Reserved, must be zero */ }; -/* Flag macros */ - -#define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ - -/* Global lock flags */ - #define ACPI_GLOCK_PENDING 0x01 /* 00: Pending global lock ownership */ #define ACPI_GLOCK_OWNED 0x02 /* 01: Global lock is owned */ +/* + * Common FACS - This is a version-independent FACS structure used for internal use only + */ +struct acpi_common_facs { + u32 *global_lock; + u64 *firmware_waking_vector; + u8 vector_width; +}; + /******************************************************************************* * * FADT - Fixed ACPI Description Table (Signature "FACP") @@ -181,98 +186,121 @@ struct acpi_table_facs { /* Fields common to all versions of the FADT */ -struct acpi_table_fadt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 facs; /* 32-bit physical address of FACS */ - u32 dsdt; /* 32-bit physical address of DSDT */ - u8 model; /* System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */ - u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */ - u16 sci_interrupt; /* System vector of SCI interrupt */ - u32 smi_command; /* 32-bit Port address of SMI command port */ - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ - u8 S4bios_request; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 pstate_control; /* Processor performance state control */ - u32 pm1a_event_block; /* 32-bit Port address of Power Mgt 1a Event Reg Blk */ - u32 pm1b_event_block; /* 32-bit Port address of Power Mgt 1b Event Reg Blk */ - u32 pm1a_control_block; /* 32-bit Port address of Power Mgt 1a Control Reg Blk */ - u32 pm1b_control_block; /* 32-bit Port address of Power Mgt 1b Control Reg Blk */ - u32 pm2_control_block; /* 32-bit Port address of Power Mgt 2 Control Reg Blk */ - u32 pm_timer_block; /* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 gpe0_block; /* 32-bit Port address of General Purpose Event 0 Reg Blk */ - u32 gpe1_block; /* 32-bit Port address of General Purpose Event 1 Reg Blk */ - u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */ - u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */ - u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */ - u8 pm_timer_length; /* Byte Length of ports at pm_timer_block */ - u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */ - u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */ - u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */ - u8 cst_control; /* Support for the _CST object and C States change notification */ - u16 C2latency; /* Worst case HW latency to enter/exit C2 state */ - u16 C3latency; /* Worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Processor's memory cache line width, in bytes */ - u16 flush_stride; /* Number of flush strides that need to be read */ - u8 duty_offset; /* Processor duty cycle index in processor's P_CNT reg */ - u8 duty_width; /* Processor duty cycle value bit width in P_CNT register. */ - u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */ - u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* Index to century in RTC CMOS RAM */ - u16 boot_flags; /* IA-PC Boot Architecture Flags. See Table 5-10 for description */ - u8 reserved; /* Reserved, must be zero */ - u32 flags; /* Miscellaneous flag bits (see below for individual flags) */ - struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */ +#define ACPI_FADT_COMMON \ + ACPI_TABLE_HEADER_DEF \ + u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ \ + u32 V1_dsdt; /* 32-bit physical address of DSDT */ \ + u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ \ + u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ \ + u16 sci_int; /* System vector of SCI interrupt */ \ + u32 smi_cmd; /* Port address of SMI command port */ \ + u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ \ + u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ \ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ \ + u8 pstate_cnt; /* Processor performance state control*/ \ + u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a Event Reg Blk */ \ + u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b Event Reg Blk */ \ + u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ \ + u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ \ + u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ \ + u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \ + u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ \ + u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ \ + u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ \ + u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ \ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ \ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ \ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ \ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ \ + u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ \ + u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ \ + u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ \ + u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ \ + u16 flush_size; /* Processor's memory cache line width, in bytes */ \ + u16 flush_stride; /* Number of flush strides that need to be read */ \ + u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/ \ + u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/ \ + u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \ + u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \ + u8 century; /* Index to century in RTC CMOS RAM */ \ + u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ \ + u8 reserved2; /* Reserved, must be zero */ + +/* + * ACPI 2.0+ FADT + */ +struct fadt_descriptor { + ACPI_FADT_COMMON + /* Flags (32 bits) */ + u8 wb_invd:1; /* 00: The wbinvd instruction works properly */ + u8 wb_invd_flush:1; /* 01: The wbinvd flushes but does not invalidate */ + u8 proc_c1:1; /* 02: All processors support C1 state */ + u8 plvl2_up:1; /* 03: C2 state works on MP system */ + u8 pwr_button:1; /* 04: Power button is handled as a generic feature */ + u8 sleep_button:1; /* 05: Sleep button is handled as a generic feature, or not present */ + u8 fixed_rTC:1; /* 06: RTC wakeup stat not in fixed register space */ + u8 rtcs4:1; /* 07: RTC wakeup stat not possible from S4 */ + u8 tmr_val_ext:1; /* 08: tmr_val is 32 bits 0=24-bits */ + u8 dock_cap:1; /* 09: Docking supported */ + u8 reset_reg_sup:1; /* 10: System reset via the FADT RESET_REG supported */ + u8 sealed_case:1; /* 11: No internal expansion capabilities and case is sealed */ + u8 headless:1; /* 12: No local video capabilities or local input devices */ + u8 cpu_sw_sleep:1; /* 13: Must execute native instruction after writing SLP_TYPx register */ + + u8 pci_exp_wak:1; /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */ + u8 use_platform_clock:1; /* 15: OSPM should use platform-provided timer (ACPI 3.0) */ + u8 S4rtc_sts_valid:1; /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */ + u8 remote_power_on_capable:1; /* 17: System is compatible with remote power on (ACPI 3.0) */ + u8 force_apic_cluster_model:1; /* 18: All local APICs must use cluster model (ACPI 3.0) */ + u8 force_apic_physical_destination_mode:1; /* 19: All local x_aPICs must use physical dest mode (ACPI 3.0) */ + u8:4; /* 20-23: Reserved, must be zero */ + u8 reserved3; /* 24-31: Reserved, must be zero */ + + struct acpi_generic_address reset_register; /* Reset register address in GAS format */ u8 reset_value; /* Value to write to the reset_register port to reset the system */ - u8 reserved4[3]; /* Reserved, must be zero */ - u64 Xfacs; /* 64-bit physical address of FACS */ + u8 reserved4[3]; /* These three bytes must be zero */ + u64 xfirmware_ctrl; /* 64-bit physical address of FACS */ u64 Xdsdt; /* 64-bit physical address of DSDT */ - struct acpi_generic_address xpm1a_event_block; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */ - struct acpi_generic_address xpm1b_event_block; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */ - struct acpi_generic_address xpm1a_control_block; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */ - struct acpi_generic_address xpm1b_control_block; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */ - struct acpi_generic_address xpm2_control_block; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */ - struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ - struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */ - struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ + struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */ + struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */ + struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ + struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ + struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ + struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ + struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */ + struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */ }; -/* FADT flags */ - -#define ACPI_FADT_WBINVD (1) /* 00: The wbinvd instruction works properly */ -#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: The wbinvd flushes but does not invalidate */ -#define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: All processors support C1 state */ -#define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: C2 state works on MP system */ -#define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: Power button is handled as a generic feature */ -#define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: Sleep button is handled as a generic feature, or not present */ -#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: RTC wakeup stat not in fixed register space */ -#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: RTC wakeup stat not possible from S4 */ -#define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: tmr_val is 32 bits 0=24-bits */ -#define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: Docking supported */ -#define ACPI_FADT_RESET_REGISTER (1<<10) /* 10: System reset via the FADT RESET_REG supported */ -#define ACPI_FADT_SEALED_CASE (1<<11) /* 11: No internal expansion capabilities and case is sealed */ -#define ACPI_FADT_HEADLESS (1<<12) /* 12: No local video capabilities or local input devices */ -#define ACPI_FADT_SLEEP_TYPE (1<<13) /* 13: Must execute native instruction after writing SLP_TYPx register */ -#define ACPI_FADT_PCI_EXPRESS_WAKE (1<<14) /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */ -#define ACPI_FADT_PLATFORM_CLOCK (1<<15) /* 15: OSPM should use platform-provided timer (ACPI 3.0) */ -#define ACPI_FADT_S4_RTC_VALID (1<<16) /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */ -#define ACPI_FADT_REMOTE_POWER_ON (1<<17) /* 17: System is compatible with remote power on (ACPI 3.0) */ -#define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: All local APICs must use cluster model (ACPI 3.0) */ -#define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: All local x_aPICs must use physical dest mode (ACPI 3.0) */ +/* + * "Down-revved" ACPI 2.0 FADT descriptor + * Defined here to allow compiler to generate the length of the struct + */ +struct fadt_descriptor_rev2_minus { + ACPI_FADT_COMMON u32 flags; + struct acpi_generic_address reset_register; /* Reset register address in GAS format */ + u8 reset_value; /* Value to write to the reset_register port to reset the system. */ + u8 reserved7[3]; /* Reserved, must be zero */ +}; /* - * FADT Prefered Power Management Profiles + * ACPI 1.0 FADT + * Defined here to allow compiler to generate the length of the struct */ -enum acpi_prefered_pm_profiles { - PM_UNSPECIFIED = 0, - PM_DESKTOP = 1, - PM_MOBILE = 2, - PM_WORKSTATION = 3, - PM_ENTERPRISE_SERVER = 4, - PM_SOHO_SERVER = 5, - PM_APPLIANCE_PC = 6 +struct fadt_descriptor_rev1 { + ACPI_FADT_COMMON u32 flags; }; -/* FADT Boot Arch Flags */ +/* FADT: Prefered Power Management Profiles */ + +#define PM_UNSPECIFIED 0 +#define PM_DESKTOP 1 +#define PM_MOBILE 2 +#define PM_WORKSTATION 3 +#define PM_ENTERPRISE_SERVER 4 +#define PM_SOHO_SERVER 5 +#define PM_APPLIANCE_PC 6 + +/* FADT: Boot Arch Flags */ #define BAF_LEGACY_DEVICES 0x0001 #define BAF_8042_KEYBOARD_CONTROLLER 0x0002 @@ -284,12 +312,59 @@ enum acpi_prefered_pm_profiles { #pragma pack() -#define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_fadt, f) - +/* + * This macro is temporary until the table bitfield flag definitions + * are removed and replaced by a Flags field. + */ +#define ACPI_FLAG_OFFSET(d,f,o) (u8) (ACPI_OFFSET (d,f) + \ + sizeof(((d *)0)->f) + o) /* * Get the remaining ACPI tables */ +#include "actbl1.h" + +/* + * ACPI Table information. We save the table address, length, + * and type of memory allocation (mapped or allocated) for each + * table for 1) when we exit, and 2) if a new table is installed + */ +#define ACPI_MEM_NOT_ALLOCATED 0 +#define ACPI_MEM_ALLOCATED 1 +#define ACPI_MEM_MAPPED 2 + +/* Definitions for the Flags bitfield member of struct acpi_table_support */ + +#define ACPI_TABLE_SINGLE 0x00 +#define ACPI_TABLE_MULTIPLE 0x01 +#define ACPI_TABLE_EXECUTABLE 0x02 + +#define ACPI_TABLE_ROOT 0x00 +#define ACPI_TABLE_PRIMARY 0x10 +#define ACPI_TABLE_SECONDARY 0x20 +#define ACPI_TABLE_ALL 0x30 +#define ACPI_TABLE_TYPE_MASK 0x30 + +/* Data about each known table type */ + +struct acpi_table_support { + char *name; + char *signature; + void **global_ptr; + u8 sig_length; + u8 flags; +}; + +extern u8 acpi_fadt_is_v1; /* is set to 1 if FADT is revision 1, + * needed for certain workarounds */ +/* Macros used to generate offsets to specific table fields */ + +#define ACPI_FACS_OFFSET(f) (u8) ACPI_OFFSET (struct facs_descriptor,f) +#define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct fadt_descriptor, f) +#define ACPI_GAS_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_generic_address,f) +#define ACPI_HDR_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_header,f) +#define ACPI_RSDP_OFFSET(f) (u8) ACPI_OFFSET (struct rsdp_descriptor,f) -#include +#define ACPI_FADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct fadt_descriptor,f,o) +#define ACPI_FACS_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct facs_descriptor,f,o) #endif /* __ACTBL_H__ */ diff --git a/trunk/include/acpi/actbl1.h b/trunk/include/acpi/actbl1.h index 4e5d3ca53a8e..745a6445a4f9 100644 --- a/trunk/include/acpi/actbl1.h +++ b/trunk/include/acpi/actbl1.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,6 @@ #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ -#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ @@ -74,6 +73,12 @@ #define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ #define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ +/* Legacy names */ + +#define APIC_SIG "APIC" /* Multiple APIC Description Table */ +#define BOOT_SIG "BOOT" /* Simple Boot Flag Table */ +#define SBST_SIG "SBST" /* Smart Battery Specification Table */ + /* * All tables must be byte-packed to match the ACPI specification, since * the tables are provided by the system BIOS. @@ -86,43 +91,31 @@ * portable, so do not use any other bitfield types. */ -/* Common Sub-table header (used in MADT, SRAT, etc.) */ - -struct acpi_subtable_header { - u8 type; - u8 length; -}; - /******************************************************************************* * * ASF - Alert Standard Format table (Signature "ASF!") * - * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 - * ******************************************************************************/ struct acpi_table_asf { - struct acpi_table_header header; /* Common ACPI table header */ -}; +ACPI_TABLE_HEADER_DEF}; -/* ASF subtable header */ +#define ACPI_ASF_HEADER_DEF \ + u8 type; \ + u8 reserved; \ + u16 length; struct acpi_asf_header { - u8 type; - u8 reserved; - u16 length; -}; +ACPI_ASF_HEADER_DEF}; -/* Values for Type field above */ +/* Values for Type field */ -enum acpi_asf_type { - ACPI_ASF_TYPE_INFO = 0, - ACPI_ASF_TYPE_ALERT = 1, - ACPI_ASF_TYPE_CONTROL = 2, - ACPI_ASF_TYPE_BOOT = 3, - ACPI_ASF_TYPE_ADDRESS = 4, - ACPI_ASF_TYPE_RESERVED = 5 -}; +#define ASF_INFO 0 +#define ASF_ALERT 1 +#define ASF_CONTROL 2 +#define ASF_BOOT 3 +#define ASF_ADDRESS 4 +#define ASF_RESERVED 5 /* * ASF subtables @@ -131,8 +124,7 @@ enum acpi_asf_type { /* 0: ASF Information */ struct acpi_asf_info { - struct acpi_asf_header header; - u8 min_reset_value; + ACPI_ASF_HEADER_DEF u8 min_reset_value; u8 min_poll_interval; u16 system_id; u32 mfg_id; @@ -143,49 +135,26 @@ struct acpi_asf_info { /* 1: ASF Alerts */ struct acpi_asf_alert { - struct acpi_asf_header header; - u8 assert_mask; + ACPI_ASF_HEADER_DEF u8 assert_mask; u8 deassert_mask; u8 alerts; u8 data_length; -}; - -struct acpi_asf_alert_data { - u8 address; - u8 command; - u8 mask; - u8 value; - u8 sensor_type; - u8 type; - u8 offset; - u8 source_type; - u8 severity; - u8 sensor_number; - u8 entity; - u8 instance; + u8 array[1]; }; /* 2: ASF Remote Control */ struct acpi_asf_remote { - struct acpi_asf_header header; - u8 controls; + ACPI_ASF_HEADER_DEF u8 controls; u8 data_length; u16 reserved2; -}; - -struct acpi_asf_control_data { - u8 function; - u8 address; - u8 command; - u8 value; + u8 array[1]; }; /* 3: ASF RMCP Boot Options */ struct acpi_asf_rmcp { - struct acpi_asf_header header; - u8 capabilities[7]; + ACPI_ASF_HEADER_DEF u8 capabilities[7]; u8 completion_code; u32 enterprise_id; u8 command; @@ -197,9 +166,9 @@ struct acpi_asf_rmcp { /* 4: ASF Address */ struct acpi_asf_address { - struct acpi_asf_header header; - u8 eprom_address; + ACPI_ASF_HEADER_DEF u8 eprom_address; u8 devices; + u8 smbus_addresses[1]; }; /******************************************************************************* @@ -209,8 +178,7 @@ struct acpi_asf_address { ******************************************************************************/ struct acpi_table_boot { - struct acpi_table_header header; /* Common ACPI table header */ - u8 cmos_index; /* Index in CMOS RAM for the boot register */ + ACPI_TABLE_HEADER_DEF u8 cmos_index; /* Index in CMOS RAM for the boot register */ u8 reserved[3]; }; @@ -221,8 +189,7 @@ struct acpi_table_boot { ******************************************************************************/ struct acpi_table_cpep { - struct acpi_table_header header; /* Common ACPI table header */ - u64 reserved; + ACPI_TABLE_HEADER_DEF u64 reserved; }; /* Subtable */ @@ -230,9 +197,9 @@ struct acpi_table_cpep { struct acpi_cpep_polling { u8 type; u8 length; - u8 id; /* Processor ID */ - u8 eid; /* Processor EID */ - u32 interval; /* Polling interval (msec) */ + u8 processor_id; /* Processor ID */ + u8 processor_eid; /* Processor EID */ + u32 polling_interval; /* Polling interval (msec) */ }; /******************************************************************************* @@ -242,97 +209,23 @@ struct acpi_cpep_polling { ******************************************************************************/ struct acpi_table_dbgp { - struct acpi_table_header header; /* Common ACPI table header */ - u8 type; /* 0=full 16550, 1=subset of 16550 */ + ACPI_TABLE_HEADER_DEF u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ u8 reserved[3]; struct acpi_generic_address debug_port; }; -/******************************************************************************* - * - * DMAR - DMA Remapping table - * - ******************************************************************************/ - -struct acpi_table_dmar { - struct acpi_table_header header; /* Common ACPI table header */ - u8 width; /* Host Address Width */ - u8 reserved[11]; -}; - -/* DMAR subtable header */ - -struct acpi_dmar_header { - u16 type; - u16 length; - u8 flags; - u8 reserved[3]; -}; - -/* Values for subtable type in struct acpi_dmar_header */ - -enum acpi_dmar_type { - ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, - ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, - ACPI_DMAR_TYPE_RESERVED = 2 /* 2 and greater are reserved */ -}; - -struct acpi_dmar_device_scope { - u8 entry_type; - u8 length; - u8 segment; - u8 bus; -}; - -/* Values for entry_type in struct acpi_dmar_device_scope */ - -enum acpi_dmar_scope_type { - ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, - ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, - ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, - ACPI_DMAR_SCOPE_TYPE_RESERVED = 3 /* 3 and greater are reserved */ -}; - -/* - * DMAR Sub-tables, correspond to Type in struct acpi_dmar_header - */ - -/* 0: Hardware Unit Definition */ - -struct acpi_dmar_hardware_unit { - struct acpi_dmar_header header; - u64 address; /* Register Base Address */ -}; - -/* Flags */ - -#define ACPI_DMAR_INCLUDE_ALL (1) - -/* 1: Reserved Memory Defininition */ - -struct acpi_dmar_reserved_memory { - struct acpi_dmar_header header; - u64 address; /* 4_k aligned base address */ - u64 end_address; /* 4_k aligned limit address */ -}; - -/* Flags */ - -#define ACPI_DMAR_ALLOW_ALL (1) - /******************************************************************************* * * ECDT - Embedded Controller Boot Resources Table * ******************************************************************************/ -struct acpi_table_ecdt { - struct acpi_table_header header; /* Common ACPI table header */ - struct acpi_generic_address control; /* Address of EC command/status register */ - struct acpi_generic_address data; /* Address of EC data register */ +struct ec_boot_resources { + ACPI_TABLE_HEADER_DEF struct acpi_generic_address ec_control; /* Address of EC command/status register */ + struct acpi_generic_address ec_data; /* Address of EC data register */ u32 uid; /* Unique ID - must be same as the EC _UID method */ - u8 gpe; /* The GPE for the EC */ - u8 id[1]; /* Full namepath of the EC in the ACPI namespace */ + u8 gpe_bit; /* The GPE for the EC */ + u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */ }; /******************************************************************************* @@ -341,22 +234,22 @@ struct acpi_table_ecdt { * ******************************************************************************/ -struct acpi_table_hpet { - struct acpi_table_header header; /* Common ACPI table header */ - u32 id; /* Hardware ID of event timer block */ - struct acpi_generic_address address; /* Address of event timer block */ - u8 sequence; /* HPET sequence number */ - u16 minimum_tick; /* Main counter min tick, periodic mode */ - u8 flags; +struct acpi_hpet_table { + ACPI_TABLE_HEADER_DEF u32 hardware_id; /* Hardware ID of event timer block */ + struct acpi_generic_address base_address; /* Address of event timer block */ + u8 hpet_number; /* HPET sequence number */ + u16 clock_tick; /* Main counter min tick, periodic mode */ + u8 attributes; }; -/*! Flags */ - -#define ACPI_HPET_PAGE_PROTECT (1) /* 00: No page protection */ -#define ACPI_HPET_PAGE_PROTECT_4 (1<<1) /* 01: 4KB page protected */ -#define ACPI_HPET_PAGE_PROTECT_64 (1<<2) /* 02: 64KB page protected */ - -/*! [End] no source code translation !*/ +#if 0 /* HPET flags to be converted to macros */ +struct { /* Flags (8 bits) */ + u8 page_protect:1; /* 00: No page protection */ + u8 page_protect4:1; /* 01: 4_kB page protected */ + u8 page_protect64:1; /* 02: 64_kB page protected */ + u8:5; /* 03-07: Reserved, must be zero */ +} flags; +#endif /******************************************************************************* * @@ -364,159 +257,148 @@ struct acpi_table_hpet { * ******************************************************************************/ -struct acpi_table_madt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 address; /* Physical address of local APIC */ - u32 flags; +struct multiple_apic_table { + ACPI_TABLE_HEADER_DEF u32 local_apic_address; /* Physical address of local APIC */ + + /* Flags (32 bits) */ + + u8 PCATcompat:1; /* 00: System also has dual 8259s */ + u8:7; /* 01-07: Reserved, must be zero */ + u8 reserved1[3]; /* 08-31: Reserved, must be zero */ }; -/* Flags */ +/* Values for MADT PCATCompat */ -#define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 -/* Values for PCATCompat flag */ +/* Common MADT Sub-table header */ -#define ACPI_MADT_DUAL_PIC 0 -#define ACPI_MADT_MULTIPLE_APIC 1 +#define APIC_HEADER_DEF \ + u8 type; \ + u8 length; -/* Values for subtable type in struct acpi_subtable_header */ +struct apic_header { +APIC_HEADER_DEF}; -enum acpi_madt_type { - ACPI_MADT_TYPE_LOCAL_APIC = 0, - ACPI_MADT_TYPE_IO_APIC = 1, - ACPI_MADT_TYPE_INTERRUPT_OVERRIDE = 2, - ACPI_MADT_TYPE_NMI_SOURCE = 3, - ACPI_MADT_TYPE_LOCAL_APIC_NMI = 4, - ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE = 5, - ACPI_MADT_TYPE_IO_SAPIC = 6, - ACPI_MADT_TYPE_LOCAL_SAPIC = 7, - ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8, - ACPI_MADT_TYPE_RESERVED = 9 /* 9 and greater are reserved */ -}; +/* Values for Type in struct apic_header */ + +#define APIC_PROCESSOR 0 +#define APIC_IO 1 +#define APIC_XRUPT_OVERRIDE 2 +#define APIC_NMI 3 +#define APIC_LOCAL_NMI 4 +#define APIC_ADDRESS_OVERRIDE 5 +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 +#define APIC_XRUPT_SOURCE 8 +#define APIC_RESERVED 9 /* 9 and greater are reserved */ + +/* Flag definitions for MADT sub-tables */ + +#define ACPI_MADT_IFLAGS /* INTI flags (16 bits) */ \ + u8 polarity : 2; /* 00-01: Polarity of APIC I/O input signals */\ + u8 trigger_mode : 2; /* 02-03: Trigger mode of APIC input signals */\ + u8 : 4; /* 04-07: Reserved, must be zero */\ + u8 reserved1; /* 08-15: Reserved, must be zero */ + +#define ACPI_MADT_LFLAGS /* Local Sapic flags (32 bits) */ \ + u8 processor_enabled: 1; /* 00: Processor is usable if set */\ + u8 : 7; /* 01-07: Reserved, must be zero */\ + u8 reserved2[3]; /* 08-31: Reserved, must be zero */ + +/* Values for MPS INTI flags */ + +#define POLARITY_CONFORMS 0 +#define POLARITY_ACTIVE_HIGH 1 +#define POLARITY_RESERVED 2 +#define POLARITY_ACTIVE_LOW 3 + +#define TRIGGER_CONFORMS 0 +#define TRIGGER_EDGE 1 +#define TRIGGER_RESERVED 2 +#define TRIGGER_LEVEL 3 /* - * MADT Sub-tables, correspond to Type in struct acpi_subtable_header + * MADT Sub-tables, correspond to Type in struct apic_header */ -/* 0: Processor Local APIC */ +/* 0: processor APIC */ -struct acpi_madt_local_apic { - struct acpi_subtable_header header; - u8 processor_id; /* ACPI processor id */ - u8 id; /* Processor's local APIC id */ - u32 lapic_flags; -}; +struct madt_processor_apic { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + u8 local_apic_id; /* Processor's local APIC id */ + ACPI_MADT_LFLAGS}; /* 1: IO APIC */ -struct acpi_madt_io_apic { - struct acpi_subtable_header header; - u8 id; /* I/O APIC ID */ +struct madt_io_apic { + APIC_HEADER_DEF u8 io_apic_id; /* I/O APIC ID */ u8 reserved; /* Reserved - must be zero */ u32 address; /* APIC physical address */ - u32 global_irq_base; /* Global system interrupt where INTI lines start */ + u32 interrupt; /* Global system interrupt where INTI lines start */ }; /* 2: Interrupt Override */ -struct acpi_madt_interrupt_override { - struct acpi_subtable_header header; - u8 bus; /* 0 - ISA */ - u8 source_irq; /* Interrupt source (IRQ) */ - u32 global_irq; /* Global system interrupt */ - u16 inti_flags; -}; +struct madt_interrupt_override { + APIC_HEADER_DEF u8 bus; /* 0 - ISA */ + u8 source; /* Interrupt source (IRQ) */ + u32 interrupt; /* Global system interrupt */ + ACPI_MADT_IFLAGS}; -/* 3: NMI Source */ +/* 3: NMI Sources */ -struct acpi_madt_nmi_source { - struct acpi_subtable_header header; - u16 inti_flags; - u32 global_irq; /* Global system interrupt */ +struct madt_nmi_source { + APIC_HEADER_DEF ACPI_MADT_IFLAGS u32 interrupt; /* Global system interrupt */ }; /* 4: Local APIC NMI */ -struct acpi_madt_local_apic_nmi { - struct acpi_subtable_header header; - u8 processor_id; /* ACPI processor id */ - u16 inti_flags; - u8 lint; /* LINTn to which NMI is connected */ +struct madt_local_apic_nmi { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + ACPI_MADT_IFLAGS u8 lint; /* LINTn to which NMI is connected */ }; /* 5: Address Override */ -struct acpi_madt_local_apic_override { - struct acpi_subtable_header header; - u16 reserved; /* Reserved, must be zero */ +struct madt_address_override { + APIC_HEADER_DEF u16 reserved; /* Reserved, must be zero */ u64 address; /* APIC physical address */ }; /* 6: I/O Sapic */ -struct acpi_madt_io_sapic { - struct acpi_subtable_header header; - u8 id; /* I/O SAPIC ID */ +struct madt_io_sapic { + APIC_HEADER_DEF u8 io_sapic_id; /* I/O SAPIC ID */ u8 reserved; /* Reserved, must be zero */ - u32 global_irq_base; /* Global interrupt for SAPIC start */ + u32 interrupt_base; /* Glocal interrupt for SAPIC start */ u64 address; /* SAPIC physical address */ }; /* 7: Local Sapic */ -struct acpi_madt_local_sapic { - struct acpi_subtable_header header; - u8 processor_id; /* ACPI processor id */ - u8 id; /* SAPIC ID */ - u8 eid; /* SAPIC EID */ +struct madt_local_sapic { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + u8 local_sapic_id; /* SAPIC ID */ + u8 local_sapic_eid; /* SAPIC EID */ u8 reserved[3]; /* Reserved, must be zero */ - u32 lapic_flags; - u32 uid; /* Numeric UID - ACPI 3.0 */ - char uid_string[1]; /* String UID - ACPI 3.0 */ + ACPI_MADT_LFLAGS u32 processor_uID; /* Numeric UID - ACPI 3.0 */ + char processor_uIDstring[1]; /* String UID - ACPI 3.0 */ }; /* 8: Platform Interrupt Source */ -struct acpi_madt_interrupt_source { - struct acpi_subtable_header header; - u16 inti_flags; - u8 type; /* 1=PMI, 2=INIT, 3=corrected */ - u8 id; /* Processor ID */ - u8 eid; /* Processor EID */ +struct madt_interrupt_source { + APIC_HEADER_DEF ACPI_MADT_IFLAGS u8 interrupt_type; /* 1=PMI, 2=INIT, 3=corrected */ + u8 processor_id; /* Processor ID */ + u8 processor_eid; /* Processor EID */ u8 io_sapic_vector; /* Vector value for PMI interrupts */ - u32 global_irq; /* Global system interrupt */ + u32 interrupt; /* Global system interrupt */ u32 flags; /* Interrupt Source Flags */ }; -/* Flags field above */ - -#define ACPI_MADT_CPEI_OVERRIDE (1) - -/* - * Common flags fields for MADT subtables - */ - -/* MADT Local APIC flags (lapic_flags) */ - -#define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */ - -/* MADT MPS INTI flags (inti_flags) */ - -#define ACPI_MADT_POLARITY_MASK (3) /* 00-01: Polarity of APIC I/O input signals */ -#define ACPI_MADT_TRIGGER_MASK (3<<2) /* 02-03: Trigger mode of APIC input signals */ - -/* Values for MPS INTI flags */ - -#define ACPI_MADT_POLARITY_CONFORMS 0 -#define ACPI_MADT_POLARITY_ACTIVE_HIGH 1 -#define ACPI_MADT_POLARITY_RESERVED 2 -#define ACPI_MADT_POLARITY_ACTIVE_LOW 3 - -#define ACPI_MADT_TRIGGER_CONFORMS (0) -#define ACPI_MADT_TRIGGER_EDGE (1<<2) -#define ACPI_MADT_TRIGGER_RESERVED (2<<2) -#define ACPI_MADT_TRIGGER_LEVEL (3<<2) - +#ifdef DUPLICATE_DEFINITION_WITH_LINUX_ACPI_H /******************************************************************************* * * MCFG - PCI Memory Mapped Configuration table and sub-table @@ -524,19 +406,17 @@ struct acpi_madt_interrupt_source { ******************************************************************************/ struct acpi_table_mcfg { - struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved[8]; + ACPI_TABLE_HEADER_DEF u8 reserved[8]; }; -/* Subtable */ - struct acpi_mcfg_allocation { - u64 address; /* Base address, processor-relative */ + u64 base_address; /* Base address, processor-relative */ u16 pci_segment; /* PCI segment group number */ u8 start_bus_number; /* Starting PCI Bus number */ u8 end_bus_number; /* Final PCI Bus number */ u32 reserved; }; +#endif /******************************************************************************* * @@ -544,9 +424,8 @@ struct acpi_mcfg_allocation { * ******************************************************************************/ -struct acpi_table_sbst { - struct acpi_table_header header; /* Common ACPI table header */ - u32 warning_level; +struct smart_battery_table { + ACPI_TABLE_HEADER_DEF u32 warning_level; u32 low_level; u32 critical_level; }; @@ -557,10 +436,9 @@ struct acpi_table_sbst { * ******************************************************************************/ -struct acpi_table_slit { - struct acpi_table_header header; /* Common ACPI table header */ - u64 locality_count; - u8 entry[1]; /* Real size = localities^2 */ +struct system_locality_info { + ACPI_TABLE_HEADER_DEF u64 locality_count; + u8 entry[1][1]; }; /******************************************************************************* @@ -570,8 +448,7 @@ struct acpi_table_slit { ******************************************************************************/ struct acpi_table_spcr { - struct acpi_table_header header; /* Common ACPI table header */ - u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ + ACPI_TABLE_HEADER_DEF u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ u8 reserved[3]; struct acpi_generic_address serial_port; u8 interrupt_type; @@ -582,7 +459,7 @@ struct acpi_table_spcr { u8 stop_bits; u8 flow_control; u8 terminal_type; - u8 reserved1; + u8 reserved2; u16 pci_device_id; u16 pci_vendor_id; u8 pci_bus; @@ -590,7 +467,7 @@ struct acpi_table_spcr { u8 pci_function; u32 pci_flags; u8 pci_segment; - u32 reserved2; + u32 reserved3; }; /******************************************************************************* @@ -600,13 +477,12 @@ struct acpi_table_spcr { ******************************************************************************/ struct acpi_table_spmi { - struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved; + ACPI_TABLE_HEADER_DEF u8 reserved; u8 interface_type; u16 spec_revision; /* Version of IPMI */ u8 interrupt_type; u8 gpe_number; /* GPE assigned */ - u8 reserved1; + u8 reserved2; u8 pci_device_flag; u32 interrupt; struct acpi_generic_address ipmi_register; @@ -622,52 +498,57 @@ struct acpi_table_spmi { * ******************************************************************************/ -struct acpi_table_srat { - struct acpi_table_header header; /* Common ACPI table header */ - u32 table_revision; /* Must be value '1' */ - u64 reserved; /* Reserved, must be zero */ +struct system_resource_affinity { + ACPI_TABLE_HEADER_DEF u32 reserved1; /* Must be value '1' */ + u64 reserved2; /* Reserved, must be zero */ }; -/* Values for subtable type in struct acpi_subtable_header */ +/* SRAT common sub-table header */ -enum acpi_srat_type { - ACPI_SRAT_TYPE_CPU_AFFINITY = 0, - ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1, - ACPI_SRAT_TYPE_RESERVED = 2 -}; +#define SRAT_SUBTABLE_HEADER \ + u8 type; \ + u8 length; + +/* Values for Type above */ + +#define SRAT_CPU_AFFINITY 0 +#define SRAT_MEMORY_AFFINITY 1 +#define SRAT_RESERVED 2 /* SRAT sub-tables */ -struct acpi_srat_cpu_affinity { - struct acpi_subtable_header header; - u8 proximity_domain_lo; +struct static_resource_alloc { + SRAT_SUBTABLE_HEADER u8 proximity_domain_lo; u8 apic_id; - u32 flags; + + /* Flags (32 bits) */ + + u8 enabled:1; /* 00: Use affinity structure */ + u8:7; /* 01-07: Reserved, must be zero */ + u8 reserved3[3]; /* 08-31: Reserved, must be zero */ + u8 local_sapic_eid; u8 proximity_domain_hi[3]; - u32 reserved; /* Reserved, must be zero */ + u32 reserved4; /* Reserved, must be zero */ }; -/* Flags */ - -#define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ - -struct acpi_srat_mem_affinity { - struct acpi_subtable_header header; - u32 proximity_domain; - u16 reserved; /* Reserved, must be zero */ +struct memory_affinity { + SRAT_SUBTABLE_HEADER u32 proximity_domain; + u16 reserved3; u64 base_address; - u64 length; - u32 memory_type; /* See acpi_address_range_id */ - u32 flags; - u64 reserved1; /* Reserved, must be zero */ -}; + u64 address_length; + u32 reserved4; -/* Flags */ + /* Flags (32 bits) */ -#define ACPI_SRAT_MEM_ENABLED (1) /* 00: Use affinity structure */ -#define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */ -#define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */ + u8 enabled:1; /* 00: Use affinity structure */ + u8 hot_pluggable:1; /* 01: Memory region is hot pluggable */ + u8 non_volatile:1; /* 02: Memory is non-volatile */ + u8:5; /* 03-07: Reserved, must be zero */ + u8 reserved5[3]; /* 08-31: Reserved, must be zero */ + + u64 reserved6; /* Reserved, must be zero */ +}; /******************************************************************************* * @@ -676,8 +557,7 @@ struct acpi_srat_mem_affinity { ******************************************************************************/ struct acpi_table_tcpa { - struct acpi_table_header header; /* Common ACPI table header */ - u16 reserved; + ACPI_TABLE_HEADER_DEF u16 reserved; u32 max_log_length; /* Maximum length for the event log area */ u64 log_address; /* Address of the event log area */ }; @@ -689,8 +569,7 @@ struct acpi_table_tcpa { ******************************************************************************/ struct acpi_table_wdrt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 header_length; /* Watchdog Header Length */ + ACPI_TABLE_HEADER_DEF u32 header_length; /* Watchdog Header Length */ u8 pci_segment; /* PCI Segment number */ u8 pci_bus; /* PCI Bus number */ u8 pci_device; /* PCI Device number */ @@ -703,9 +582,58 @@ struct acpi_table_wdrt { u32 entries; /* Number of watchdog entries that follow */ }; -/* Flags */ - -#define ACPI_WDRT_TIMER_ENABLED (1) /* 00: Timer enabled */ +#if 0 /* Flags, will be converted to macros */ +u8 enabled:1; /* 00: Timer enabled */ +u8:6; /* 01-06: Reserved */ +u8 sleep_stop:1; /* 07: Timer stopped in sleep state */ +#endif + +/* Macros used to generate offsets to specific table fields */ + +#define ACPI_ASF0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_info,f) +#define ACPI_ASF1_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_alert,f) +#define ACPI_ASF2_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_remote,f) +#define ACPI_ASF3_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_rmcp,f) +#define ACPI_ASF4_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_address,f) +#define ACPI_BOOT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_boot,f) +#define ACPI_CPEP_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_cpep,f) +#define ACPI_CPEP0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_cpep_polling,f) +#define ACPI_DBGP_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_dbgp,f) +#define ACPI_ECDT_OFFSET(f) (u8) ACPI_OFFSET (struct ec_boot_resources,f) +#define ACPI_HPET_OFFSET(f) (u8) ACPI_OFFSET (struct hpet_table,f) +#define ACPI_MADT_OFFSET(f) (u8) ACPI_OFFSET (struct multiple_apic_table,f) +#define ACPI_MADT0_OFFSET(f) (u8) ACPI_OFFSET (struct madt_processor_apic,f) +#define ACPI_MADT1_OFFSET(f) (u8) ACPI_OFFSET (struct madt_io_apic,f) +#define ACPI_MADT2_OFFSET(f) (u8) ACPI_OFFSET (struct madt_interrupt_override,f) +#define ACPI_MADT3_OFFSET(f) (u8) ACPI_OFFSET (struct madt_nmi_source,f) +#define ACPI_MADT4_OFFSET(f) (u8) ACPI_OFFSET (struct madt_local_apic_nmi,f) +#define ACPI_MADT5_OFFSET(f) (u8) ACPI_OFFSET (struct madt_address_override,f) +#define ACPI_MADT6_OFFSET(f) (u8) ACPI_OFFSET (struct madt_io_sapic,f) +#define ACPI_MADT7_OFFSET(f) (u8) ACPI_OFFSET (struct madt_local_sapic,f) +#define ACPI_MADT8_OFFSET(f) (u8) ACPI_OFFSET (struct madt_interrupt_source,f) +#define ACPI_MADTH_OFFSET(f) (u8) ACPI_OFFSET (struct apic_header,f) +#define ACPI_MCFG_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_mcfg,f) +#define ACPI_MCFG0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_mcfg_allocation,f) +#define ACPI_SBST_OFFSET(f) (u8) ACPI_OFFSET (struct smart_battery_table,f) +#define ACPI_SLIT_OFFSET(f) (u8) ACPI_OFFSET (struct system_locality_info,f) +#define ACPI_SPCR_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_spcr,f) +#define ACPI_SPMI_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_spmi,f) +#define ACPI_SRAT_OFFSET(f) (u8) ACPI_OFFSET (struct system_resource_affinity,f) +#define ACPI_SRAT0_OFFSET(f) (u8) ACPI_OFFSET (struct static_resource_alloc,f) +#define ACPI_SRAT1_OFFSET(f) (u8) ACPI_OFFSET (struct memory_affinity,f) +#define ACPI_TCPA_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_tcpa,f) +#define ACPI_WDRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_wdrt,f) + +#define ACPI_HPET_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct hpet_table,f,o) +#define ACPI_SRAT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct static_resource_alloc,f,o) +#define ACPI_SRAT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct memory_affinity,f,o) +#define ACPI_MADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct multiple_apic_table,f,o) +#define ACPI_MADT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_processor_apic,f,o) +#define ACPI_MADT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_interrupt_override,f,o) +#define ACPI_MADT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_nmi_source,f,o) +#define ACPI_MADT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_local_apic_nmi,f,o) +#define ACPI_MADT7_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_local_sapic,f,o) +#define ACPI_MADT8_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_interrupt_source,f,o) /* Reset to default packing */ diff --git a/trunk/include/acpi/actbl2.h b/trunk/include/acpi/actbl2.h new file mode 100644 index 000000000000..67efe6cad27b --- /dev/null +++ b/trunk/include/acpi/actbl2.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Name: actbl2.h - ACPI Specification Revision 2.0 Tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2006, 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. + */ + +#ifndef __ACTBL2_H__ +#define __ACTBL2_H__ + +/* Code moved to both actbl.h and actbl1.h */ + +#endif /* __ACTBL2_H__ */ diff --git a/trunk/include/acpi/actbl71.h b/trunk/include/acpi/actbl71.h new file mode 100644 index 000000000000..10ac05bb36bc --- /dev/null +++ b/trunk/include/acpi/actbl71.h @@ -0,0 +1,134 @@ +/****************************************************************************** + * + * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 + * This file includes tables specific to this + * specification revision. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACTBL71_H__ +#define __ACTBL71_H__ + +/* 0.71 FADT address_space data item bitmasks defines */ +/* If the associated bit is zero then it is in memory space else in io space */ + +#define SMI_CMD_ADDRESS_SPACE 0x01 +#define PM1_BLK_ADDRESS_SPACE 0x02 +#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 +#define PM_TMR_BLK_ADDRESS_SPACE 0x08 +#define GPE0_BLK_ADDRESS_SPACE 0x10 +#define GPE1_BLK_ADDRESS_SPACE 0x20 + +/* Only for clarity in declarations */ + +typedef u64 IO_ADDRESS; + +#pragma pack(1) +struct { /* Root System Descriptor Pointer */ + NATIVE_CHAR signature[8]; /* contains "RSD PTR " */ + u8 checksum; /* to make sum of struct == 0 */ + NATIVE_CHAR oem_id[6]; /* OEM identification */ + u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */ + u64 rsdt_physical_address; /* 64-bit physical address of RSDT */ +}; + +/*****************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Root System Description Table */ +/*****************************************/ +struct { + struct acpi_table_header header; /* Table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + u64 table_offset_entry[1]; /* Array of pointers to other */ + /* tables' headers */ +}; + +/*******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Firmware ACPI Control Structure */ +/*******************************************/ +struct { + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 reserved4; /* must be 0 */ + u64 firmware_waking_vector; /* ACPI OS waking vector */ + u64 global_lock; /* Global Lock */ + u32 S4bios_f:1; /* Indicates if S4BIOS support is present */ + u32 reserved1:31; /* must be 0 */ + u8 reserved3[28]; /* reserved - must be zero */ +}; + +/******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Fixed ACPI Description Table */ +/******************************************/ +struct { + struct acpi_table_header header; /* table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + u64 firmware_ctrl; /* 64-bit Physical address of FACS */ + u64 dsdt; /* 64-bit Physical address of DSDT */ + u8 model; /* System Interrupt Model */ + u8 address_space; /* Address Space Bitmask */ + u16 sci_int; /* System vector of SCI interrupt */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ + u8 reserved2; /* reserved - must be zero */ + u64 smi_cmd; /* Port address of SMI command port */ + u64 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ + u64 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ + u64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u64 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ + u64 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 reserved3; /* reserved */ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u8 reserved4; /* reserved */ + u32 flush_cash:1; /* PAL_FLUSH_CACHE is correctly supported */ + u32 reserved5:1; /* reserved - must be zero */ + u32 proc_c1:1; /* all processors support C1 state */ + u32 plvl2_up:1; /* C2 state works on MP system */ + u32 pwr_button:1; /* Power button is handled as a generic feature */ + u32 sleep_button:1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC:1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4:1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext:1; /* tmr_val is 32 bits */ + u32 dock_cap:1; /* Supports Docking */ + u32 reserved6:22; /* reserved - must be zero */ +}; + +#pragma pack() + +#endif /* __ACTBL71_H__ */ diff --git a/trunk/include/acpi/actypes.h b/trunk/include/acpi/actypes.h index 72a6e2c3a536..64b603cfe92e 100644 --- a/trunk/include/acpi/actypes.h +++ b/trunk/include/acpi/actypes.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,8 +48,7 @@ /* * ACPI_MACHINE_WIDTH must be specified in an OS- or compiler-dependent header - * and must be either 32 or 64. 16-bit ACPICA is no longer supported, as of - * 12/2006. + * and must be either 16, 32, or 64 */ #ifndef ACPI_MACHINE_WIDTH #error ACPI_MACHINE_WIDTH not defined @@ -150,6 +149,7 @@ typedef int INT32; typedef u64 acpi_native_uint; typedef s64 acpi_native_int; +typedef u64 acpi_table_ptr; typedef u64 acpi_io_address; typedef u64 acpi_physical_address; @@ -189,15 +189,48 @@ typedef int INT32; typedef u32 acpi_native_uint; typedef s32 acpi_native_int; +typedef u64 acpi_table_ptr; typedef u32 acpi_io_address; -typedef u32 acpi_physical_address; +typedef u64 acpi_physical_address; #define ACPI_MAX_PTR ACPI_UINT32_MAX #define ACPI_SIZE_MAX ACPI_UINT32_MAX +/******************************************************************************* + * + * Types specific to 16-bit targets + * + ******************************************************************************/ + +#elif ACPI_MACHINE_WIDTH == 16 + +/*! [Begin] no source code translation (keep the typedefs as-is) */ + +typedef unsigned long UINT32; +typedef short INT16; +typedef long INT32; + +/*! [End] no source code translation !*/ + +typedef u16 acpi_native_uint; +typedef s16 acpi_native_int; + +typedef u32 acpi_table_ptr; +typedef u32 acpi_io_address; +typedef char *acpi_physical_address; + +#define ACPI_MAX_PTR ACPI_UINT16_MAX +#define ACPI_SIZE_MAX ACPI_UINT16_MAX + +#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ + +/* 64-bit integers cannot be supported */ + +#define ACPI_NO_INTEGER64_SUPPORT + #else -/* ACPI_MACHINE_WIDTH must be either 64 or 32 */ +/* ACPI_MACHINE_WIDTH must be either 64, 32, or 16 */ #error unknown ACPI_MACHINE_WIDTH #endif @@ -278,6 +311,36 @@ typedef acpi_native_uint acpi_size; * ******************************************************************************/ +/* + * Pointer overlays to avoid lots of typecasting for + * code that accepts both physical and logical pointers. + */ +union acpi_pointers { + acpi_physical_address physical; + void *logical; + acpi_table_ptr value; +}; + +struct acpi_pointer { + u32 pointer_type; + union acpi_pointers pointer; +}; + +/* pointer_types for above */ + +#define ACPI_PHYSICAL_POINTER 0x01 +#define ACPI_LOGICAL_POINTER 0x02 + +/* Processor mode */ + +#define ACPI_PHYSICAL_ADDRESSING 0x04 +#define ACPI_LOGICAL_ADDRESSING 0x08 +#define ACPI_MEMORY_MODE 0x0C + +#define ACPI_PHYSMODE_PHYSPTR ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER +#define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER +#define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER + /* Logical defines and NULL */ #ifdef FALSE @@ -379,8 +442,7 @@ typedef u64 acpi_integer; /* * Initialization state */ -#define ACPI_SUBSYSTEM_INITIALIZE 0x01 -#define ACPI_INITIALIZED_OK 0x02 +#define ACPI_INITIALIZED_OK 0x01 /* * Power state values @@ -428,6 +490,21 @@ typedef u64 acpi_integer; #define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6 #define ACPI_NOTIFY_POWER_FAULT (u8) 7 +/* + * Table types. These values are passed to the table related APIs + */ +typedef u32 acpi_table_type; + +#define ACPI_TABLE_ID_RSDP (acpi_table_type) 0 +#define ACPI_TABLE_ID_DSDT (acpi_table_type) 1 +#define ACPI_TABLE_ID_FADT (acpi_table_type) 2 +#define ACPI_TABLE_ID_FACS (acpi_table_type) 3 +#define ACPI_TABLE_ID_PSDT (acpi_table_type) 4 +#define ACPI_TABLE_ID_SSDT (acpi_table_type) 5 +#define ACPI_TABLE_ID_XSDT (acpi_table_type) 6 +#define ACPI_TABLE_ID_MAX 6 +#define ACPI_NUM_TABLE_TYPES (ACPI_TABLE_ID_MAX+1) + /* * Types associated with ACPI names and objects. The first group of * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition @@ -560,7 +637,7 @@ typedef u32 acpi_event_status; * | | | +--- Type of dispatch -- to method, handler, or none * | | +--- Enabled for runtime? * | +--- Enabled for wake? - * +--- Unused + * +--- System state when GPE ocurred (running/waking) */ #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 @@ -586,6 +663,10 @@ typedef u32 acpi_event_status; #define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */ +#define ACPI_GPE_SYSTEM_MASK (u8) 0x80 +#define ACPI_GPE_SYSTEM_RUNNING (u8) 0x80 +#define ACPI_GPE_SYSTEM_WAKING (u8) 0x00 + /* * Flags for GPE and Lock interfaces */ @@ -734,6 +815,13 @@ struct acpi_buffer { #define ACPI_SYS_MODE_LEGACY 0x0002 #define ACPI_SYS_MODES_MASK 0x0003 +/* + * ACPI Table Info. One per ACPI table _type_ + */ +struct acpi_table_info { + u32 count; +}; + /* * System info returned by acpi_get_system_info() */ @@ -745,6 +833,8 @@ struct acpi_system_info { u32 reserved2; u32 debug_level; u32 debug_layer; + u32 num_table_types; + struct acpi_table_info table_info[ACPI_TABLE_ID_MAX + 1]; }; /* diff --git a/trunk/include/acpi/acutils.h b/trunk/include/acpi/acutils.h index 883ffe92148f..ba039ea1a057 100644 --- a/trunk/include/acpi/acutils.h +++ b/trunk/include/acpi/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -141,6 +141,8 @@ acpi_status acpi_ut_hardware_initialize(void); void acpi_ut_subsystem_shutdown(void); +acpi_status acpi_ut_validate_fadt(void); + /* * utclib - Local implementations of C library functions */ @@ -451,8 +453,6 @@ acpi_ut_short_divide(acpi_integer in_dividend, /* * utmisc */ -const char *acpi_ut_validate_exception(acpi_status status); - u8 acpi_ut_is_aml_table(struct acpi_table_header *table); acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); @@ -470,7 +470,7 @@ void acpi_ut_print_string(char *string, u8 max_length); u8 acpi_ut_valid_acpi_name(u32 name); -acpi_name acpi_ut_repair_name(char *name); +acpi_name acpi_ut_repair_name(acpi_name name); u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position); diff --git a/trunk/include/acpi/amlcode.h b/trunk/include/acpi/amlcode.h index da53a4ef287a..cf18426a87b1 100644 --- a/trunk/include/acpi/amlcode.h +++ b/trunk/include/acpi/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -273,7 +273,7 @@ #define ARGI_DATAOBJECT 0x12 /* Buffer, String, package or reference to a Node - Used only by size_of operator */ #define ARGI_COMPLEXOBJ 0x13 /* Buffer, String, or package (Used by INDEX op only) */ #define ARGI_REF_OR_STRING 0x14 /* Reference or String (Used by DEREFOF op only) */ -#define ARGI_REGION_OR_BUFFER 0x15 /* Used by LOAD op only */ +#define ARGI_REGION_OR_FIELD 0x15 /* Used by LOAD op only */ #define ARGI_DATAREFOBJ 0x16 /* Note: types above can expand to 0x1F maximum */ diff --git a/trunk/include/acpi/amlresrc.h b/trunk/include/acpi/amlresrc.h index f7d541239da4..be03818af9d1 100644 --- a/trunk/include/acpi/amlresrc.h +++ b/trunk/include/acpi/amlresrc.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/platform/acenv.h b/trunk/include/acpi/platform/acenv.h index dab2ec59a3b0..453a469fd397 100644 --- a/trunk/include/acpi/platform/acenv.h +++ b/trunk/include/acpi/platform/acenv.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/platform/acgcc.h b/trunk/include/acpi/platform/acgcc.h index 3bb50494a38a..da80933963db 100644 --- a/trunk/include/acpi/platform/acgcc.h +++ b/trunk/include/acpi/platform/acgcc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/acpi/platform/aclinux.h b/trunk/include/acpi/platform/aclinux.h index 5f532d2ac180..7f1e92930b62 100644 --- a/trunk/include/acpi/platform/aclinux.h +++ b/trunk/include/acpi/platform/aclinux.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/trunk/include/asm-i386/acpi.h b/trunk/include/asm-i386/acpi.h index 5e657eb8946c..7cfad93edf10 100644 --- a/trunk/include/asm-i386/acpi.h +++ b/trunk/include/asm-i386/acpi.h @@ -39,7 +39,7 @@ * Calling conventions: * * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_EXTERNAL_XFACE - External ACPI interfaces * ACPI_INTERNAL_XFACE - Internal ACPI interfaces * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces */ @@ -59,11 +59,11 @@ int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock); -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_release_global_lock(&facs->global_lock)) +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_release_global_lock((unsigned int *) GLptr)) /* * Math helper asm macros @@ -87,7 +87,7 @@ extern void check_acpi_pci(void); static inline void check_acpi_pci(void) { } #endif -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI extern int acpi_lapic; extern int acpi_ioapic; extern int acpi_noirq; @@ -95,9 +95,9 @@ extern int acpi_strict; extern int acpi_disabled; extern int acpi_ht; extern int acpi_pci_disabled; -static inline void disable_acpi(void) -{ - acpi_disabled = 1; +static inline void disable_acpi(void) +{ + acpi_disabled = 1; acpi_ht = 0; acpi_pci_disabled = 1; acpi_noirq = 1; @@ -114,9 +114,9 @@ extern int acpi_use_timer_override; #endif static inline void acpi_noirq_set(void) { acpi_noirq = 1; } -static inline void acpi_disable_pci(void) +static inline void acpi_disable_pci(void) { - acpi_pci_disabled = 1; + acpi_pci_disabled = 1; acpi_noirq_set(); } extern int acpi_irq_balance_set(char *str); @@ -144,6 +144,8 @@ extern void acpi_reserve_bootmem(void); #endif /*CONFIG_ACPI_SLEEP*/ +extern u8 x86_acpiid_to_apicid[]; + #define ARCH_HAS_POWER_INIT 1 #endif /*__KERNEL__*/ diff --git a/trunk/include/asm-i386/mach-es7000/mach_mpparse.h b/trunk/include/asm-i386/mach-es7000/mach_mpparse.h index 24990e546da3..99f66be240be 100644 --- a/trunk/include/asm-i386/mach-es7000/mach_mpparse.h +++ b/trunk/include/asm-i386/mach-es7000/mach_mpparse.h @@ -3,13 +3,13 @@ #include -static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, +static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, struct mpc_config_translation *translation) { Dprintk("Bus #%d is %s\n", m->mpc_busid, name); } -static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, +static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, struct mpc_config_translation *translation) { } @@ -22,7 +22,7 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid) { if (mpc->mpc_oemptr) { - struct mp_config_oemtable *oem_table = + struct mp_config_oemtable *oem_table = (struct mp_config_oemtable *)mpc->mpc_oemptr; if (!strncmp(oem, "UNISYS", 6)) return parse_unisys_oem((char *)oem_table); @@ -31,13 +31,12 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, } #ifdef CONFIG_ACPI - static inline int es7000_check_dsdt(void) { - struct acpi_table_header header; - memcpy(&header, 0, sizeof(struct acpi_table_header)); - acpi_get_table_header(ACPI_SIG_DSDT, 0, &header); - if (!strncmp(header.oem_id, "UNISYS", 6)) + struct acpi_table_header *header = NULL; + if(!acpi_get_table_header_early(ACPI_DSDT, &header)) + acpi_table_print(header, 0); + if (!strncmp(header->oem_id, "UNISYS", 6)) return 1; return 0; } @@ -45,7 +44,7 @@ static inline int es7000_check_dsdt(void) /* Hook from generic ACPI tables.c */ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { - unsigned long oem_addr; + unsigned long oem_addr; if (!find_unisys_acpi_oem_table(&oem_addr)) { if (es7000_check_dsdt()) return parse_unisys_oem((char *)oem_addr); diff --git a/trunk/include/asm-ia64/acpi.h b/trunk/include/asm-ia64/acpi.h index 5d03792d4f65..09a5dd0e44a8 100644 --- a/trunk/include/asm-ia64/acpi.h +++ b/trunk/include/asm-ia64/acpi.h @@ -82,11 +82,11 @@ ia64_acpi_release_global_lock (unsigned int *lock) return old & 0x1; } -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = ia64_acpi_acquire_global_lock(&facs->global_lock)) +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = ia64_acpi_acquire_global_lock((unsigned int *) GLptr)) -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = ia64_acpi_release_global_lock(&facs->global_lock)) +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr)) #define acpi_disabled 0 /* ACPI always enabled on IA64 */ #define acpi_noirq 0 /* ACPI always enabled on IA64 */ @@ -119,6 +119,8 @@ extern int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS]; extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; #endif +extern u16 ia64_acpiid_to_sapicid[]; + /* * Refer Intel ACPI _PDC support document for bit definitions */ diff --git a/trunk/include/asm-ia64/sn/acpi.h b/trunk/include/asm-ia64/sn/acpi.h index 9ce2801cbd57..2850a7ef5e71 100644 --- a/trunk/include/asm-ia64/sn/acpi.h +++ b/trunk/include/asm-ia64/sn/acpi.h @@ -11,7 +11,6 @@ #include "acpi/acglobal.h" -extern int sn_acpi_rev; -#define SN_ACPI_BASE_SUPPORT() (sn_acpi_rev >= 0x20101) +#define SN_ACPI_BASE_SUPPORT() (acpi_gbl_DSDT->oem_revision >= 0x20101) #endif /* _ASM_IA64_SN_ACPI_H */ diff --git a/trunk/include/asm-ia64/sn/pcibr_provider.h b/trunk/include/asm-ia64/sn/pcibr_provider.h index 17cb6cc3f21a..da3eade0cae2 100644 --- a/trunk/include/asm-ia64/sn/pcibr_provider.h +++ b/trunk/include/asm-ia64/sn/pcibr_provider.h @@ -142,7 +142,7 @@ extern int pcibr_ate_alloc(struct pcibus_info *, int); extern void pcibr_ate_free(struct pcibus_info *, int); extern void ate_write(struct pcibus_info *, int, int, u64); extern int sal_pcibr_slot_enable(struct pcibus_info *soft, int device, - void *resp, char **ssdt); + void *resp); extern int sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, void *resp); extern u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus); diff --git a/trunk/include/asm-ia64/sn/pcidev.h b/trunk/include/asm-ia64/sn/pcidev.h index 1c2382cea807..9fe89a93d880 100644 --- a/trunk/include/asm-ia64/sn/pcidev.h +++ b/trunk/include/asm-ia64/sn/pcidev.h @@ -70,16 +70,10 @@ extern void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info); extern void sn_irq_unfixup(struct pci_dev *pci_dev); extern struct pcidev_info * sn_pcidev_info_get(struct pci_dev *); -extern void sn_bus_fixup(struct pci_bus *); -extern void sn_acpi_bus_fixup(struct pci_bus *); -extern void sn_common_bus_fixup(struct pci_bus *, struct pcibus_bussoft *); extern void sn_bus_store_sysdata(struct pci_dev *dev); extern void sn_bus_free_sysdata(void); extern void sn_generate_path(struct pci_bus *pci_bus, char *address); -extern void sn_io_slot_fixup(struct pci_dev *); -extern void sn_acpi_slot_fixup(struct pci_dev *); -extern void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *, - struct sn_irq_info *); +extern void sn_pci_fixup_slot(struct pci_dev *dev); extern void sn_pci_unfixup_slot(struct pci_dev *dev); extern void sn_irq_lh_init(void); #endif /* _ASM_IA64_SN_PCI_PCIDEV_H */ diff --git a/trunk/include/asm-x86_64/acpi.h b/trunk/include/asm-x86_64/acpi.h index a29f05087a31..6b6fc6f8be7e 100644 --- a/trunk/include/asm-x86_64/acpi.h +++ b/trunk/include/asm-x86_64/acpi.h @@ -37,7 +37,7 @@ * Calling conventions: * * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_EXTERNAL_XFACE - External ACPI interfaces * ACPI_INTERNAL_XFACE - Internal ACPI interfaces * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces */ @@ -57,11 +57,11 @@ int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock); -#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) -#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ - ((Acq) = __acpi_release_global_lock(&facs->global_lock)) +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + ((Acq) = __acpi_release_global_lock((unsigned int *) GLptr)) /* * Math helper asm macros @@ -87,10 +87,10 @@ extern int acpi_strict; extern int acpi_disabled; extern int acpi_pci_disabled; extern int acpi_ht; -static inline void disable_acpi(void) -{ - acpi_disabled = 1; - acpi_ht = 0; +static inline void disable_acpi(void) +{ + acpi_disabled = 1; + acpi_ht = 0; acpi_pci_disabled = 1; acpi_noirq = 1; } @@ -100,9 +100,9 @@ static inline void disable_acpi(void) extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); static inline void acpi_noirq_set(void) { acpi_noirq = 1; } -static inline void acpi_disable_pci(void) +static inline void acpi_disable_pci(void) { - acpi_pci_disabled = 1; + acpi_pci_disabled = 1; acpi_noirq_set(); } extern int acpi_irq_balance_set(char *str); @@ -136,6 +136,8 @@ extern void acpi_reserve_bootmem(void); extern int acpi_disabled; extern int acpi_pci_disabled; +extern u8 x86_acpiid_to_apicid[]; + #define ARCH_HAS_POWER_INIT 1 extern int acpi_skip_timer_override; diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 815f1fb4ce21..91f1f2363870 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -53,6 +53,166 @@ enum acpi_irq_model_id { extern enum acpi_irq_model_id acpi_irq_model; + +/* Root System Description Pointer (RSDP) */ + +struct acpi_table_rsdp { + char signature[8]; + u8 checksum; + char oem_id[6]; + u8 revision; + u32 rsdt_address; +} __attribute__ ((packed)); + +struct acpi20_table_rsdp { + char signature[8]; + u8 checksum; + char oem_id[6]; + u8 revision; + u32 rsdt_address; + u32 length; + u64 xsdt_address; + u8 ext_checksum; + u8 reserved[3]; +} __attribute__ ((packed)); + +typedef struct { + u8 type; + u8 length; +} __attribute__ ((packed)) acpi_table_entry_header; + +/* Root System Description Table (RSDT) */ + +struct acpi_table_rsdt { + struct acpi_table_header header; + u32 entry[8]; +} __attribute__ ((packed)); + +/* Extended System Description Table (XSDT) */ + +struct acpi_table_xsdt { + struct acpi_table_header header; + u64 entry[1]; +} __attribute__ ((packed)); + +/* Fixed ACPI Description Table (FADT) */ + +struct acpi_table_fadt { + struct acpi_table_header header; + u32 facs_addr; + u32 dsdt_addr; + /* ... */ +} __attribute__ ((packed)); + +/* Multiple APIC Description Table (MADT) */ + +struct acpi_table_madt { + struct acpi_table_header header; + u32 lapic_address; + struct { + u32 pcat_compat:1; + u32 reserved:31; + } flags; +} __attribute__ ((packed)); + +enum acpi_madt_entry_id { + ACPI_MADT_LAPIC = 0, + ACPI_MADT_IOAPIC, + ACPI_MADT_INT_SRC_OVR, + ACPI_MADT_NMI_SRC, + ACPI_MADT_LAPIC_NMI, + ACPI_MADT_LAPIC_ADDR_OVR, + ACPI_MADT_IOSAPIC, + ACPI_MADT_LSAPIC, + ACPI_MADT_PLAT_INT_SRC, + ACPI_MADT_ENTRY_COUNT +}; + +typedef struct { + u16 polarity:2; + u16 trigger:2; + u16 reserved:12; +} __attribute__ ((packed)) acpi_interrupt_flags; + +struct acpi_table_lapic { + acpi_table_entry_header header; + u8 acpi_id; + u8 id; + struct { + u32 enabled:1; + u32 reserved:31; + } flags; +} __attribute__ ((packed)); + +struct acpi_table_ioapic { + acpi_table_entry_header header; + u8 id; + u8 reserved; + u32 address; + u32 global_irq_base; +} __attribute__ ((packed)); + +struct acpi_table_int_src_ovr { + acpi_table_entry_header header; + u8 bus; + u8 bus_irq; + u32 global_irq; + acpi_interrupt_flags flags; +} __attribute__ ((packed)); + +struct acpi_table_nmi_src { + acpi_table_entry_header header; + acpi_interrupt_flags flags; + u32 global_irq; +} __attribute__ ((packed)); + +struct acpi_table_lapic_nmi { + acpi_table_entry_header header; + u8 acpi_id; + acpi_interrupt_flags flags; + u8 lint; +} __attribute__ ((packed)); + +struct acpi_table_lapic_addr_ovr { + acpi_table_entry_header header; + u8 reserved[2]; + u64 address; +} __attribute__ ((packed)); + +struct acpi_table_iosapic { + acpi_table_entry_header header; + u8 id; + u8 reserved; + u32 global_irq_base; + u64 address; +} __attribute__ ((packed)); + +struct acpi_table_lsapic { + acpi_table_entry_header header; + u8 acpi_id; + u8 id; + u8 eid; + u8 reserved[3]; + struct { + u32 enabled:1; + u32 reserved:31; + } flags; +} __attribute__ ((packed)); + +struct acpi_table_plat_int_src { + acpi_table_entry_header header; + acpi_interrupt_flags flags; + u8 type; /* See acpi_interrupt_type */ + u8 id; + u8 eid; + u8 iosapic_vector; + u32 global_irq; + struct { + u32 cpei_override_flag:1; + u32 reserved:31; + } plint_flags; +} __attribute__ ((packed)); + enum acpi_interrupt_id { ACPI_INTERRUPT_PMI = 1, ACPI_INTERRUPT_INIT, @@ -62,6 +222,89 @@ enum acpi_interrupt_id { #define ACPI_SPACE_MEM 0 +struct acpi_gen_regaddr { + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 resv; + u32 addrl; + u32 addrh; +} __attribute__ ((packed)); + +struct acpi_table_hpet { + struct acpi_table_header header; + u32 id; + struct acpi_gen_regaddr addr; + u8 number; + u16 min_tick; + u8 page_protect; +} __attribute__ ((packed)); + +/* + * Simple Boot Flags + * http://www.microsoft.com/whdc/hwdev/resources/specs/simp_bios.mspx + */ +struct acpi_table_sbf +{ + u8 sbf_signature[4]; + u32 sbf_len; + u8 sbf_revision; + u8 sbf_csum; + u8 sbf_oemid[6]; + u8 sbf_oemtable[8]; + u8 sbf_revdata[4]; + u8 sbf_creator[4]; + u8 sbf_crearev[4]; + u8 sbf_cmos; + u8 sbf_spare[3]; +} __attribute__ ((packed)); + +/* + * System Resource Affinity Table (SRAT) + * http://www.microsoft.com/whdc/hwdev/platform/proc/SRAT.mspx + */ + +struct acpi_table_srat { + struct acpi_table_header header; + u32 table_revision; + u64 reserved; +} __attribute__ ((packed)); + +enum acpi_srat_entry_id { + ACPI_SRAT_PROCESSOR_AFFINITY = 0, + ACPI_SRAT_MEMORY_AFFINITY, + ACPI_SRAT_ENTRY_COUNT +}; + +struct acpi_table_processor_affinity { + acpi_table_entry_header header; + u8 proximity_domain; + u8 apic_id; + struct { + u32 enabled:1; + u32 reserved:31; + } flags; + u8 lsapic_eid; + u8 reserved[7]; +} __attribute__ ((packed)); + +struct acpi_table_memory_affinity { + acpi_table_entry_header header; + u8 proximity_domain; + u8 reserved1[5]; + u32 base_addr_lo; + u32 base_addr_hi; + u32 length_lo; + u32 length_hi; + u32 memory_type; /* See acpi_address_range_id */ + struct { + u32 enabled:1; + u32 hot_pluggable:1; + u32 reserved:30; + } flags; + u64 reserved2; +} __attribute__ ((packed)); + enum acpi_address_range_id { ACPI_ADDRESS_RANGE_MEMORY = 1, ACPI_ADDRESS_RANGE_RESERVED = 2, @@ -70,12 +313,84 @@ enum acpi_address_range_id { ACPI_ADDRESS_RANGE_COUNT }; +/* + * System Locality Information Table (SLIT) + * see http://devresource.hp.com/devresource/docs/techpapers/ia64/slit.pdf + */ + +struct acpi_table_slit { + struct acpi_table_header header; + u64 localities; + u8 entry[1]; /* real size = localities^2 */ +} __attribute__ ((packed)); + +/* Smart Battery Description Table (SBST) */ + +struct acpi_table_sbst { + struct acpi_table_header header; + u32 warning; /* Warn user */ + u32 low; /* Critical sleep */ + u32 critical; /* Critical shutdown */ +} __attribute__ ((packed)); + +/* Embedded Controller Boot Resources Table (ECDT) */ + +struct acpi_table_ecdt { + struct acpi_table_header header; + struct acpi_generic_address ec_control; + struct acpi_generic_address ec_data; + u32 uid; + u8 gpe_bit; + char ec_id[0]; +} __attribute__ ((packed)); + +/* PCI MMCONFIG */ + +/* Defined in PCI Firmware Specification 3.0 */ +struct acpi_table_mcfg_config { + u32 base_address; + u32 base_reserved; + u16 pci_segment_group_number; + u8 start_bus_number; + u8 end_bus_number; + u8 reserved[4]; +} __attribute__ ((packed)); +struct acpi_table_mcfg { + struct acpi_table_header header; + u8 reserved[8]; + struct acpi_table_mcfg_config config[0]; +} __attribute__ ((packed)); /* Table Handlers */ -typedef int (*acpi_table_handler) (struct acpi_table_header *table); +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_TABLE_COUNT +}; + +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) (struct acpi_subtable_header *header, const unsigned long end); +typedef int (*acpi_madt_entry_handler) (acpi_table_entry_header *header, const unsigned long end); char * __acpi_map_table (unsigned long phys_addr, unsigned long size); unsigned long acpi_find_rsdp (void); @@ -84,12 +399,14 @@ int acpi_boot_table_init (void); int acpi_numa_init (void); int acpi_table_init (void); -int acpi_table_parse (char *id, acpi_table_handler handler); -int acpi_table_parse_madt (enum acpi_madt_type id, acpi_madt_entry_handler handler, unsigned int max_entries); -int acpi_table_parse_srat (enum acpi_srat_type id, acpi_madt_entry_handler handler, unsigned int max_entries); -int acpi_parse_mcfg (struct acpi_table_header *header); -void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); -void acpi_table_print_srat_entry (struct acpi_subtable_header *srat); +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_parse_mcfg (unsigned long phys_addr, unsigned long size); +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); /* the following four functions are architecture-dependent */ #ifdef CONFIG_HAVE_ARCH_PARSE_SRAT @@ -100,8 +417,8 @@ void acpi_table_print_srat_entry (struct acpi_subtable_header *srat); #define acpi_numa_arch_fixup() do {} while (0) #else void acpi_numa_slit_init (struct acpi_table_slit *slit); -void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); -void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); +void acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa); +void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma); void acpi_numa_arch_fixup(void); #endif @@ -116,7 +433,7 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); extern int acpi_mp_config; -extern struct acpi_mcfg_allocation *pci_mmcfg_config; +extern struct acpi_table_mcfg_config *pci_mmcfg_config; extern int pci_mmcfg_config_num; extern int sbf_port;