[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Newbie question about PCI interrupts





> George,
> 
> Please see the interspersed responses.
> 
> -David O'Shea
> 
> -----Original Message-----
> From:	George Pauley [SMTP:gpauley@3a.com]
> Sent:	Wednesday, January 06, 1999 3:40 PM
> To:	Mailing List Recipients
> Subject:	Newbie question about PCI interrupts
> 
> I'm new to PCI, and am sure this is a stupid question, but I can't glean
> this information from the PCI spec or any of my other sources.  Thanks
> in advance for your help.
> 
> We are building a custom computer device which will act as a PCI host
> controller.  (We are using a PCI bridge chip from V3 as our interface to
> the PCI bus.)  The system is not x86 based, so my question is PCI 
> specific, not PC/ISA specific.  We are using Windows CE  (if that is
> pertinent).
> 
> The general question is:
> 
> How do I process interrupts from the PCI bus?  What is the process for
> acknowledging and clearing interrupts?
> 
> David O'Shea writes:
> Generally, there is no general solution, because it always depends on the
> interrupt controller that you are using.   In your case, the interrupt
> "controller"
> is an OR gate and the interrupt set/clear bit within your processor.
> Unless
> there really is a fancier controller in your CE device.  But it does not
> sound
> like it.
> 
> More specifically, here are some of the issues which are confusing me...
> 
> INTA thru INTD are ORed by the bridge chip and will signal a single
> interrupt on the CPU.   Presumably my ISR will have query each PCI
> device on the bus to determine which device  caused the interrupt.
> Since this information is (typically) located in the device specific
> portions of the configuration ROM, the ISR will have use each device's
> driver to determine  this information.  Furthermore, each device driver
> will be required to cause the device to relinquish its INTx line.
> 
> Since the INTx lines are level triggered, if I get two interrupts
> simultaneously, and clear one interrupt, presumably the second 
> device will still be holding the INTx line low.  How does the bridge
> chip know that this is a 2nd interrupt?
> 
> Now we might say that my ISR should query each device to
> see if it has an active  interrupt.  But querying is not a discrete
> instruction.  I could query a device, then while I'm querying the
> next device, I could get an interrupt on the 1st device.  How do
> I handle these situations.
> 
> Your model is not really correct.   The basic solution is as follows:
> 
> Interrupt occurs - base handler invoked.
> Base Handler clears (blocks) interrupt bit in CPU (all CPU's have this
> ability).
> Handler envokes each driver's interrupt service routine in turn
>    until one of the routines claims credit for the interrupt.  This 
>    is determined by reading that devices private working 
>    registers in its mapped I/O or Memory space.   The ISR caues
>    the device to be satisfied for this interrupt cause and the device
>    deasserts its level INTx line.
> This interrupt is "handled at this point".
> Unwind, then enable (set) interrupts in the processor - At this point you
>     might get a second interrupt if there were two interrupts (Level
> sense)
>     outstanding.  ie. you handled the first, it went away, but level still
>     active because of second.  When you enable interrupts at CPU,
>     you will immediately get another interrupt.  (Assuming CPU is
>     also level driven.   If CPU is edge driven then you have a problem
>     because you have no interrupt controller and you are feeding level
>     sensitive shared interrupts into an edge trigger - won't work).
> Return from base interrupt handler, interrupts enabled at CPU.
> 
> An alternative, similar model is:
> Interrupt occurs - handler invoked.
> Handler clears (blocks) interrupt bit in CPU (all CPU's have this
> ability).
> Handler envokes each driver's interrupt service routine in turn
>    until one of the routines claims credit for the interrupt. This 
>    is determined by by reading that devices private working 
>    registers in its mapped I/O or Memory space.
> This interrupt is "handled at this point".  The ISR caues
>    the device to be satisfied for this interrupt cause and the device
>    deasserts its level INTx line.
> >>> Continue scanning other driver ISR's to see if any other devices also
> >>> interrupted.  Let them handle their interrupts as well.  Again, these
> >>> drivers scan their own devices private register spaces to access 
> >>> whether their device caused the interrupt, and to clear the interrupt
> >>> condition.  The device will deassert its line when happy.
> Unwind, then enable (set) interrupts in the processor - At this point you
>     might get a second interrupt if a new interrupt occurs before you 
>     return out of the base handler.  ie. you handled the first and
> possibly
>     multiple interrupts, they all went away, but level still active now
>     because of a new interrupt.  When you enable interrupts at CPU,
>     you might immediately get another interrupt.  (Assuming CPU is
>     also level driven.   If CPU is edge driven then you have a problem
>     because you have no interrupt controller and you are feeding level
>     sensitive shared interrupts into an edge trigger - won't work).
> Return from base interrupt handler - interrupts enabled at CPU.
> 
> Finally, what is the Interrupt Acknowledge cycle all about?  Is this what
> resets the bus to allow future interrupts?  The cycle returns a vector,
> which appears to be the Interrupt Line value determine during
> configuration.
> Since the cycle is a read cycle with no address, which card responds
> with a vector?  The spec says the acknowledge cycle is implicitly
> addressed to the interrupt controller.  Well how does the interrupt
> controller know what vector to return?
> 
> You would not be using the Int Ack cycle in your situation where you
> don't have a PC/ISA 8259A interrupt controller.  The IntAck cycles were
> put in specifically for these types of interrupt controllers.   The CPU
> (x86)
> would normally put out IntAck cycles to read the interrupt vector from
> an 8259A PIC.   If you don't have an x86 CPU and are not using an
> 8259A PIC, then you won't be seeing any PCI IntAck cycles.   You need
> to look at the interrupt mechanism of your CPU, which is far beyond
> the scope of the PCI specification.
> 
> It should be obvious by now, that what I really need is someone to go
> through an interrupt cycle step by step for me.  If you can recommend a
> good book, or web-site, etc. which can give me this information that 
> would be great too.
> 
> There is no book because this is a system issue.  It's not even a PCI
> issue because the real issue is how does your interrupt controller work.
> In your case, you don't appear to actually have an "interrupt controller".
> So what you have is an implicit controller via the PCI shared interrupts,
> OR-tied interrupt lines (all PCI interrupts shared to single interrupt
> line)
> and the CPU's own enable/disable bit for interrupts.   It depends on your
> CPU, but I have not met a CPU yet that did not have instructions for
> enabling and disabling interrupts.  From what you describe, it does not
> sound like you have interrupt "vectors" because all of the interrupts are
> tied to a single input into the CPU.  You have a single vector, if your
> CPU even works this way.    You need to look at your CPU specification.
> 
> I appreciate the help.  I'm a bit disappointed in the spec which goes
> through read and write cycles in great detail, but forgets to discuss this
> issue.  Guess I'm really only supposed to use PCI in a x86 PC system
> which already has all this stuff handled in the hardware! <grin>
> 
> There is no way to document this in the PCI spec, since its not a PCI
> issue, but instead a system design issue.  The issue is how does your
> system interrupt controller work?   Everything of interest for the PCI
> devices
> is in fact in the PCI spec.  ie.  PCI interrupts are level driven, active
> low and
> that PCI interrupts are sharable and it is a *requirement* for PCI device 
> interrupt handlers to be able to handle shared interrupts.   Those two
> pieces of information are in the PCI specification, and those are the only
> relavent pieces of information.
> 
> -Daveo
> 
> George Pauley
> 
> 3A International
> Tempe, Arizona
> mailto:gpauley@3a.com
> 
>