diff options
Diffstat (limited to 'arch/i386')
42 files changed, 481 insertions, 575 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 0d67a0a1151..0dfee812811 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -777,6 +777,47 @@ config CRASH_DUMP PHYSICAL_START. For more details see Documentation/kdump/kdump.txt +config PHYSICAL_START + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) + default "0x100000" + help + This gives the physical address where the kernel is loaded. + + If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then + bzImage will decompress itself to above physical address and + run from there. Otherwise, bzImage will run from the address where + it has been loaded by the boot loader and will ignore above physical + address. + + In normal kdump cases one does not have to set/change this option + as now bzImage can be compiled as a completely relocatable image + (CONFIG_RELOCATABLE=y) and be used to load and run from a different + address. This option is mainly useful for the folks who don't want + to use a bzImage for capturing the crash dump and want to use a + vmlinux instead. vmlinux is not relocatable hence a kernel needs + to be specifically compiled to run from a specific memory area + (normally a reserved region) and this option comes handy. + + So if you are using bzImage for capturing the crash dump, leave + the value here unchanged to 0x100000 and set CONFIG_RELOCATABLE=y. + Otherwise if you plan to use vmlinux for capturing the crash dump + change this value to start of the reserved region (Typically 16MB + 0x1000000). In other words, it can be set based on the "X" value as + specified in the "crashkernel=YM@XM" command line boot parameter + passed to the panic-ed kernel. Typically this parameter is set as + crashkernel=64M@16M. Please take a look at + Documentation/kdump/kdump.txt for more details about crash dumps. + + Usage of bzImage for capturing the crash dump is recommended as + one does not have to build two kernels. Same kernel can be used + as production kernel and capture kernel. Above option should have + gone away after relocatable bzImage support is introduced. But it + is present because there are users out there who continue to use + vmlinux for dump capture. This option should go away down the + line. + + Don't change this unless you know what you are doing. + config RELOCATABLE bool "Build a relocatable kernel(EXPERIMENTAL)" depends on EXPERIMENTAL diff --git a/arch/i386/boot/compressed/.gitignore b/arch/i386/boot/compressed/.gitignore new file mode 100644 index 00000000000..be0ed065249 --- /dev/null +++ b/arch/i386/boot/compressed/.gitignore @@ -0,0 +1 @@ +relocs diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S index f395a4bb38b..3517a32aaf4 100644 --- a/arch/i386/boot/compressed/head.S +++ b/arch/i386/boot/compressed/head.S @@ -28,7 +28,7 @@ #include <asm/page.h> #include <asm/boot.h> -.section ".text.head" +.section ".text.head","ax",@progbits .globl startup_32 startup_32: diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c index 468da89153c..881951ca03e 100644 --- a/arch/i386/boot/compressed/relocs.c +++ b/arch/i386/boot/compressed/relocs.c @@ -43,6 +43,8 @@ static int is_safe_abs_reloc(const char* sym_name) /* Match found */ return 1; } + if (strncmp(sym_name, "__crc_", 6) == 0) + return 1; return 0; } diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 77927922dca..bb0c376b62b 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-git14 -# Sat Dec 9 21:23:14 2006 +# Linux kernel version: 2.6.20-rc3 +# Fri Jan 5 11:54:46 2007 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -1168,7 +1168,7 @@ CONFIG_USB_STORAGE=y # USB Input Devices # CONFIG_USB_HID=y -# CONFIG_USB_HID_POWERBOOK is not set +# CONFIG_USB_HIDINPUT_POWERBOOK is not set # CONFIG_HID_FF is not set # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set @@ -1288,6 +1288,11 @@ CONFIG_USB_MON=y # # +# Virtualization +# +# CONFIG_KVM is not set + +# # File systems # CONFIG_EXT2_FS=y @@ -1472,6 +1477,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_UNUSED_SYMBOLS=y +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_DETECT_SOFTLOCKUP=y @@ -1490,14 +1497,10 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_HIGHMEM is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set CONFIG_EARLY_PRINTK=y @@ -1530,6 +1533,7 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index c8f96cff07c..e94aff6888c 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/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 || \ - ((acpi_table_entry_header *)entry)->length < sizeof(*entry)) + ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) #define PREFIX "ACPI: " @@ -79,7 +79,7 @@ int acpi_ioapic; int acpi_strict; EXPORT_SYMBOL(acpi_strict); -acpi_interrupt_flags acpi_sci_flags __initdata; +u8 acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; int acpi_skip_timer_override __initdata; int acpi_use_timer_override __initdata; @@ -92,11 +92,6 @@ 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 -------------------------------------------------------------------------- */ @@ -166,30 +161,26 @@ 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_table_mcfg_config *pci_mmcfg_config; +struct acpi_mcfg_allocation *pci_mmcfg_config; int pci_mmcfg_config_num; -int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +int __init acpi_parse_mcfg(struct acpi_table_header *header) { struct acpi_table_mcfg *mcfg; unsigned long i; int config_size; - if (!phys_addr || !size) + if (!header) return -EINVAL; - mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); - if (!mcfg) { - printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); - return -ENODEV; - } + mcfg = (struct acpi_table_mcfg *)header; /* how many config structures do we have */ pci_mmcfg_config_num = 0; - i = size - sizeof(struct acpi_table_mcfg); - while (i >= sizeof(struct acpi_table_mcfg_config)) { + i = header->length - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_mcfg_allocation)) { ++pci_mmcfg_config_num; - i -= sizeof(struct acpi_table_mcfg_config); + i -= sizeof(struct acpi_mcfg_allocation); }; if (pci_mmcfg_config_num == 0) { printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); @@ -204,9 +195,9 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) return -ENOMEM; } - memcpy(pci_mmcfg_config, &mcfg->config, config_size); + memcpy(pci_mmcfg_config, &mcfg[1], config_size); for (i = 0; i < pci_mmcfg_config_num; ++i) { - if (mcfg->config[i].base_reserved) { + if (pci_mmcfg_config[i].address > 0xFFFFFFFF) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); kfree(pci_mmcfg_config); @@ -220,24 +211,24 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) #endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC -static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) +static int __init acpi_parse_madt(struct acpi_table_header *table) { struct acpi_table_madt *madt = NULL; - if (!phys_addr || !size || !cpu_has_apic) + if (!cpu_has_apic) return -EINVAL; - madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); + madt = (struct acpi_table_madt *)table; if (!madt) { printk(KERN_WARNING PREFIX "Unable to map MADT\n"); return -ENODEV; } - if (madt->lapic_address) { - acpi_lapic_addr = (u64) madt->lapic_address; + if (madt->address) { + acpi_lapic_addr = (u64) madt->address; printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", - madt->lapic_address); + madt->address); } acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); @@ -246,21 +237,17 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) } static int __init -acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_lapic *processor = NULL; + struct acpi_madt_local_apic *processor = NULL; - processor = (struct acpi_table_lapic *)header; + processor = (struct acpi_madt_local_apic *)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 @@ -269,18 +256,18 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) * when we use CPU hotplug. */ mp_register_lapic(processor->id, /* APIC ID */ - processor->flags.enabled); /* Enabled? */ + processor->lapic_flags & ACPI_MADT_ENABLED); /* Enabled? */ return 0; } static int __init -acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, +acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; + struct acpi_madt_local_apic_override *lapic_addr_ovr = NULL; - lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header; + lapic_addr_ovr = (struct acpi_madt_local_apic_override *)header; if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) return -EINVAL; @@ -291,11 +278,11 @@ acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, } static int __init -acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_lapic_nmi *lapic_nmi = NULL; + struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; - lapic_nmi = (struct acpi_table_lapic_nmi *)header; + lapic_nmi = (struct acpi_madt_local_apic_nmi *)header; if (BAD_MADT_ENTRY(lapic_nmi, end)) return -EINVAL; @@ -313,11 +300,11 @@ acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) #ifdef CONFIG_X86_IO_APIC static int __init -acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_ioapic *ioapic = NULL; + struct acpi_madt_io_apic *ioapic = NULL; - ioapic = (struct acpi_table_ioapic *)header; + ioapic = (struct acpi_madt_io_apic *)header; if (BAD_MADT_ENTRY(ioapic, end)) return -EINVAL; @@ -333,7 +320,7 @@ acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) /* * Parse Interrupt Source Override for the ACPI SCI */ -static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) +static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) { if (trigger == 0) /* compatible SCI trigger is level */ trigger = 3; @@ -342,11 +329,11 @@ static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) polarity = 3; /* Command-line over-ride via acpi_sci= */ - if (acpi_sci_flags.trigger) - trigger = acpi_sci_flags.trigger; + if (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) + trigger = (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2; - if (acpi_sci_flags.polarity) - polarity = acpi_sci_flags.polarity; + if (acpi_sci_flags & ACPI_MADT_POLARITY_MASK) + polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK; /* * mp_config_acpi_legacy_irqs() already setup IRQs < 16 @@ -357,51 +344,52 @@ static void 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_fadt + * and for later update of acpi_gbl_FADT */ acpi_sci_override_gsi = gsi; return; } static int __init -acpi_parse_int_src_ovr(acpi_table_entry_header * header, +acpi_parse_int_src_ovr(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_int_src_ovr *intsrc = NULL; + struct acpi_madt_interrupt_override *intsrc = NULL; - intsrc = (struct acpi_table_int_src_ovr *)header; + intsrc = (struct acpi_madt_interrupt_override *)header; if (BAD_MADT_ENTRY(intsrc, end)) return -EINVAL; acpi_table_print_madt_entry(header); - if (intsrc->bus_irq == acpi_fadt.sci_int) { + if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) { acpi_sci_ioapic_setup(intsrc->global_irq, - intsrc->flags.polarity, - intsrc->flags.trigger); + intsrc->inti_flags & ACPI_MADT_POLARITY_MASK, + (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2); return 0; } if (acpi_skip_timer_override && - intsrc->bus_irq == 0 && intsrc->global_irq == 2) { + intsrc->source_irq == 0 && intsrc->global_irq == 2) { printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); return 0; } - mp_override_legacy_irq(intsrc->bus_irq, - intsrc->flags.polarity, - intsrc->flags.trigger, intsrc->global_irq); + 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); return 0; } static int __init -acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) +acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) { - struct acpi_table_nmi_src *nmi_src = NULL; + struct acpi_madt_nmi_source *nmi_src = NULL; - nmi_src = (struct acpi_table_nmi_src *)header; + nmi_src = (struct acpi_madt_nmi_source *)header; if (BAD_MADT_ENTRY(nmi_src, end)) return -EINVAL; @@ -417,7 +405,7 @@ acpi_parse_nmi_src(acpi_table_entry_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 @@ -511,7 +499,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_table_lapic *lapic; + struct acpi_madt_local_apic *lapic; cpumask_t tmp_map, new_map; u8 physid; int cpu; @@ -529,10 +517,10 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) return -EINVAL; } - lapic = (struct acpi_table_lapic *)obj->buffer.pointer; + lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; - if ((lapic->header.type != ACPI_MADT_LAPIC) || - (!lapic->flags.enabled)) { + if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || + !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { kfree(buffer.pointer); return -EINVAL; } @@ -544,7 +532,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) buffer.pointer = NULL; tmp_map = cpu_present_map; - mp_register_lapic(physid, lapic->flags.enabled); + mp_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); /* * If mp_register_lapic successfully generates a new logical cpu @@ -566,14 +554,6 @@ 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--; @@ -619,42 +599,36 @@ acpi_scan_rsdp(unsigned long start, unsigned long length) return 0; } -static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) +static int __init acpi_parse_sbf(struct acpi_table_header *table) { - struct acpi_table_sbf *sb; - - if (!phys_addr || !size) - return -EINVAL; + struct acpi_table_boot *sb; - sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); + sb = (struct acpi_table_boot *)table; if (!sb) { printk(KERN_WARNING PREFIX "Unable to map SBF\n"); return -ENODEV; } - sbf_port = sb->sbf_cmos; /* Save CMOS port */ + sbf_port = sb->cmos_index; /* Save CMOS port */ return 0; } #ifdef CONFIG_HPET_TIMER -static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) +static int __init acpi_parse_hpet(struct acpi_table_header *table) { struct acpi_table_hpet *hpet_tbl; struct resource *hpet_res; resource_size_t res_start; - if (!phys || !size) - return -EINVAL; - - hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size); + hpet_tbl = (struct acpi_table_hpet *)table; if (!hpet_tbl) { printk(KERN_WARNING PREFIX "Unable to map HPET\n"); return -ENODEV; } - if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { + if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { printk(KERN_WARNING PREFIX "HPET timers must be located in " "memory.\n"); return -1; @@ -667,29 +641,28 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) 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->number); + "HPET %u", hpet_tbl->sequence); hpet_res->end = (1 * 1024) - 1; } -#ifdef CONFIG_X86_64 - vxtime.hpet_address = hpet_tbl->addr.addrl | - ((long)hpet_tbl->addr.addrh << 32); +#ifdef CONFIG_X86_64 + vxtime.hpet_address = hpet_tbl->address.address; 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->addr.addrl; + hpet_address = hpet_tbl->address.address; 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; @@ -707,42 +680,28 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) extern u32 pmtmr_ioport; #endif -static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) +static int __init acpi_parse_fadt(struct acpi_table_header *table) { - 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 (fadt->revision >= FADT2_REVISION_ID) { + if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) { /* FADT rev. 2 */ - if (fadt->xpm_tmr_blk.address_space_id != + if (acpi_gbl_FADT.xpm_timer_block.space_id != ACPI_ADR_SPACE_SYSTEM_IO) return 0; - pmtmr_ioport = fadt->xpm_tmr_blk.address; + pmtmr_ioport = acpi_gbl_FADT.xpm_timer_block.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 = fadt->V1_pm_tmr_blk; + pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; } else { /* FADT rev. 1 */ - pmtmr_ioport = fadt->V1_pm_tmr_blk; + pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; } if (pmtmr_ioport) printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", @@ -784,13 +743,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_LAPIC_ADDR_OVR, + acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, acpi_parse_lapic_addr_ovr, 0); if (count < 0) { printk(KERN_ERR PREFIX @@ -800,7 +759,7 @@ static int __init acpi_parse_madt_lapic_entries(void) mp_register_lapic_address(acpi_lapic_addr); - count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, + count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, acpi_parse_lapic, MAX_APICS); if (!count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); @@ -813,7 +772,7 @@ static int __init acpi_parse_madt_lapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); + acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_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 */ @@ -842,7 +801,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) return -ENODEV; } - if (!cpu_has_apic) + if (!cpu_has_apic) return -ENODEV; /* @@ -855,7 +814,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, + acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic, MAX_IO_APICS); if (!count) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); @@ -866,7 +825,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) } count = - acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, + acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); if (count < 0) { printk(KERN_ERR PREFIX @@ -880,13 +839,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_fadt.sci_int, 0, 0); + acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0); /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); count = - acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, + acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src, NR_IRQ_VECTORS); if (count < 0) { printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); @@ -908,7 +867,7 @@ static void __init acpi_process_madt(void) #ifdef CONFIG_X86_LOCAL_APIC int count, error; - count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); + count = acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt); if (count >= 1) { /* @@ -1195,7 +1154,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(); @@ -1204,7 +1163,7 @@ int __init acpi_boot_table_init(void) return error; } - acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); /* * blacklist may disable ACPI entirely @@ -1232,19 +1191,19 @@ int __init acpi_boot_init(void) if (acpi_disabled && !acpi_ht) return 1; - acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); /* * set sci_int and PM timer address */ - acpi_table_parse(ACPI_FADT, acpi_parse_fadt); + acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt); /* * Process the Multiple APIC Description Table (MADT), if present */ acpi_process_madt(); - acpi_table_parse(ACPI_HPET, acpi_parse_hpet); + acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); return 0; } @@ -1315,15 +1274,41 @@ static int __init setup_acpi_sci(char *s) if (!s) return -EINVAL; if (!strcmp(s, "edge")) - acpi_sci_flags.trigger = 1; + acpi_sci_flags = ACPI_MADT_TRIGGER_EDGE | + (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK); else if (!strcmp(s, "level")) - acpi_sci_flags.trigger = 3; + acpi_sci_flags = ACPI_MADT_TRIGGER_LEVEL | + (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK); else if (!strcmp(s, "high")) - acpi_sci_flags.polarity = 1; + acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_HIGH | + (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK); else if (!strcmp(s, "low")) - acpi_sci_flags.polarity = 3; + acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_LOW | + (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK); else return -EINVAL; return 0; } early_param("acpi_sci", setup_acpi_sci); + +int __acpi_acquire_global_lock(unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); + val = cmpxchg(lock, old, new); + } while (unlikely (val != old)); + return (new < 3) ? -1 : 0; +} + +int __acpi_release_global_lock(unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = old & ~0x3; + val = cmpxchg(lock, old, new); + } while (unlikely (val != old)); + return old & 0x1; +} diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c index 12e937c1ce4..2d39f55d29a 100644 --- a/arch/i386/kernel/acpi/cstate.c +++ b/arch/i386/kernel/acpi/cstate.c @@ -47,13 +47,13 @@ EXPORT_SYMBOL(acpi_processor_power_init_bm_check); /* The code below handles cstate entry with monitor-mwait pair on Intel*/ -struct cstate_entry_s { +struct cstate_entry { struct { unsigned int eax; unsigned int ecx; } states[ACPI_PROCESSOR_MAX_POWER]; }; -static struct cstate_entry_s *cpu_cstate_entry; /* per CPU ptr */ +static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; @@ -71,7 +71,7 @@ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; int acpi_processor_ffh_cstate_probe(unsigned int cpu, struct acpi_processor_cx *cx, struct acpi_power_register *reg) { - struct cstate_entry_s *percpu_entry; + struct cstate_entry *percpu_entry; struct cpuinfo_x86 *c = cpu_data + cpu; cpumask_t saved_mask; @@ -136,7 +136,7 @@ EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) { unsigned int cpu = smp_processor_id(); - struct cstate_entry_s *percpu_entry; + struct cstate_entry *percpu_entry; percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); mwait_idle_with_hints(percpu_entry->states[cx->index].eax, @@ -150,7 +150,7 @@ static int __init ffh_cstate_init(void) if (c->x86_vendor != X86_VENDOR_INTEL) return -1; - cpu_cstate_entry = alloc_percpu(struct cstate_entry_s); + cpu_cstate_entry = alloc_percpu(struct cstate_entry); return 0; } diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 4b60af7f91d..bf86f7662d8 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -16,7 +16,7 @@ static int nvidia_hpet_detected __initdata; -static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +static int __init nvidia_hpet_check(struct acpi_table_header *header) { 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_HPET, nvidia_hpet_check); + acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; printk(KERN_INFO "Nvidia board " diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index b75cff25de4..19901692754 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -785,7 +785,11 @@ static int apm_do_idle(void) polling = !!(current_thread_info()->status & TS_POLLING); if (polling) { current_thread_info()->status &= ~TS_POLLING; - smp_mb__after_clear_bit(); + /* + * TS_POLLING-cleared state must be visible before we + * test NEED_RESCHED: + */ + smp_mb(); } if (!need_resched()) { idled = 1; diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 1b34c56f812..8a8bbdaaf38 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -54,7 +54,7 @@ static struct cpu_dev __cpuinitdata default_cpu = { .c_init = default_init, .c_vendor = "Unknown", }; -static struct cpu_dev * this_cpu = &default_cpu; +static struct cpu_dev * this_cpu __cpuinitdata = &default_cpu; static int __init cachesize_setup(char *str) { @@ -710,11 +710,8 @@ __cpuinit int init_gdt(int cpu, struct task_struct *idle) return 1; } -/* Common CPU init for both boot and secondary CPUs */ -static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) +void __cpuinit cpu_set_gdt(int cpu) { - struct tss_struct * t = &per_cpu(init_tss, cpu); - struct thread_struct *thread = &curr->thread; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); /* Reinit these anyway, even if they've already been done (on @@ -722,6 +719,13 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) the real ones). */ load_gdt(cpu_gdt_descr); set_kernel_gs(); +} + +/* Common CPU init for both boot and secondary CPUs */ +static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) +{ + struct tss_struct * t = &per_cpu(init_tss, cpu); + struct thread_struct *thread = &curr->thread; if (cpu_test_and_set(cpu, cpu_initialized)) { printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); @@ -807,6 +811,7 @@ void __cpuinit cpu_init(void) local_irq_enable(); } + cpu_set_gdt(cpu); _cpu_init(cpu, curr); } diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 18f4715c655..10baa3501ed 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -126,27 +126,6 @@ static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data) } } -static void wrport(u16 port, u8 bit_width, u32 value) -{ - if (bit_width <= 8) - outb(value, port); - else if (bit_width <= 16) - outw(value, port); - else if (bit_width <= 32) - outl(value, port); -} - -static void rdport(u16 port, u8 bit_width, u32 * ret) -{ - *ret = 0; - if (bit_width <= 8) - *ret = inb(port); - else if (bit_width <= 16) - *ret = inw(port); - else if (bit_width <= 32) - *ret = inl(port); -} - struct msr_addr { u32 reg; }; @@ -177,7 +156,9 @@ static void do_drv_read(struct drv_cmd *cmd) rdmsr(cmd->addr.msr.reg, cmd->val, h); break; case SYSTEM_IO_CAPABLE: - rdport(cmd->addr.io.port, cmd->addr.io.bit_width, &cmd->val); + acpi_os_read_port((acpi_io_address)cmd->addr.io.port, + &cmd->val, + (u32)cmd->addr.io.bit_width); break; default: break; @@ -193,7 +174,9 @@ static void do_drv_write(struct drv_cmd *cmd) wrmsr(cmd->addr.msr.reg, cmd->val, h); break; case SYSTEM_IO_CAPABLE: - wrport(cmd->addr.io.port, cmd->addr.io.bit_width, cmd->val); + acpi_os_write_port((acpi_io_address)cmd->addr.io.port, + cmd->val, + (u32)cmd->addr.io.bit_width); break; default: break; @@ -390,8 +373,8 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, cpumask_t online_policy_cpus; struct drv_cmd cmd; unsigned int msr; - unsigned int next_state = 0; - unsigned int next_perf_state = 0; + unsigned int next_state = 0; /* Index into freq_table */ + unsigned int next_perf_state = 0; /* Index into perf table */ unsigned int i; int result = 0; @@ -437,6 +420,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, msr = (u32) perf->states[next_perf_state]. control & INTEL_MSR_RANGE; + cmd.val = get_cur_val(online_policy_cpus); cmd.val = (cmd.val & ~INTEL_MSR_RANGE) | msr; break; case SYSTEM_IO_CAPABLE: @@ -456,8 +440,8 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, else cpu_set(policy->cpu, cmd.mask); - freqs.old = data->freq_table[perf->state].frequency; - freqs.new = data->freq_table[next_perf_state].frequency; + freqs.old = perf->states[perf->state].core_frequency * 1000; + freqs.new = data->freq_table[next_state].frequency; for_each_cpu_mask(i, cmd.mask) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); @@ -694,19 +678,20 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) valid_states++; } data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END; + perf->state = 0; result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table); if (result) goto err_freqfree; - switch (data->cpu_feature) { + switch (perf->control_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: /* Current speed is unknown and not detectable by IO port */ policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); break; case ACPI_ADR_SPACE_FIXED_HARDWARE: acpi_cpufreq_driver.get = get_cur_freq_on_cpu; - get_cur_freq_on_cpu(cpu); + policy->cur = get_cur_freq_on_cpu(cpu); break; default: break; diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index c548daad347..a3db9332d65 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -52,6 +52,10 @@ #define CPU_EZRA_T 4 #define CPU_NEHEMIAH 5 +/* Flags */ +#define USE_ACPI_C3 (1 << 1) +#define USE_NORTHBRIDGE (1 << 2) + static int cpu_model; static unsigned int numscales=16; static unsigned int fsb; @@ -68,7 +72,7 @@ static unsigned int minmult, maxmult; static int can_scale_voltage; static struct acpi_processor *pr = NULL; static struct acpi_processor_cx *cx = NULL; -static int port22_en; +static u8 longhaul_flags; /* Module parameters */ static int scale_voltage; @@ -80,7 +84,6 @@ static int ignore_latency; /* Clock ratios multiplied by 10 */ static int clock_ratio[32]; static int eblcr_table[32]; -static unsigned int highest_speed, lowest_speed; /* kHz */ static int longhaul_version; static struct cpufreq_frequency_table *longhaul_table; @@ -178,7 +181,7 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index) safe_halt(); /* Change frequency on next halt or sleep */ wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - if (port22_en) { + if (!cx_address) { ACPI_FLUSH_CPU_CACHE(); /* Invoke C1 */ halt(); @@ -187,9 +190,8 @@ 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_fadt.xpm_tmr_blk.address); + t = inl(acpi_gbl_FADT.xpm_timer_block.address); } - /* Disable bus ratio bit */ local_irq_disable(); longhaul.bits.RevisionKey = longhaul.bits.RevisionID; @@ -243,15 +245,13 @@ static void longhaul_setstate(unsigned int clock_ratio_index) outb(0xFF,0xA1); /* Overkill */ outb(0xFE,0x21); /* TMR0 only */ - if (pr->flags.bm_control) { - /* Disable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, - ACPI_MTX_DO_NOT_LOCK); - } else if (port22_en) { + if (longhaul_flags & USE_NORTHBRIDGE) { /* Disable AGP and PCI arbiters */ outb(3, 0x22); + } else if ((pr != NULL) && pr->flags.bm_control) { + /* Disable bus master arbitration */ + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); } - switch (longhaul_version) { /* @@ -278,22 +278,23 @@ static void longhaul_setstate(unsigned int clock_ratio_index) * to work in practice. */ case TYPE_POWERSAVER: - /* Don't allow wakeup */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, - ACPI_MTX_DO_NOT_LOCK); - do_powersaver(cx->address, clock_ratio_index); + if (longhaul_flags & USE_ACPI_C3) { + /* Don't allow wakeup */ + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + do_powersaver(cx->address, clock_ratio_index); + } else { + do_powersaver(0, clock_ratio_index); + } break; } - if (pr->flags.bm_control) { - /* Enable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, - ACPI_MTX_DO_NOT_LOCK); - } else if (port22_en) { + if (longhaul_flags & USE_NORTHBRIDGE) { /* Enable arbiters */ outb(0, 0x22); + } else if ((pr != NULL) && pr->flags.bm_control) { + /* Enable bus master arbitration */ + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); } - outb(pic2_mask,0xA1); /* restore mask */ outb(pic1_mask,0x21); @@ -314,12 +315,12 @@ static void longhaul_setstate(unsigned int clock_ratio_index) #define ROUNDING 0xf -static int _guess(int guess) +static int _guess(int guess, int mult) { int target; - target = ((maxmult/10)*guess); - if (maxmult%10 != 0) + target = ((mult/10)*guess); + if (mult%10 != 0) target += (guess/2); target += ROUNDING/2; target &= ~ROUNDING; @@ -327,17 +328,17 @@ static int _guess(int guess) } -static int guess_fsb(void) +static int guess_fsb(int mult) { int speed = (cpu_khz/1000); int i; - int speeds[3] = { 66, 100, 133 }; + int speeds[] = { 66, 100, 133, 200 }; speed += ROUNDING/2; speed &= ~ROUNDING; - for (i=0; i<3; i++) { - if (_guess(speeds[i]) == speed) + for (i=0; i<4; i++) { + if (_guess(speeds[i], mult) == speed) return speeds[i]; } return 0; @@ -354,9 +355,7 @@ static int __init longhaul_get_ranges(void) 130, 150, 160, 140, -1, 155, -1, 145 }; unsigned int j, k = 0; union msr_longhaul longhaul; - unsigned long lo, hi; - unsigned int eblcr_fsb_table_v1[] = { 66, 133, 100, -1 }; - unsigned int eblcr_fsb_table_v2[] = { 133, 100, -1, 66 }; + int mult = 0; switch (longhaul_version) { case TYPE_LONGHAUL_V1: @@ -364,30 +363,18 @@ static int __init longhaul_get_ranges(void) /* Ugh, Longhaul v1 didn't have the min/max MSRs. Assume min=3.0x & max = whatever we booted at. */ minmult = 30; - maxmult = longhaul_get_cpu_mult(); - rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); - invalue = (lo & (1<<18|1<<19)) >>18; - if (cpu_model==CPU_SAMUEL || cpu_model==CPU_SAMUEL2) - fsb = eblcr_fsb_table_v1[invalue]; - else - fsb = guess_fsb(); + maxmult = mult = longhaul_get_cpu_mult(); break; case TYPE_POWERSAVER: /* Ezra-T */ if (cpu_model==CPU_EZRA_T) { + minmult = 30; rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); invalue = longhaul.bits.MaxMHzBR; if (longhaul.bits.MaxMHzBR4) invalue += 16; - maxmult=ezra_t_multipliers[invalue]; - - invalue = longhaul.bits.MinMHzBR; - if (longhaul.bits.MinMHzBR4 == 1) - minmult = 30; - else - minmult = ezra_t_multipliers[invalue]; - fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB]; + maxmult = mult = ezra_t_multipliers[invalue]; break; } @@ -407,21 +394,16 @@ static int __init longhaul_get_ranges(void) * But it works, so we don't grumble. */ minmult=40; - maxmult=longhaul_get_cpu_mult(); - - /* Starting with the 1.2GHz parts, theres a 200MHz bus. */ - if ((cpu_khz/maxmult) > 13400) - fsb = 200; - else - fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB]; + maxmult = mult = longhaul_get_cpu_mult(); break; } } + fsb = guess_fsb(mult); dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n", minmult/10, minmult%10, maxmult/10, maxmult%10); - if (fsb == -1) { + if (fsb == 0) { printk (KERN_INFO PFX "Invalid (reserved) FSB!\n"); return -EINVAL; } @@ -429,7 +411,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) { @@ -513,7 +495,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; @@ -691,27 +673,32 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) /* Find ACPI data for processor */ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, &longhaul_walk_callback, NULL, (void *)&pr); - if (pr == NULL) - goto err_acpi; - if (longhaul_version == TYPE_POWERSAVER) { - /* Check ACPI support for C3 state */ + /* Check ACPI support for C3 state */ + if ((pr != NULL) && (longhaul_version == TYPE_POWERSAVER)) { cx = &pr->power.states[ACPI_STATE_C3]; if (cx->address > 0 && (cx->latency <= 1000 || ignore_latency != 0) ) { + longhaul_flags |= USE_ACPI_C3; goto print_support_type; } } + /* Check if northbridge is friendly */ + if (enable_arbiter_disable()) { + longhaul_flags |= USE_NORTHBRIDGE; + goto print_support_type; + } + + /* No ACPI C3 or we can't use it */ /* Check ACPI support for bus master arbiter disable */ - if (!pr->flags.bm_control) { - if (enable_arbiter_disable()) { - port22_en = 1; - } else { - goto err_acpi; - } + if ((pr == NULL) || !(pr->flags.bm_control)) { + printk(KERN_ERR PFX + "No ACPI support. Unsupported northbridge.\n"); + return -ENODEV; } + print_support_type: - if (!port22_en) { + if (!(longhaul_flags & USE_NORTHBRIDGE)) { printk (KERN_INFO PFX "Using ACPI support.\n"); } else { printk (KERN_INFO PFX "Using northbridge support.\n"); @@ -736,10 +723,6 @@ print_support_type: cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu); return 0; - -err_acpi: - printk(KERN_ERR PFX "No ACPI support. Unsupported northbridge. Aborting.\n"); - return -ENODEV; } static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy) @@ -774,8 +757,8 @@ static int __init longhaul_init(void) #ifdef CONFIG_SMP if (num_online_cpus() > 1) { - return -ENODEV; printk(KERN_ERR PFX "More than 1 CPU detected, longhaul disabled.\n"); + return -ENODEV; } #endif #ifdef CONFIG_X86_IO_APIC @@ -787,8 +770,10 @@ static int __init longhaul_init(void) switch (c->x86_model) { case 6 ... 9: return cpufreq_register_driver(&longhaul_driver); + case 10: + printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n"); default: - printk (KERN_INFO PFX "Unknown VIA CPU. Contact davej@codemonkey.org.uk\n"); + ;; } return -ENODEV; diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index bec50170b75..4786fedca6e 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -51,7 +51,6 @@ enum { static int has_N44_O17_errata[NR_CPUS]; -static int has_N60_errata[NR_CPUS]; static unsigned int stock_freq; static struct cpufreq_driver p4clockmod_driver; static unsigned int cpufreq_p4_get(unsigned int cpu); @@ -224,12 +223,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) case 0x0f12: has_N44_O17_errata[policy->cpu] = 1; dprintk("has errata -- disabling low frequencies\n"); - break; - - case 0x0f29: - has_N60_errata[policy->cpu] = 1; - dprintk("has errata -- disabling frequencies lower than 2ghz\n"); - break; } /* get max frequency */ @@ -241,8 +234,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { if ((i<2) && (has_N44_O17_errata[policy->cpu])) p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; - else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000) - p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; else p4clockmod_table[i].frequency = (stock_freq * i)/8; } diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 5113e923163..f43b987f952 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -533,9 +533,9 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) /* notify BIOS that we exist */ acpi_processor_notify_smm(THIS_MODULE); - printk("speedstep-centrino with X86_SPEEDSTEP_CENTRINO_ACPI" - "config is deprecated.\n " - "Use X86_ACPI_CPUFREQ (acpi-cpufreq instead.\n" ); + printk("speedstep-centrino with X86_SPEEDSTEP_CENTRINO_ACPI " + "config is deprecated.\n " + "Use X86_ACPI_CPUFREQ (acpi-cpufreq) instead.\n" ); return 0; diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index 2f7d0a92fd7..f391abcf7da 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -668,7 +668,7 @@ void __init register_bootmem_low_pages(unsigned long max_low_pfn) } } -void __init register_memory(void) +void __init e820_register_memory(void) { unsigned long gapstart, gapsize, round; unsigned long long last; diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index de34b7fed3c..5e47683fc63 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -302,12 +302,16 @@ sysenter_past_esp: pushl $(__USER_CS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET cs, 0*/ +#ifndef CONFIG_COMPAT_VDSO /* * Push current_thread_info()->sysenter_return to the stack. * A tiny bit of offset fixup is necessary - 4*4 means the 4 words * pushed above; +8 corresponds to copy_thread's esp0 setting. */ pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) +#else + pushl $SYSENTER_RETURN +#endif CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eip, 0 @@ -979,38 +983,6 @@ ENTRY(spurious_interrupt_bug) jmp error_code CFI_ENDPROC -#ifdef CONFIG_STACK_UNWIND -ENTRY(arch_unwind_init_running) - CFI_STARTPROC - movl 4(%esp), %edx - movl (%esp), %ecx - leal 4(%esp), %eax - movl %ebx, PT_EBX(%edx) - xorl %ebx, %ebx - movl %ebx, PT_ECX(%edx) - movl %ebx, PT_EDX(%edx) - movl %esi, PT_ESI(%edx) - movl %edi, PT_EDI(%edx) - movl %ebp, PT_EBP(%edx) - movl %ebx, PT_EAX(%edx) - movl $__USER_DS, PT_DS(%edx) - movl $__USER_DS, PT_ES(%edx) - movl $0, PT_GS(%edx) - movl %ebx, PT_ORIG_EAX(%edx) - movl %ecx, PT_EIP(%edx) - movl 12(%esp), %ecx - movl $__KERNEL_CS, PT_CS(%edx) - movl %ebx, PT_EFLAGS(%edx) - movl %eax, PT_OLDESP(%edx) - movl 8(%esp), %eax - movl %ecx, 8(%esp) - movl PT_EBX(%edx), %ebx - movl $__KERNEL_DS, PT_OLDSS(%edx) - jmpl *%eax - CFI_ENDPROC -ENDPROC(arch_unwind_init_running) -#endif - ENTRY(kernel_thread_helper) pushl $0 # fake return address for unwinder CFI_STARTPROC diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 2424cc9c7b3..6a3875f81a0 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1227,26 +1227,32 @@ static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 } static int __assign_irq_vector(int irq) { - static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; - int vector; + static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; + int vector, offset, i; BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); if (irq_vector[irq] > 0) return irq_vector[irq]; - current_vector += 8; - if (current_vector == SYSCALL_VECTOR) - current_vector += 8; - - if (current_vector >= FIRST_SYSTEM_VECTOR) { - offset++; - if (!(offset % 8)) - return -ENOSPC; - current_vector = FIRST_DEVICE_VECTOR + offset; - } - vector = current_vector; + offset = current_offset; +next: + vector += 8; + if (vector >= FIRST_SYSTEM_VECTOR) { + offset = (offset + 1) % 8; + vector = FIRST_DEVICE_VECTOR + offset; + } + if (vector == current_vector) + return -ENOSPC; + if (vector == SYSCALL_VECTOR) + goto next; + for (i = 0; i < NR_IRQ_VECTORS; i++) + if (irq_vector[i] == vector) + goto next; + + current_vector = vector; + current_offset = offset; irq_vector[irq] = vector; return vector; diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 47ffec57c0c..c8fa13721bc 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -722,7 +722,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) return NOTIFY_OK; } -static struct notifier_block mc_cpu_notifier = { +static struct notifier_block __cpuinitdata mc_cpu_notifier = { .notifier_call = mc_cpu_callback, }; diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 2ce67228dff..4f5983c9866 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -36,7 +36,7 @@ /* Have we found an MP table */ int smp_found_config; -unsigned int __initdata maxcpus = NR_CPUS; +unsigned int __cpuinitdata maxcpus = NR_CPUS; /* * Various Linux-internal data structures created from the @@ -102,9 +102,9 @@ static int __init mpf_checksum(unsigned char *mp, int len) */ static int mpc_record; -static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; +static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __cpuinitdata; -static void __devinit MP_processor_info (struct mpc_config_processor *m) +static void __cpuinit MP_processor_info (struct mpc_config_processor *m) { int ver, apicid; physid_mask_t phys_cpu; @@ -822,7 +822,7 @@ void __init mp_register_lapic_address(u64 address) Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); } -void __devinit mp_register_lapic (u8 id, u8 enabled) +void __cpuinit mp_register_lapic (u8 id, u8 enabled) { struct mpc_config_processor processor; int boot_cpu = 0; @@ -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_fadt.sci_int == gsi) + if (acpi_gbl_FADT.sci_interrupt == 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_fadt.sci_int) + if (gsi == acpi_gbl_FADT.sci_interrupt) gsi = pci_irq++; gsi_to_irq[irq] = gsi; } else { diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index a5e34d65596..1a6f8bb8881 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -310,13 +310,7 @@ static int __init setup_nmi_watchdog(char *str) if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) return 0; - /* - * If any other x86 CPU has a local APIC, then - * please test the NMI stuff there and send me the - * missing bits. Right now Intel P6/P4 and AMD K7 only. - */ - if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0)) - return 0; /* no lapic support */ + nmi_watchdog = nmi; return 1; } diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 3dceab5828f..e55fd05da0f 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -566,4 +566,11 @@ struct paravirt_ops paravirt_ops = { .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, }; -EXPORT_SYMBOL(paravirt_ops); + +/* + * NOTE: CONFIG_PARAVIRT is experimental and the paravirt_ops + * semantics are subject to change. Hence we only do this + * internal-only export of this, until it gets sorted out and + * all lowlevel CPU ops used by modules are separately exported. + */ +EXPORT_SYMBOL_GPL(paravirt_ops); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 99308510a17..c641056233a 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -102,7 +102,12 @@ void default_idle(void) { if (!hlt_counter && boot_cpu_data.hlt_works_ok) { current_thread_info()->status &= ~TS_POLLING; - smp_mb__after_clear_bit(); + /* + * TS_POLLING-cleared state must be visible before we + * test NEED_RESCHED: + */ + smp_mb(); + local_irq_disable(); if (!need_resched()) safe_halt(); /* enables interrupts racelessly */ diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index f3f94ac5736..af8aabe8580 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -45,7 +45,7 @@ /* * Offset of eflags on child stack.. */ -#define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs)) +#define EFL_OFFSET offsetof(struct pt_regs, eflags) static inline struct pt_regs *get_child_regs(struct task_struct *task) { @@ -54,24 +54,24 @@ static inline struct pt_regs *get_child_regs(struct task_struct *task) } /* - * this routine will get a word off of the processes privileged stack. - * the offset is how far from the base addr as stored in the TSS. - * this routine assumes that all the privileged stacks are in our + * This routine will get a word off of the processes privileged stack. + * the offset is bytes into the pt_regs structure on the stack. + * This routine assumes that all the privileged stacks are in our * data space. */ static inline int get_stack_long(struct task_struct *task, int offset) { unsigned char *stack; - stack = (unsigned char *)task->thread.esp0; + stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs); stack += offset; return (*((int *)stack)); } /* - * this routine will put a word on the processes privileged stack. - * the offset is how far from the base addr as stored in the TSS. - * this routine assumes that all the privileged stacks are in our + * This routine will put a word on the processes privileged stack. + * the offset is bytes into the pt_regs structure on the stack. + * This routine assumes that all the privileged stacks are in our * data space. */ static inline int put_stack_long(struct task_struct *task, int offset, @@ -79,7 +79,7 @@ static inline int put_stack_long(struct task_struct *task, int offset, { unsigned char * stack; - stack = (unsigned char *) task->thread.esp0; + stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs); stack += offset; *(unsigned long *) stack = data; return 0; @@ -114,7 +114,7 @@ static int putreg(struct task_struct *child, } if (regno > ES*4) regno -= 1*4; - put_stack_long(child, regno - sizeof(struct pt_regs), value); + put_stack_long(child, regno, value); return 0; } @@ -137,7 +137,6 @@ static unsigned long getreg(struct task_struct *child, default: if (regno > ES*4) regno -= 1*4; - regno = regno - sizeof(struct pt_regs); retval &= get_stack_long(child, regno); } return retval; diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 79df6e612db..4b31ad70c1a 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -77,7 +77,7 @@ extern struct resource code_resource; extern struct resource data_resource; /* cpu data as detected by the assembly code in head.S */ -struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; /* common cpu data for all cpus */ struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; EXPORT_SYMBOL(boot_cpu_data); @@ -495,7 +495,7 @@ static void set_mca_bus(int x) { } #endif /* Overridden in paravirt.c if CONFIG_PARAVIRT */ -char * __attribute__((weak)) memory_setup(void) +char * __init __attribute__((weak)) memory_setup(void) { return machine_specific_memory_setup(); } @@ -639,7 +639,7 @@ void __init setup_arch(char **cmdline_p) get_smp_config(); #endif - register_memory(); + e820_register_memory(); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index aef39be8136..8c6c8c52b95 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -159,7 +159,7 @@ void __init smp_alloc_memory(void) * a given CPU */ -static void __devinit smp_store_cpu_info(int id) +static void __cpuinit smp_store_cpu_info(int id) { struct cpuinfo_x86 *c = cpu_data + id; @@ -227,7 +227,7 @@ static struct { atomic_t count_start; atomic_t count_stop; unsigned long long values[NR_CPUS]; -} tsc __initdata = { +} tsc __cpuinitdata = { .start_flag = ATOMIC_INIT(0), .count_start = ATOMIC_INIT(0), .count_stop = ATOMIC_INIT(0), @@ -332,7 +332,7 @@ static void __init synchronize_tsc_bp(void) printk("passed.\n"); } -static void __init synchronize_tsc_ap(void) +static void __cpuinit synchronize_tsc_ap(void) { int i; @@ -364,7 +364,7 @@ extern void calibrate_delay(void); static atomic_t init_deasserted; -static void __devinit smp_callin(void) +static void __cpuinit smp_callin(void) { int cpuid, phys_id; unsigned long timeout; @@ -538,7 +538,7 @@ set_cpu_sibling_map(int cpu) /* * Activate a secondary processor. */ -static void __devinit start_secondary(void *unused) +static void __cpuinit start_secondary(void *unused) { /* * Don't put *anything* before secondary_cpu_init(), SMP @@ -596,6 +596,12 @@ static void __devinit start_secondary(void *unused) void __devinit initialize_secondary(void) { /* + * switch to the per CPU GDT we already set up + * in do_boot_cpu() + */ + cpu_set_gdt(current_thread_info()->cpu); + + /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. */ @@ -931,7 +937,7 @@ static inline struct task_struct * alloc_idle_task(int cpu) #define alloc_idle_task(cpu) fork_idle(cpu) #endif -static int __devinit do_boot_cpu(int apicid, int cpu) +static int __cpuinit do_boot_cpu(int apicid, int cpu) /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad * (ie clustered apic addressing mode), this is a LOGICAL apic ID. @@ -972,9 +978,6 @@ static int __devinit do_boot_cpu(int apicid, int cpu) /* Stack for startup_32 can be just as for start_secondary onwards */ stack_start.esp = (void *) idle->thread.esp; - start_pda = cpu_pda(cpu); - cpu_gdt_descr = per_cpu(cpu_gdt_descr, cpu); - irq_ctx_init(cpu); x86_cpu_to_apicid[cpu] = apicid; @@ -1432,7 +1435,7 @@ void __cpu_die(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -int __devinit __cpu_up(unsigned int cpu) +int __cpuinit __cpu_up(unsigned int cpu) { #ifdef CONFIG_HOTPLUG_CPU int ret=0; diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c index f7e735c077c..2a8713ec0f9 100644 --- a/arch/i386/kernel/srat.c +++ b/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_table_processor_affinity *cpu_affinity = - (struct acpi_table_processor_affinity *) p; + struct acpi_srat_cpu_affinity *cpu_affinity = + (struct acpi_srat_cpu_affinity *) p; - if (!cpu_affinity->flags.enabled) + if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0) return; /* empty entry */ /* mark this node as "seen" in node bitmap */ - BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain); + BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo); - apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain; + apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo; printk("CPU 0x%02X in proximity domain 0x%02X\n", - cpu_affinity->apic_id, cpu_affinity->proximity_domain); + cpu_affinity->apic_id, cpu_affinity->proximity_domain_lo); } /* @@ -84,28 +84,27 @@ 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_table_memory_affinity *memory_affinity = - (struct acpi_table_memory_affinity *) sratp; + struct acpi_srat_mem_affinity *memory_affinity = + (struct acpi_srat_mem_affinity *) sratp; - if (!memory_affinity->flags.enabled) + if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0) return; /* empty entry */ + pxm = memory_affinity->proximity_domain & 0xff; + /* mark this node as "seen" in node bitmap */ - BMAP_SET(pxm_bitmap, memory_affinity->proximity_domain); + BMAP_SET(pxm_bitmap, pxm); /* calculate info for memory chunk structure */ - 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; - + paddr = memory_affinity->base_address; + size = memory_affinity->length; + 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", @@ -132,8 +131,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, - memory_affinity->proximity_domain, - (memory_affinity->flags.hot_pluggable ? + pxm, + ((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ? "enabled and removable" : "enabled" ) ); } @@ -185,10 +184,10 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) num_memory_chunks = 0; while (p < end) { switch (*p) { - case ACPI_SRAT_PROCESSOR_AFFINITY: + case ACPI_SRAT_TYPE_CPU_AFFINITY: parse_cpu_affinity_structure(p); break; - case ACPI_SRAT_MEMORY_AFFINITY: + case ACPI_SRAT_TYPE_MEMORY_AFFINITY: parse_memory_affinity_structure(p); break; default: @@ -262,31 +261,30 @@ out_fail: 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; - struct acpi_pointer *rsdp_address = NULL; - struct acpi_table_rsdt saved_rsdt; + acpi_native_uint rsdp_address = 0; + struct acpi_static_rsdt saved_rsdt; int tables = 0; int i = 0; - if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, - rsdp_address))) { + rsdp_address = acpi_find_rsdp(); + if (!rsdp_address) { printk("%s: System description tables not found\n", __FUNCTION__); goto out_err; } - 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; - } + printk("%s: assigning address to rsdp\n", __FUNCTION__); + rsdp = (struct acpi_table_rsdp *)(u32)rsdp_address; if (!rsdp) { printk("%s: Didn't find ACPI root!\n", __FUNCTION__); goto out_err; @@ -295,13 +293,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, RSDP_SIG,strlen(RSDP_SIG))) { + if (strncmp(rsdp->signature, ACPI_SIG_RSDP,strlen(ACPI_SIG_RSDP))) { printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __FUNCTION__); goto out_err; } rsdt = (struct acpi_table_rsdt *) - boot_ioremap(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt)); + boot_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt)); if (!rsdt) { printk(KERN_WARNING @@ -310,9 +308,9 @@ int __init get_memcfg_from_srat(void) goto out_err; } - header = & rsdt->header; + header = &rsdt->header; - if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) { + if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) { printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); goto out_err; } @@ -330,9 +328,9 @@ int __init get_memcfg_from_srat(void) memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); - if (saved_rsdt.header.length > sizeof(saved_rsdt)) { + if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) { printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", - saved_rsdt.header.length); + saved_rsdt.table.header.length); goto out_err; } @@ -341,15 +339,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.entry[i], sizeof(struct acpi_table_header)); + boot_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header)); if (!header) break; header = (struct acpi_table_header *) - boot_ioremap(saved_rsdt.entry[i], header->length); + boot_ioremap(saved_rsdt.table.table_offset_entry[i], header->length); if (!header) break; - if (strncmp((char *) &header->signature, "SRAT", 4)) + if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4)) continue; /* we've found the srat table. don't need to look at any more tables */ diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 7de9117b5a3..5da744204d1 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -79,11 +79,6 @@ int __init sysenter_setup(void) #ifdef CONFIG_COMPAT_VDSO __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); -#else - /* - * In the non-compat case the ELF coredumping code needs the fixmap: - */ - __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); #endif if (!boot_cpu_has(X86_FEATURE_SEP)) { @@ -100,6 +95,7 @@ int __init sysenter_setup(void) return 0; } +#ifndef CONFIG_COMPAT_VDSO static struct page *syscall_nopage(struct vm_area_struct *vma, unsigned long adr, int *type) { @@ -146,6 +142,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) vma->vm_end = addr + PAGE_SIZE; /* MAYWRITE to allow gdb to COW and set breakpoints */ vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; + /* + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later + * without matching up the same kernel and hardware config to see + * what PC values meant. + */ + vma->vm_flags |= VM_ALWAYSDUMP; vma->vm_flags |= mm->def_flags; vma->vm_page_prot = protection_map[vma->vm_flags & 7]; vma->vm_ops = &syscall_vm_ops; @@ -187,3 +190,4 @@ int in_gate_area_no_task(unsigned long addr) { return 0; } +#endif diff --git a/arch/i386/kernel/trampoline.S b/arch/i386/kernel/trampoline.S index fcce0e61b0e..2f1814c5cfd 100644 --- a/arch/i386/kernel/trampoline.S +++ b/arch/i386/kernel/trampoline.S @@ -38,6 +38,11 @@ .data +/* We can free up trampoline after bootup if cpu hotplug is not supported. */ +#ifndef CONFIG_HOTPLUG_CPU +.section ".init.data","aw",@progbits +#endif + .code16 ENTRY(trampoline_data) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 2b30dbf8d11..0efad8aeb41 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -94,11 +94,6 @@ asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); int kstack_depth_to_print = 24; -#ifdef CONFIG_STACK_UNWIND -static int call_trace = 1; -#else -#define call_trace (-1) -#endif ATOMIC_NOTIFIER_HEAD(i386die_chain); int register_die_notifier(struct notifier_block *nb) @@ -152,33 +147,6 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, return ebp; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - -static asmlinkage int -dump_trace_unwind(struct unwind_frame_info *info, void *data) -{ - struct ops_and_data *oad = (struct ops_and_data *)data; - int n = 0; - unsigned long sp = UNW_SP(info); - - if (arch_unw_user_mode(info)) - return -1; - while (unwind(info) == 0 && UNW_PC(info)) { - n++; - oad->ops->address(oad->data, UNW_PC(info)); - if (arch_unw_user_mode(info)) - break; - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) - && sp > UNW_SP(info)) - break; - sp = UNW_SP(info); - } - return n; -} - #define MSG(msg) ops->warning(data, msg) void dump_trace(struct task_struct *task, struct pt_regs *regs, @@ -190,41 +158,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (!task) task = current; - if (call_trace >= 0) { - int unw_ret = 0; - struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; - - if (regs) { - if (unwind_init_frame_info(&info, task, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } else if (task == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, - &oad); - else { - if (unwind_init_blocked(&info, task) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } - if (unw_ret > 0) { - if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s", - UNW_PC(&info)); - if (UNW_SP(&info) >= PAGE_OFFSET) { - MSG("Leftover inexact backtrace:"); - stack = (void *)UNW_SP(&info); - if (!stack) - return; - ebp = UNW_FP(&info); - } else - MSG("Full inexact backtrace again:"); - } else if (call_trace >= 1) - return; - else - MSG("Full inexact backtrace again:"); - } else - MSG("Inexact backtrace:"); - } if (!stack) { unsigned long dummy; stack = &dummy; @@ -1258,19 +1191,3 @@ static int __init kstack_setup(char *s) return 1; } __setup("kstack=", kstack_setup); - -#ifdef CONFIG_STACK_UNWIND -static int __init call_trace_setup(char *s) -{ - if (strcmp(s, "old") == 0) - call_trace = -1; - else if (strcmp(s, "both") == 0) - call_trace = 0; - else if (strcmp(s, "newfallback") == 0) - call_trace = 1; - else if (strcmp(s, "new") == 2) - call_trace = 2; - return 1; -} -__setup("call_trace=", call_trace_setup); -#endif diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index 1bbe45dca7a..2cfc7b09b92 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -24,7 +24,7 @@ */ unsigned int tsc_khz; -int tsc_disable __cpuinitdata = 0; +int tsc_disable; #ifdef CONFIG_X86_TSC static int __init tsc_setup(char *str) diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index c511705c386..cc2f519b2f7 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c @@ -102,7 +102,7 @@ void __init time_init_hook(void) * along the MCA bus. Use this to hook into that chain if you will need * it. **/ -void __init mca_nmi_hook(void) +void mca_nmi_hook(void) { /* If I recall correctly, there's a whole bunch of other things that * we can do to check for NMI problems, but that's all I know about diff --git a/arch/i386/mach-es7000/es7000.h b/arch/i386/mach-es7000/es7000.h index 80566ca4a80..c8d5aa132fa 100644 --- a/arch/i386/mach-es7000/es7000.h +++ b/arch/i386/mach-es7000/es7000.h @@ -84,15 +84,6 @@ 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/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c index 3d0fc853516..9be6ceabf04 100644 --- a/arch/i386/mach-es7000/es7000plat.c +++ b/arch/i386/mach-es7000/es7000plat.c @@ -160,51 +160,14 @@ parse_unisys_oem (char *oemptr) int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { - 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; - } + 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; } } return -1; diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c index 33d9f93557b..8a210fa915b 100644 --- a/arch/i386/mach-generic/bigsmp.c +++ b/arch/i386/mach-generic/bigsmp.c @@ -45,7 +45,7 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { }; -static __init int probe_bigsmp(void) +static int probe_bigsmp(void) { if (def_to_bigsmp) dmi_bigsmp = 1; diff --git a/arch/i386/mach-generic/default.c b/arch/i386/mach-generic/default.c index 96c19821e47..8685208d851 100644 --- a/arch/i386/mach-generic/default.c +++ b/arch/i386/mach-generic/default.c @@ -18,7 +18,7 @@ #include <asm/mach-default/mach_mpparse.h> /* should be called last. */ -static __init int probe_default(void) +static int probe_default(void) { return 1; } diff --git a/arch/i386/mach-generic/es7000.c b/arch/i386/mach-generic/es7000.c index aa144d82334..b8963a5a3b2 100644 --- a/arch/i386/mach-generic/es7000.c +++ b/arch/i386/mach-generic/es7000.c @@ -19,7 +19,7 @@ #include <asm/mach-es7000/mach_mpparse.h> #include <asm/mach-es7000/mach_wakecpu.h> -static __init int probe_es7000(void) +static int probe_es7000(void) { /* probed later in mptable/ACPI hooks */ return 0; diff --git a/arch/i386/mach-generic/summit.c b/arch/i386/mach-generic/summit.c index f7e5d66648d..74883ccb8f7 100644 --- a/arch/i386/mach-generic/summit.c +++ b/arch/i386/mach-generic/summit.c @@ -18,7 +18,7 @@ #include <asm/mach-summit/mach_ipi.h> #include <asm/mach-summit/mach_mpparse.h> -static __init int probe_summit(void) +static int probe_summit(void) { /* probed later in mptable/ACPI hooks */ return 0; diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 55428e656a3..74aeedf277f 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -773,6 +773,12 @@ initialize_secondary(void) #endif /* + * switch to the per CPU GDT we already set up + * in do_boot_cpu() + */ + cpu_set_gdt(current_thread_info()->cpu); + + /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. */ diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index 103b76e56a9..e0c390d6ceb 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c @@ -405,3 +405,31 @@ void __init set_highmem_pages_init(int bad_ppro) totalram_pages += totalhigh_pages; #endif } + +#ifdef CONFIG_MEMORY_HOTPLUG +int paddr_to_nid(u64 addr) +{ + int nid; + unsigned long pfn = PFN_DOWN(addr); + + for_each_node(nid) + if (node_start_pfn[nid] <= pfn && + pfn < node_end_pfn[nid]) + return nid; + + return -1; +} + +/* + * This function is used to ask node id BEFORE memmap and mem_section's + * initialization (pfn_to_nid() can't be used yet). + * If _PXM is not defined on ACPI's DSDT, node id must be found by this. + */ +int memory_add_physaddr_to_nid(u64 addr) +{ + int nid = paddr_to_nid(addr); + return (nid >= 0) ? nid : 0; +} + +EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); +#endif diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 84697dfc734..c5c5ea700cc 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -283,7 +283,7 @@ void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro) SetPageReserved(page); } -static int add_one_highpage_hotplug(struct page *page, unsigned long pfn) +static int __meminit add_one_highpage_hotplug(struct page *page, unsigned long pfn) { free_new_highpage(page); totalram_pages++; @@ -300,7 +300,7 @@ static int add_one_highpage_hotplug(struct page *page, unsigned long pfn) * has been added dynamically that would be * onlined here is in HIGHMEM */ -void online_page(struct page *page) +void __meminit online_page(struct page *page) { ClearPageReserved(page); add_one_highpage_hotplug(page, page_to_pfn(page)); @@ -673,16 +673,10 @@ void __init mem_init(void) #endif } -/* - * this is for the non-NUMA, single node SMP system case. - * Specifically, in the case of x86, we will always add - * memory to the highmem for now. - */ #ifdef CONFIG_MEMORY_HOTPLUG -#ifndef CONFIG_NEED_MULTIPLE_NODES int arch_add_memory(int nid, u64 start, u64 size) { - struct pglist_data *pgdata = &contig_page_data; + struct pglist_data *pgdata = NODE_DATA(nid); struct zone *zone = pgdata->node_zones + ZONE_HIGHMEM; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; @@ -694,7 +688,7 @@ int remove_memory(u64 start, u64 size) { return -EINVAL; } -#endif +EXPORT_SYMBOL_GPL(remove_memory); #endif struct kmem_cache *pgd_cache; diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index cde1170b01a..8053b17ab64 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -115,7 +115,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci #define VIA_8363_KL133_REVISION_ID 0x81 #define VIA_8363_KM133_REVISION_ID 0x84 -static void __devinit pci_fixup_via_northbridge_bug(struct pci_dev *d) +static void pci_fixup_via_northbridge_bug(struct pci_dev *d) { u8 v; u8 revision; @@ -151,6 +151,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_northbridge_bug); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug); /* * For some reasons Intel decided that certain parts of their @@ -181,7 +185,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_ * issue another HALT within 80 ns of the initial HALT, the failure condition * is avoided. */ -static void __init pci_fixup_nforce2(struct pci_dev *dev) +static void pci_fixup_nforce2(struct pci_dev *dev) { u32 val; @@ -204,6 +208,7 @@ static void __init pci_fixup_nforce2(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2); /* Max PCI Express root ports */ #define MAX_PCIEROOT 6 @@ -419,7 +424,7 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032, * Prevent the BIOS trapping accesses to the Cyrix CS5530A video device * configuration space. */ -static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev) +static void pci_early_fixup_cyrix_5530(struct pci_dev *dev) { u8 r; /* clear 'F4 Video Configuration Trap' bit */ @@ -429,3 +434,5 @@ static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, pci_early_fixup_cyrix_5530); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, + pci_early_fixup_cyrix_5530); diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index c6b6d9bbc45..5700220dcf5 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -26,6 +26,7 @@ /* The base address of the last MMCONFIG device accessed */ static u32 mmcfg_last_accessed_device; +static int mmcfg_last_accessed_cpu; static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); @@ -35,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_table_mcfg_config *cfg; + struct acpi_mcfg_allocation *cfg; if (seg == 0 && bus < MAX_CHECK_BUS && test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) @@ -47,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_group_number != seg) + if (cfg->pci_segment != seg) continue; if ((cfg->start_bus_number <= bus) && (cfg->end_bus_number >= bus)) - return cfg->base_address; + return cfg->address; } /* Handle more broken MCFG tables on Asus etc. @@ -59,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_group_number == 0 && + cfg->pci_segment == 0 && (cfg->start_bus_number | cfg->end_bus_number) == 0) - return cfg->base_address; + return cfg->address; /* Fall back to type 0 */ return 0; @@ -73,8 +74,11 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) { u32 dev_base = base | (bus << 20) | (devfn << 12); - if (dev_base != mmcfg_last_accessed_device) { + int cpu = smp_processor_id(); + if (dev_base != mmcfg_last_accessed_device || + cpu != mmcfg_last_accessed_cpu) { mmcfg_last_accessed_device = dev_base; + mmcfg_last_accessed_cpu = cpu; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); } } @@ -121,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); @@ -195,19 +199,19 @@ void __init pci_mmcfg_init(int type) if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; - acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); if ((pci_mmcfg_config_num == 0) || (pci_mmcfg_config == NULL) || - (pci_mmcfg_config[0].base_address == 0)) + (pci_mmcfg_config[0].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].base_address, - pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, + if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].address, + pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, E820_RESERVED)) { - 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: BIOS Bug: MCFG area at %lx is not E820-reserved\n", + (unsigned long)pci_mmcfg_config[0].address); printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); return; } |