Is that for Nvidia CK804 stuff? Actually in LinuxBIOS I swap the irq 0 and 2 entries in mptable to solve the problem. and it could work well with current code.
YH On 7/29/05, Eric W. Biederman <[EMAIL PROTECTED]> wrote: > > Currently we attempt to restore virtual wire mode on reboot, which > only works if we can figure out where the i8259 is connected. This > is very useful when we kexec another kernel and likely helpful > when dealing with a BIOS that make assumptions about how the system is setup. > > Since the acpi MADT table does not provide the location where the i8259 > is connected we have to look at the hardware to figure it out. > > Most systems have the i8259 connected to the local apic of the cpu so > won't be affected but people running on Opteron and some serverworks chipsets > should be able to use kexec now. > > Signed-off-by: Eric W. Biederman <[EMAIL PROTECTED]> > --- > > arch/x86_64/kernel/io_apic.c | 52 > ++++++++++++++++++++++++++++++++++++++---- > 1 files changed, 47 insertions(+), 5 deletions(-) > > 96c59dd871b00735ef159ddf0d68f338958387fc > diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c > --- a/arch/x86_64/kernel/io_apic.c > +++ b/arch/x86_64/kernel/io_apic.c > @@ -45,6 +45,9 @@ int sis_apic_bug; /* not actually suppor > > static int no_timer_check; > > +/* Where if anywhere is the i8259 connect in external int mode */ > +static int ioapic_i8259_pin = -1; > + > static DEFINE_SPINLOCK(ioapic_lock); > > /* > @@ -330,7 +333,7 @@ static int find_irq_entry(int apic, int > /* > * Find the pin to which IRQ[irq] (ISA) is connected > */ > -static int find_isa_irq_pin(int irq, int type) > +static int __init find_isa_irq_pin(int irq, int type) > { > int i; > > @@ -1096,6 +1099,44 @@ void __apicdebuginit print_PIC(void) > > #endif /* 0 */ > > +static void __init find_i8259_pin(void) > +{ > + struct IO_APIC_route_entry entry; > + unsigned long flags; > + int pin, pins; > + > + ioapic_i8259_pin = -1; > + > + /* Find the number of pins on the primary ioapic */ > + spin_lock_irqsave(&ioapic_lock, flags); > + pins = ((io_apic_read(0, 0x01) >> 16) & 0xff) + 1; > + spin_unlock_irqrestore(&ioapic_lock, flags); > + > + /* See if any of the pins is in ExtINT mode */ > + for(pin = 0; pin < pins; pin++) { > + spin_lock_irqsave(&ioapic_lock, flags); > + *(((int *)&entry) + 0) = io_apic_read(0, 0x10 + 2 * pin); > + *(((int *)&entry) + 1) = io_apic_read(0, 0x11 + 2 * pin); > + spin_unlock_irqrestore(&ioapic_lock, flags); > + > + /* If the interrupt line is enabled and in ExtInt mode > + * I have found the pin where the i8259 is connected. > + */ > + if ((entry.mask == 0) && (entry.delivery_mode == > dest_ExtINT)) { > + ioapic_i8259_pin = pin; > + break; > + } > + } > + > + /* If we could not find an appropriate pin by looking at the ioapic > + * the i8259 probably isn't connected to the ioapic but give > + * the mptable a chance anyway. > + */ > + if (ioapic_i8259_pin == -1) { > + ioapic_i8259_pin = find_isa_irq_pin(0, mp_ExtINT); > + } > +} > + > static void __init enable_IO_APIC(void) > { > union IO_APIC_reg_01 reg_01; > @@ -1138,11 +1179,11 @@ void disable_IO_APIC(void) > clear_IO_APIC(); > > /* > - * If the i82559 is routed through an IOAPIC > + * If the i8259 is routed through an IOAPIC > * Put that IOAPIC in virtual wire mode > * so legacy interrups can be delivered. > */ > - pin = find_isa_irq_pin(0, mp_ExtINT); > + pin = ioapic_i8259_pin; > if (pin != -1) { > struct IO_APIC_route_entry entry; > unsigned long flags; > @@ -1154,7 +1195,7 @@ void disable_IO_APIC(void) > entry.polarity = 0; /* High */ > entry.delivery_status = 0; > entry.dest_mode = 0; /* Physical */ > - entry.delivery_mode = 7; /* ExtInt */ > + entry.delivery_mode = dest_ExtINT; /* ExtInt */ > entry.vector = 0; > entry.dest.physical.physical_dest = 0; > > @@ -1626,7 +1667,7 @@ static inline void check_timer(void) > enable_8259A_irq(0); > > pin1 = find_isa_irq_pin(0, mp_INT); > - pin2 = find_isa_irq_pin(0, mp_ExtINT); > + pin2 = ioapic_i8259_pin; > > apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X pin1=%d > pin2=%d\n", vector, pin1, pin2); > > @@ -1723,6 +1764,7 @@ __setup("no_timer_check", notimercheck); > > void __init setup_IO_APIC(void) > { > + find_i8259_pin(); > enable_IO_APIC(); > > if (acpi_ioapic) > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to [EMAIL PROTECTED] > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/