Your description is vague in a couple of critical areas. You don’t say
whether the “PCI bridge” is actually a PCI compliant bridge with a Type
1 header. I suspect that it’s not. What you are probably describing is
a device that attaches legacy logic to the PCI bus, with a type 0 header
that you get to fill in with your specifics.
This design can’t work unless you have a latch somewhere in your PCI
logic that takes the edge-triggered signals from the legacy stuff and
then asserts the PCI level-triggered interrupt in a PCI-compliant
level-triggered mode. Along with the latch, you need a couple of other
things. First, you need to gate the PCI interrupt behind some
software-visible register, so that interrupts cannot possibly be
asserted unless your driver unmasks them. You also need a status bit
that allows software to see that the latch is set. Lastly, you need a
bit in a software-visible register that clears the latch.
If you try to pass the edge-triggered interrupts straight through to the
INTA# pin in the PCI slot, then you’ll get into a bunch of weird
edge-cases.
First, all PCI interrupts are, by definition within the PCI spec,
level-triggered and shareable. This means that your PCI card may be
plugged into a motherboard that forces it to share interrupts with some
other PCI device. In order to share successfully, you have implement
the same protocol as the other device.
If you don’t want to change the hardware, you’ve still got problems.
Even if your current product definition says that you control the
motherboard, the BIOS and all of your custom devices, (which could get
you around the problems listed above, since you might not be required to
share with another PCI device,) then you’ll still have trouble because
all of the interrupt logic in NT assumes that PCI devices are PCI
compliant, which yours wouldn’t be. And it would fail to route
interrupts appropriately, since the decisions that it makes are based on
the PCI spec. There are no APIs that say “Please connect my interrupt.
It’s coming from a PCI device. But it’s not really a PCI-compliant
device.” It wouldn’t be practical to add such an API, as there are just
too many permutations of PCI-non-compliance. Even if that feat were
attempted, it would be impossible to test, as you’d have to build
hardware with every possible spec violation. The matrix would be huge.
On to the next topic. You don’t say if you intend to expose generic
plug-in ISA devices or whether you have a controlled set of a few that
you’re trying to deal with. If you’re looking for something that
amounts to a generic ISA bridge, intending to run the stock drivers for
those ISA devices, you’re still going to fail, as most ISA devices can’t
share an interrupt, and certainly haven’t been tested with
level-triggered semantics. You’d be better off to re-do your design
using a stock cardbus bridge, representing your ISA devices as PCMCIA
devices. This is well-known territory.
If, on the other hand, you’re trying to glue a few well-controlled ISA
devices onto a modern PCI bus, then your task will be a little easier.
You’ll need to write a new device driver, probably a bus driver, that
handles interrupts for each of the child devices. Those children will
register their ISRs with the parent bus driver, not with the IO manager.
The parent bus driver will register the one and only PCI interrupt
through the IO manager and then call the child ISRs. (This is exactly
what the PCMCIA bus driver does when the child devices are using
PCI-style interrupts.
-----Original Message-----
Subject: How to register ISA interrupts that sit behind a PCI bridge?
From: Taed Wynnell
Date: Sun, 27 Jan 2002 21:45:50 -0800
X-Message-Number: 1
We have a somewhat odd setup where we have a few ISA cards that share a
single edge-triggered interrupt. These are not connected to the
motherboard
directly, but actually sit behind a device which then converts it to PCI
(such as the PLX / Tundra products), and a single level-triggered
interrupt.
Since the devices share an interrupt, they are obviously shared, but are
they edge- or level-triggered? From the motherboard’s point of view, it
is
level-triggered. But since the actual devices are edge-triggered, maybe
that is how they should be registered?
This makes a difference due to the different algorithms used by NT to
handle
shared interrupts. On shared level-triggered devices, the ISRs are
called
until one of them returns TRUE. On shared edge-triggered devices, the
ISRs
are called until ALL of them have returned FALSE.
Due to that, I think that registering them as edge-triggered would
ensure
the correct behavior and avoid loss of interrupts. However, how will NT
react when we registered a PCI interrupt as edge-triggered?
(The hardware is not functional yet, so we can’t just try this out…)
—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com