From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1765078AbXGKPTT (ORCPT ); Wed, 11 Jul 2007 11:19:19 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1761655AbXGKPTM (ORCPT ); Wed, 11 Jul 2007 11:19:12 -0400 Received: from [222.92.8.141] ([222.92.8.141]:36491 "HELO lemote.com" rhost-flags-FAIL-FAIL-OK-OK) by vger.kernel.org with SMTP id S1760264AbXGKPTL (ORCPT ); Wed, 11 Jul 2007 11:19:11 -0400 Message-ID: <4694F4EB.8040000@lemote.com> Date: Wed, 11 Jul 2007 23:19:07 +0800 From: Songmao Tian User-Agent: Icedove 1.5.0.8 (X11/20061116) MIME-Version: 1.0 To: "Maciej W. Rozycki" CC: LinuxBIOS Mailing List , marc.jones@amd.com, linux-kernel@vger.kernel.org, linux-mips@linux-mips.org Subject: Re: about cs5536 interrupt ack References: <4694A495.1050006@lemote.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org 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;