Messages in this thread | | | Date | Wed, 11 Jul 2007 23:38:40 +0800 | From | Songmao Tian <> | Subject | Re: about cs5536 interrupt ack |
| |
Songmao Tian wrote: > Before I post the mail, I think you will reply, and haha you did:), > Thanks that. > > Maciej W. Rozycki wrote: >> On Wed, 11 Jul 2007, Songmao Tian wrote: >> >> >>> "Control Logic >>> The INT output goes directly to the CPU interrupt input. >>> When an INT signal is activated, the CPU responds with an >>> Interrupt Acknowledge access that is translated to two >>> pulses on the INTA input of the PIC. At the first INTA pulse, >>> the highest priority IRR bit is loaded into the corresponding >>> ISR bit, and that IRR bit is reset. The second INTA pulse >>> instructs the PIC to present the 8-bit vector of the interrupt >>> handler onto the data bus." >>> >>> Is it the responsibility of north bridge to reponse to intr with a PCI >>> Interrupt Ack cycle? >>> >> >> With an i386 system such a pair of INTA cycles would be generated by >> the CPU itself and translated by the north bridge to a PCI Interrupt >> Acknowledge cycle (see the PCI spec for a more elaborate description). >> >> If the CPU does not generate INTA cycles, it is a common practice to >> let it ask the north bridge for a PCI Interrupt Acknowledge in some >> other way, typically by issuing a read cycle that returns the vector >> reported by the interrupt controller. >> >> >>> it's a problem that my northbridge didn't implement that! >>> Fortunately we use a >>> fpga as a northbridge. >>> >>> it seem it's no way to fix this by software, for OCW3 didn't >>> implemnt Poll >>> command:( >>> >> >> Huh? Have you managed to find an 8259A clone *that* broken? So >> what does it return if you write 0xc to the address 0x20 in the I/O >> port space and then read back from that location? You should >> complain to the > > It's the value of IRR, so guess IRR. AMD has well documented cs5536, I > appreciate that. > >> manufacturer -- they may be able to fix the problem in a later revision. >> >> BTW, I have just found a bug (OK, a misfeature, perhaps) in >> include/asm-mips/i8259.h. ;-) I'll cook a patch. >> >> >>> so I guess the the process is: >>> 1) 8259 receive a int, a bit irr got set. >>> 2) 8259 assert intr. >>> 3) northbrige generate a int ack cycle. >>> 4) cs5536 translate the ack into two INTA pulse, and the reponse >>> northbridge >>> with a interrupt vector. >>> 5) then my program can get the vector from northbridge? >>> >>> Is that right? >>> >> >> More or less -- 3-5 should probably be the outcome of a single read >> transaction from the north bridge. I.e. you issue a read to a >> "magic" location, 3-5 happen, and the data value returned is the >> vector presented by the interrupt controller on the PCI bus. >> > yeah, we can implement a register in north bridge. >> >>> Without int ack, generic linux-mips 8259 code can't work. >>> >> >> You can still dispatch interrupts manually by examining the IRR >> register, but having a way to ask the 8259A's prioritiser would be >> nice. Although given such a lethal erratum you report I would not >> count on the prioritiser to provide any useful flexibility... >> > yeah, that's a straight thought, tried but failed:(, patch followed. > >> Maciej >> >> >> > diff --git a/include/asm-mips/i8259.h b/include/asm-mips/i8259.h > index e88a016..38628af 100644 > --- a/include/asm-mips/i8259.h > +++ b/include/asm-mips/i8259.h > @@ -42,6 +42,37 @@ extern void enable_8259A_irq(unsigned int irq); > extern void disable_8259A_irq(unsigned int irq); > > extern void init_i8259_irqs(void); > +#define CONFIG_NO_INTERRUPT_ACK > +#ifdef CONFIG_NO_INTERRUPT_ACK > +static inline int _byte_ffs(u8 word) > +{ > + int num = 0; > + if ((word & 0xf) == 0) { > + num += 4; > + word >>= 4; > + } > + if ((word & 0x3) == 0) { > + num += 2; > + word >>= 2; > + } > + if ((word & 0x1) == 0) > + num += 1; > + return num; > +} > + > +static inline int read_irq(int port) > +{ > + outb(0x0A, port); > + return _byte_ffs(inb(port)); > +} > +#else > +static inline int read_irq(int port) > +{ > + /* Perform an interrupt acknowledge cycle on controller 1. */ > + outb(0x0C, port); /* prepare for poll */ > + return inb(port) & 7; > +} > +#endif > > /* > * Do the traditional i8259 interrupt polling thing. This is for the few > @@ -54,18 +85,16 @@ static inline int i8259_irq(void) > > spin_lock(&i8259A_lock); > > - /* Perform an interrupt acknowledge cycle on controller 1. */ > - outb(0x0C, PIC_MASTER_CMD); /* prepare for poll */ > - irq = inb(PIC_MASTER_CMD) & 7; > + irq = read_irq(PIC_MASTER_CMD); > + > if (irq == PIC_CASCADE_IR) { > /* > * Interrupt is cascaded so perform interrupt > * acknowledge on controller 2. > */ > - outb(0x0C, PIC_SLAVE_CMD); /* prepare for poll */ > - irq = (inb(PIC_SLAVE_CMD) & 7) + 8; > - } > - > + irq = read_irq(PIC_SLAVE_CMD) + 8; > + } > +#ifndef CONFIG_NO_INTERRUPT_ACK > if (unlikely(irq == 7)) { > /* > * This may be a spurious interrupt. > @@ -78,7 +107,7 @@ static inline int i8259_irq(void) > if(~inb(PIC_MASTER_ISR) & 0x80) > irq = -1; > } > - > +#endif > spin_unlock(&i8259A_lock); > > return likely(irq >= 0) ? irq + I8259A_IRQ_BASE : irq; > > > after applying this patch, system hung when probing ide, seems reading harddisk continuously, since the led is on all the time. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |