# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1519 -> 1.1520 # drivers/acpi/tables.c 1.19 -> 1.20 # arch/i386/kernel/acpi/boot.c 1.43 -> 1.44 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 04/03/01 len.brown@intel.com 1.1520 # [ACPI] acpi_boot_init() cleanup suggested by Matt Wilcox # HPET doesn't depend on IOAPIC # -------------------------------------------- # diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c Mon Mar 1 00:05:32 2004 +++ b/arch/i386/kernel/acpi/boot.c Mon Mar 1 00:05:32 2004 @@ -34,7 +34,7 @@ #include #include -#if defined (CONFIG_X86_LOCAL_APIC) +#ifdef CONFIG_X86_LOCAL_APIC #include #include #include @@ -49,11 +49,19 @@ int acpi_ioapic; int acpi_strict; +#ifdef CONFIG_X86_LOCAL_APIC +static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; +#endif + /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ -enum acpi_irq_model_id acpi_irq_model; +/* + * The default interrupt routing model is PIC (8259). This gets + * overriden if IOAPICs are enumerated (below). + */ +enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; /* * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, @@ -97,10 +105,6 @@ #ifdef CONFIG_X86_LOCAL_APIC - -static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; - - static int __init acpi_parse_madt ( unsigned long phys_addr, @@ -117,11 +121,12 @@ return -ENODEV; } - if (madt->lapic_address) + if (madt->lapic_address) { acpi_lapic_addr = (u64) madt->lapic_address; - printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", - madt->lapic_address); + printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", + madt->lapic_address); + } acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); @@ -247,7 +252,7 @@ return 0; } -#endif /*CONFIG_X86_IO_APIC*/ +#endif /* CONFIG_X86_IO_APIC */ #ifdef CONFIG_ACPI_BUS /* @@ -387,122 +392,61 @@ return rsdp_phys; } +#ifdef CONFIG_X86_LOCAL_APIC /* - * acpi_boot_init() - * called from setup_arch(), always. - * 1. maps ACPI tables for later use - * 2. enumerates lapics - * 3. enumerates io-apics - * - * side effects: - * acpi_lapic = 1 if LAPIC found - * acpi_ioapic = 1 if IOAPIC found - * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; - * if acpi_blacklisted() acpi_disabled = 1; - * acpi_irq_model=... - * ... - * - * return value: (currently ignored) - * 0: success - * !0: failure + * Parse LAPIC entries in MADT + * returns 0 on success, < 0 on error */ - -int __init -acpi_boot_init (void) +static int __init +acpi_parse_madt_lapic_entries(void) { - int result = 0; - - if (acpi_disabled && !acpi_ht) - return 1; - - /* - * The default interrupt routing model is PIC (8259). This gets - * overriden if IOAPICs are enumerated (below). - */ - acpi_irq_model = ACPI_IRQ_MODEL_PIC; - - /* - * Initialize the ACPI boot-time table parser. - */ - result = acpi_table_init(); - if (result) { - acpi_disabled = 1; - return result; - } - - result = acpi_blacklisted(); - if (result) { - printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); - acpi_disabled = 1; - return result; - } - -#ifdef CONFIG_X86_LOCAL_APIC + int count; /* - * MADT - * ---- - * Parse the Multiple APIC Description Table (MADT), if exists. - * Note that this table provides platform SMP configuration - * information -- the successor to MPS tables. - */ - - result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); - if (!result) { - return 0; - } - else if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing MADT\n"); - return result; - } - else if (result > 1) - printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); - - /* - * Local APIC - * ---------- * 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). */ - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); - if (result < 0) { + count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); + if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - return result; + return count; } mp_register_lapic_address(acpi_lapic_addr); - result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, + count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, MAX_APICS); - if (!result) { + if (!count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); /* TBD: Cleanup to allow fallback to MPS */ return -ENODEV; } - else if (result < 0) { + else if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ - return result; + return count; } - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); - if (result < 0) { + count = 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 */ - return result; + return count; } - - acpi_lapic = 1; - -#endif /*CONFIG_X86_LOCAL_APIC*/ + return 0; +} +#endif /* CONFIG_X86_LOCAL_APIC */ #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) - - /* - * I/O APIC - * -------- - */ +/* + * Parse IOAPIC related entries in MADT + * returns 0 on success, < 0 on error + */ +static int __init +acpi_parse_madt_ioapic_entries(void) +{ + int count; /* * ACPI interpreter is required to complete interrupt setup, @@ -511,7 +455,7 @@ * otherwise the system will stay in PIC mode */ if (acpi_disabled || acpi_noirq) { - return 1; + return -ENODEV; } /* @@ -520,54 +464,140 @@ if (ioapic_setup_disabled()) { printk(KERN_INFO PREFIX "Skipping IOAPIC probe " "due to 'noapic' option.\n"); - return 1; + return -ENODEV; } - result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); - if (!result) { + count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); + if (!count) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); return -ENODEV; } - else if (result < 0) { + else if (count < 0) { printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); - return result; + return count; } /* Build a default routing table for legacy (ISA) interrupts. */ mp_config_acpi_legacy_irqs(); - result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); - if (result < 0) { + count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); + if (count < 0) { printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); /* TBD: Cleanup to allow fallback to MPS */ - return result; + return count; } - result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); - if (result < 0) { + count = 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"); /* TBD: Cleanup to allow fallback to MPS */ - return result; + return count; } - acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; + return 0; +} +#else +static inline int acpi_parse_madt_ioapic_entries(void) +{ + return -1; +} +#endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */ - acpi_irq_balance_set(NULL); - acpi_ioapic = 1; +static void __init +acpi_process_madt(void) +{ +#ifdef CONFIG_X86_LOCAL_APIC + int count, error; -#endif /* CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER */ + count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); + if (count == 1) { -#ifdef CONFIG_X86_LOCAL_APIC - if (acpi_lapic && acpi_ioapic) { - smp_found_config = 1; - clustered_apic_check(); + /* + * Parse MADT LAPIC entries + */ + error = acpi_parse_madt_lapic_entries(); + if (!error) { + acpi_lapic = 1; + + /* + * Parse MADT IO-APIC entries + */ + error = acpi_parse_madt_ioapic_entries(); + if (!error) { + acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; + acpi_irq_balance_set(NULL); + acpi_ioapic = 1; + + smp_found_config = 1; + clustered_apic_check(); + } + } } #endif + return; +} + +/* + * acpi_boot_init() + * called from setup_arch(), always. + * 1. checksums all tables + * 2. enumerates lapics + * 3. enumerates io-apics + * + * side effects: + * acpi_lapic = 1 if LAPIC found + * acpi_ioapic = 1 if IOAPIC found + * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; + * if acpi_blacklisted() acpi_disabled = 1; + * acpi_irq_model=... + * ... + * + * return value: (currently ignored) + * 0: success + * !0: failure + */ + +int __init +acpi_boot_init (void) +{ + int error; + + /* + * If acpi_disabled, bail out + * One exception: acpi=ht continues far enough to enumerate LAPICs + */ + if (acpi_disabled && !acpi_ht) + return 1; + + /* + * Initialize the ACPI boot-time table parser. + */ + error = acpi_table_init(); + if (error) { + acpi_disabled = 1; + return error; + } + + /* + * blacklist may disable ACPI entirely + */ + error = acpi_blacklisted(); + if (error) { + printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); + acpi_disabled = 1; + return error; + } + + /* + * Process the Multiple APIC Description Table (MADT), if present + */ + acpi_process_madt(); #ifdef CONFIG_HPET_TIMER - acpi_table_parse(ACPI_HPET, acpi_parse_hpet); + (void) acpi_table_parse(ACPI_HPET, acpi_parse_hpet); #endif return 0; } + diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c Mon Mar 1 00:05:32 2004 +++ b/drivers/acpi/tables.c Mon Mar 1 00:05:32 2004 @@ -550,6 +550,14 @@ return 0; } +/* + * acpi_table_init() + * + * find RSDP, find and checksum SDT/XSDT. + * checksum all tables, print SDT/XSDT + * + * result: sdt_entry[] is initialized + */ int __init acpi_table_init (void)