Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 99330
b: refs/heads/master
c: 691874f
h: refs/heads/master
v: v3
  • Loading branch information
Maciej W. Rozycki authored and Ingo Molnar committed Jul 8, 2008
1 parent b606bf6 commit afa9b2a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 03be750559b2fe20d85dd968e08d5fe1c3accf83
refs/heads/master: 691874fa96d6349a8b60f8ea9c2bae52ece79941
38 changes: 28 additions & 10 deletions trunk/arch/x86/kernel/io_apic_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -2122,6 +2122,7 @@ static inline void __init unlock_ExtINT_logic(void)
static inline void __init check_timer(void)
{
int apic1, pin1, apic2, pin2;
int no_pin1 = 0;
int vector;
unsigned int ver;
unsigned long flags;
Expand Down Expand Up @@ -2159,10 +2160,30 @@ static inline void __init check_timer(void)
printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
vector, apic1, pin1, apic2, pin2);

/*
* Some BIOS writers are clueless and report the ExtINTA
* I/O APIC input from the cascaded 8259A as the timer
* interrupt input. So just in case, if only one pin
* was found above, try it both directly and through the
* 8259A.
*/
if (pin1 == -1) {
pin1 = pin2;
apic1 = apic2;
no_pin1 = 1;
} else if (pin2 == -1) {
pin2 = pin1;
apic2 = apic1;
}

if (pin1 != -1) {
/*
* Ok, does IRQ0 through the IOAPIC work?
*/
if (no_pin1) {
add_pin_to_irq(0, apic1, pin1);
setup_timer_IRQ0_pin(apic1, pin1, vector);
}
unmask_IO_APIC_irq(0);
if (timer_irq_works()) {
if (nmi_watchdog == NMI_IO_APIC) {
Expand All @@ -2174,26 +2195,23 @@ static inline void __init check_timer(void)
goto out;
}
clear_IO_APIC_pin(apic1, pin1);
printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
"IO-APIC\n");
}
if (!no_pin1)
printk(KERN_ERR "..MP-BIOS bug: "
"8254 timer not connected to IO-APIC\n");

printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
if (pin2 != -1) {
printk(KERN_INFO "...trying to set up timer (IRQ0) "
"through the 8259A ... ");
printk("\n..... (found pin %d) ...", pin2);
/*
* legacy devices should be connected to IO APIC #0
*/
replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
setup_timer_IRQ0_pin(apic2, pin2, vector);
unmask_IO_APIC_irq(0);
enable_8259A_irq(0);
if (timer_irq_works()) {
printk("works.\n");
timer_through_8259 = 1;
if (pin1 != -1)
replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
else
add_pin_to_irq(0, apic2, pin2);
if (nmi_watchdog == NMI_IO_APIC) {
disable_8259A_irq(0);
setup_nmi();
Expand All @@ -2206,8 +2224,8 @@ static inline void __init check_timer(void)
*/
disable_8259A_irq(0);
clear_IO_APIC_pin(apic2, pin2);
printk(" failed.\n");
}
printk(" failed.\n");

if (nmi_watchdog == NMI_IO_APIC) {
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
Expand Down
36 changes: 29 additions & 7 deletions trunk/arch/x86/kernel/io_apic_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,7 @@ static inline void __init check_timer(void)
struct irq_cfg *cfg = irq_cfg + 0;
int apic1, pin1, apic2, pin2;
unsigned long flags;
int no_pin1 = 0;

local_irq_save(flags);

Expand All @@ -1662,10 +1663,30 @@ static inline void __init check_timer(void)
apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
cfg->vector, apic1, pin1, apic2, pin2);

/*
* Some BIOS writers are clueless and report the ExtINTA
* I/O APIC input from the cascaded 8259A as the timer
* interrupt input. So just in case, if only one pin
* was found above, try it both directly and through the
* 8259A.
*/
if (pin1 == -1) {
pin1 = pin2;
apic1 = apic2;
no_pin1 = 1;
} else if (pin2 == -1) {
pin2 = pin1;
apic2 = apic1;
}

if (pin1 != -1) {
/*
* Ok, does IRQ0 through the IOAPIC work?
*/
if (no_pin1) {
add_pin_to_irq(0, apic1, pin1);
setup_timer_IRQ0_pin(apic1, pin1, vector);
}
unmask_IO_APIC_irq(0);
if (!no_timer_check && timer_irq_works()) {
nmi_watchdog_default();
Expand All @@ -1678,18 +1699,19 @@ static inline void __init check_timer(void)
goto out;
}
clear_IO_APIC_pin(apic1, pin1);
apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: 8254 timer not "
"connected to IO-APIC\n");
}
if (!no_pin1)
apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: "
"8254 timer not connected to IO-APIC\n");

apic_printk(APIC_VERBOSE,KERN_INFO "...trying to set up timer (IRQ0) "
"through the 8259A ... ");
if (pin2 != -1) {
apic_printk(APIC_VERBOSE,KERN_INFO
"...trying to set up timer (IRQ0) "
"through the 8259A ... ");
apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...",
apic2, pin2);
/*
* legacy devices should be connected to IO APIC #0
*/
/* replace_pin_at_irq(0, apic1, pin1, apic2, pin2); */
setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
unmask_IO_APIC_irq(0);
enable_8259A_irq(0);
Expand All @@ -1709,8 +1731,8 @@ static inline void __init check_timer(void)
*/
disable_8259A_irq(0);
clear_IO_APIC_pin(apic2, pin2);
apic_printk(APIC_VERBOSE," failed.\n");
}
apic_printk(APIC_VERBOSE," failed.\n");

if (nmi_watchdog == NMI_IO_APIC) {
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
Expand Down

0 comments on commit afa9b2a

Please sign in to comment.