[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4694F980.6060500@lemote.com>
Date: Wed, 11 Jul 2007 23:38:40 +0800
From: Songmao Tian <tiansm@...ote.com>
To: Songmao Tian <tiansm@...ote.com>
CC: "Maciej W. Rozycki" <macro@...ux-mips.org>,
LinuxBIOS Mailing List <linuxbios@...uxbios.org>,
marc.jones@....com, linux-kernel@...r.kernel.org,
linux-mips@...ux-mips.org
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@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists