Revert "i386: move apic init in init_IRQs"
Commit f2b36db692
causes a bootup hang on
at least one machine. Revert for now until we understand why. The old
code may be ugly, but it works.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
d83c671fb7
commit
1e4c85f97f
10 changed files with 106 additions and 102 deletions
|
@ -803,7 +803,6 @@ static int __init detect_init_APIC (void)
|
|||
|
||||
void __init init_apic_mappings(void)
|
||||
{
|
||||
unsigned int orig_apicid;
|
||||
unsigned long apic_phys;
|
||||
|
||||
/*
|
||||
|
@ -825,11 +824,8 @@ void __init init_apic_mappings(void)
|
|||
* Fetch the APIC ID of the BSP in case we have a
|
||||
* default configuration (or the MP table is broken).
|
||||
*/
|
||||
orig_apicid = boot_cpu_physical_apicid;
|
||||
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
|
||||
if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid))
|
||||
printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)",
|
||||
orig_apicid, boot_cpu_physical_apicid);
|
||||
if (boot_cpu_physical_apicid == -1U)
|
||||
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
{
|
||||
|
@ -1259,81 +1255,40 @@ fastcall void smp_error_interrupt(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
/*
|
||||
* This initializes the IO-APIC and APIC hardware.
|
||||
* This initializes the IO-APIC and APIC hardware if this is
|
||||
* a UP kernel.
|
||||
*/
|
||||
int __init APIC_init(void)
|
||||
int __init APIC_init_uniprocessor (void)
|
||||
{
|
||||
if (enable_local_apic < 0) {
|
||||
printk(KERN_INFO "APIC disabled\n");
|
||||
return -1;
|
||||
}
|
||||
if (enable_local_apic < 0)
|
||||
clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
|
||||
|
||||
/* See if we have a SMP configuration or have forced enabled
|
||||
* the local apic.
|
||||
*/
|
||||
if (!smp_found_config && !acpi_lapic && !cpu_has_apic) {
|
||||
enable_local_apic = -1;
|
||||
if (!smp_found_config && !cpu_has_apic)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Complain if the BIOS pretends there is an apic.
|
||||
* Then get out because we don't have an a local apic.
|
||||
* Complain if the BIOS pretends there is one.
|
||||
*/
|
||||
if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
|
||||
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
|
||||
boot_cpu_physical_apicid);
|
||||
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
|
||||
enable_local_apic = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
verify_local_APIC();
|
||||
|
||||
/*
|
||||
* Should not be necessary because the MP table should list the boot
|
||||
* CPU too, but we do it for the sake of robustness anyway.
|
||||
* Makes no sense to do this check in clustered apic mode, so skip it
|
||||
*/
|
||||
if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
|
||||
printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
|
||||
boot_cpu_physical_apicid);
|
||||
physid_set(boot_cpu_physical_apicid, phys_cpu_present_map);
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch from PIC to APIC mode.
|
||||
*/
|
||||
connect_bsp_APIC();
|
||||
|
||||
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
|
||||
|
||||
setup_local_APIC();
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
/*
|
||||
* Now start the IO-APICs
|
||||
*/
|
||||
if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
|
||||
setup_IO_APIC();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init APIC_late_time_init(void)
|
||||
{
|
||||
/* Improve our loops per jiffy estimate */
|
||||
loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz;
|
||||
boot_cpu_data.loops_per_jiffy = loops_per_jiffy;
|
||||
cpu_data[0].loops_per_jiffy = loops_per_jiffy;
|
||||
|
||||
/* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is
|
||||
* initialized. So redo it here to ensure the boot cpu is setup
|
||||
* properly.
|
||||
*/
|
||||
if (nmi_watchdog == NMI_LOCAL_APIC)
|
||||
setup_apic_nmi_watchdog();
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
|
||||
IO_APIC_late_time_init();
|
||||
if (smp_found_config)
|
||||
if (!skip_ioapic_setup && nr_ioapics)
|
||||
setup_IO_APIC();
|
||||
#endif
|
||||
setup_boot_APIC_clock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -435,8 +435,4 @@ void __init init_IRQ(void)
|
|||
setup_irq(FPU_IRQ, &fpu_irq);
|
||||
|
||||
irq_ctx_init(smp_processor_id());
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
APIC_init();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2387,15 +2387,11 @@ void __init setup_IO_APIC(void)
|
|||
sync_Arb_IDs();
|
||||
setup_IO_APIC_irqs();
|
||||
init_IO_APIC_traps();
|
||||
check_timer();
|
||||
if (!acpi_ioapic)
|
||||
print_IO_APIC();
|
||||
}
|
||||
|
||||
void __init IO_APIC_late_time_init(void)
|
||||
{
|
||||
check_timer();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after all the initialization is done. If we didnt find any
|
||||
* APIC bugs then we can allow the modify fast path
|
||||
|
|
|
@ -1078,16 +1078,6 @@ void *xquad_portio;
|
|||
EXPORT_SYMBOL(xquad_portio);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fall back to non SMP mode after errors.
|
||||
*
|
||||
*/
|
||||
static __init void disable_smp(void)
|
||||
{
|
||||
cpu_set(0, cpu_sibling_map[0]);
|
||||
cpu_set(0, cpu_core_map[0]);
|
||||
}
|
||||
|
||||
static void __init smp_boot_cpus(unsigned int max_cpus)
|
||||
{
|
||||
int apicid, cpu, bit, kicked;
|
||||
|
@ -1100,6 +1090,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
|
|||
printk("CPU%d: ", 0);
|
||||
print_cpu_info(&cpu_data[0]);
|
||||
|
||||
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
|
||||
boot_cpu_logical_apicid = logical_smp_processor_id();
|
||||
x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
|
||||
|
||||
|
@ -1111,27 +1102,68 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
|
|||
cpus_clear(cpu_core_map[0]);
|
||||
cpu_set(0, cpu_core_map[0]);
|
||||
|
||||
map_cpu_to_logical_apicid();
|
||||
|
||||
/*
|
||||
* If we couldn't find an SMP configuration at boot time,
|
||||
* get out of here now!
|
||||
*/
|
||||
if (!smp_found_config && !acpi_lapic) {
|
||||
printk(KERN_NOTICE "SMP motherboard not detected.\n");
|
||||
disable_smp();
|
||||
smpboot_clear_io_apic_irqs();
|
||||
phys_cpu_present_map = physid_mask_of_physid(0);
|
||||
if (APIC_init_uniprocessor())
|
||||
printk(KERN_NOTICE "Local APIC not detected."
|
||||
" Using dummy APIC emulation.\n");
|
||||
map_cpu_to_logical_apicid();
|
||||
cpu_set(0, cpu_sibling_map[0]);
|
||||
cpu_set(0, cpu_core_map[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If SMP should be disabled, then really disable it!
|
||||
* Should not be necessary because the MP table should list the boot
|
||||
* CPU too, but we do it for the sake of robustness anyway.
|
||||
* Makes no sense to do this check in clustered apic mode, so skip it
|
||||
*/
|
||||
if (!max_cpus || (enable_local_apic < 0)) {
|
||||
printk(KERN_INFO "SMP mode deactivated.\n");
|
||||
disable_smp();
|
||||
if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
|
||||
printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
|
||||
boot_cpu_physical_apicid);
|
||||
physid_set(hard_smp_processor_id(), phys_cpu_present_map);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we couldn't find a local APIC, then get out of here now!
|
||||
*/
|
||||
if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
|
||||
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
|
||||
boot_cpu_physical_apicid);
|
||||
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
|
||||
smpboot_clear_io_apic_irqs();
|
||||
phys_cpu_present_map = physid_mask_of_physid(0);
|
||||
cpu_set(0, cpu_sibling_map[0]);
|
||||
cpu_set(0, cpu_core_map[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
verify_local_APIC();
|
||||
|
||||
/*
|
||||
* If SMP should be disabled, then really disable it!
|
||||
*/
|
||||
if (!max_cpus) {
|
||||
smp_found_config = 0;
|
||||
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
|
||||
smpboot_clear_io_apic_irqs();
|
||||
phys_cpu_present_map = physid_mask_of_physid(0);
|
||||
cpu_set(0, cpu_sibling_map[0]);
|
||||
cpu_set(0, cpu_core_map[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
connect_bsp_APIC();
|
||||
setup_local_APIC();
|
||||
map_cpu_to_logical_apicid();
|
||||
|
||||
|
||||
setup_portio_remap();
|
||||
|
||||
/*
|
||||
|
@ -1212,6 +1244,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
|
|||
cpu_set(0, cpu_sibling_map[0]);
|
||||
cpu_set(0, cpu_core_map[0]);
|
||||
|
||||
smpboot_setup_io_apic();
|
||||
|
||||
setup_boot_APIC_clock();
|
||||
|
||||
/*
|
||||
* Synchronize the TSC with the AP
|
||||
*/
|
||||
|
|
|
@ -440,8 +440,8 @@ static int time_init_device(void)
|
|||
|
||||
device_initcall(time_init_device);
|
||||
|
||||
extern void (*late_time_init)(void);
|
||||
#ifdef CONFIG_HPET_TIMER
|
||||
extern void (*late_time_init)(void);
|
||||
/* Duplicate of time_init() below, with hpet_enable part added */
|
||||
static void __init hpet_time_init(void)
|
||||
{
|
||||
|
@ -458,11 +458,6 @@ static void __init hpet_time_init(void)
|
|||
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
|
||||
|
||||
time_init_hook();
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
if (enable_local_apic >= 0)
|
||||
APIC_late_time_init();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -487,9 +482,4 @@ void __init time_init(void)
|
|||
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
|
||||
|
||||
time_init_hook();
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
if (enable_local_apic >= 0)
|
||||
late_time_init = APIC_late_time_init;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -118,8 +118,7 @@ extern void release_lapic_nmi(void);
|
|||
extern void disable_timer_nmi_watchdog(void);
|
||||
extern void enable_timer_nmi_watchdog(void);
|
||||
extern void nmi_watchdog_tick (struct pt_regs * regs);
|
||||
extern int APIC_init(void);
|
||||
extern void APIC_late_time_init(void);
|
||||
extern int APIC_init_uniprocessor (void);
|
||||
extern void disable_APIC_timer(void);
|
||||
extern void enable_APIC_timer(void);
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ void init_8259A(int aeoi);
|
|||
void FASTCALL(send_IPI_self(int vector));
|
||||
void init_VISWS_APIC_irqs(void);
|
||||
void setup_IO_APIC(void);
|
||||
void IO_APIC_late_time_init(void);
|
||||
void disable_IO_APIC(void);
|
||||
void print_IO_APIC(void);
|
||||
int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
|
||||
* which needs to alter them. */
|
||||
|
||||
static inline void smpboot_clear_io_apic_irqs(void)
|
||||
{
|
||||
io_apic_irqs = 0;
|
||||
}
|
||||
|
||||
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
|
||||
{
|
||||
CMOS_WRITE(0xa, 0xf);
|
||||
|
@ -27,3 +32,13 @@ static inline void smpboot_restore_warm_reset_vector(void)
|
|||
|
||||
*((volatile long *) phys_to_virt(0x467)) = 0;
|
||||
}
|
||||
|
||||
static inline void smpboot_setup_io_apic(void)
|
||||
{
|
||||
/*
|
||||
* Here we can be sure that there is an IO-APIC in the system. Let's
|
||||
* go and set it up:
|
||||
*/
|
||||
if (!skip_ioapic_setup && nr_ioapics)
|
||||
setup_IO_APIC();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,14 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
|
|||
|
||||
/* for visws do nothing for any of these */
|
||||
|
||||
static inline void smpboot_clear_io_apic_irqs(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void smpboot_restore_warm_reset_vector(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void smpboot_setup_io_apic(void)
|
||||
{
|
||||
}
|
||||
|
|
11
init/main.c
11
init/main.c
|
@ -64,6 +64,10 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
#include <asm/smp.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Versions of gcc older than that listed below may actually compile
|
||||
* and link okay, but the end product can have subtle run time bugs.
|
||||
|
@ -310,7 +314,14 @@ extern void setup_arch(char **);
|
|||
|
||||
#ifndef CONFIG_SMP
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
static void __init smp_init(void)
|
||||
{
|
||||
APIC_init_uniprocessor();
|
||||
}
|
||||
#else
|
||||
#define smp_init() do { } while (0)
|
||||
#endif
|
||||
|
||||
static inline void setup_per_cpu_areas(void) { }
|
||||
static inline void smp_prepare_cpus(unsigned int maxcpus) { }
|
||||
|
|
Loading…
Reference in a new issue