PCI configuration space access during interrupt servicing

I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base address,
interrupt vector, command) when it requests an interrupt. This means I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

The online docs for the C library say that the PCI BIOS access functions
are not safe to use in interrupt service routines, and in fact, when I
try to access the PCI configuration registers (not with those functions
though) the OS comes down hard with a kernel fault.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space into my
process because its frowned upon in the PCI BIOS spec, but I guess I
will if I have to. The functions I am using to access config space at
the moment use the int386() function, which is not documented, but is in
the library. Is int386() safe to use in an interrupt handler?

I’m using QNX 4.25 and the Watcom 10.6 C/C++ compiler.

Thanks
Ted Hildum

Edward A. Hildum <ehildum@mail.arc.nasa.gov> wrote:

I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base address,
interrupt vector, command) when it requests an interrupt. This means I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

I don’t see how you can possibly work around this. This can’t be a design
feature, is it?

Previously, Edward A. Hildum wrote in qdn.public.qnx4:

I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base address,
interrupt vector, command) when it requests an interrupt. This means I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

The online docs for the C library say that the PCI BIOS access functions
are not safe to use in interrupt service routines, and in fact, when I
try to access the PCI configuration registers (not with those functions
though) the OS comes down hard with a kernel fault.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space into my
process because its frowned upon in the PCI BIOS spec, but I guess I
will if I have to. The functions I am using to access config space at
the moment use the int386() function, which is not documented, but is in
the library. Is int386() safe to use in an interrupt handler?

I’m using QNX 4.25 and the Watcom 10.6 C/C++ compiler.

As per the documentation, you cannot use any of the CA_PCI functions in
an interrupt handler as well as the int386 call. This sounds like a
really bad card!

Thanks
Ted Hildum
\

Hugh Brown (613) 591-0931 ext. 209 (voice)
QNX Software Systems Ltd. (613) 591-3579 (fax)
175 Terence Matthews Cres. email: hsbrown@qnx.com
Kanata, Ontario, Canada.
K2M 1W8

Edward A. Hildum <ehildum@mail.arc.nasa.gov> wrote:

I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base address,
interrupt vector, command) when it requests an interrupt. This means I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

This sounds like badly broken hardware.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space into my
process because its frowned upon in the PCI BIOS spec, but I guess I
will if I have to. The functions I am using to access config space at
the moment use the int386() function, which is not documented, but is in
the library. Is int386() safe to use in an interrupt handler?

int386() is not safe to use in an irq handler. In fact, most things you
would normally want to do with int386() can’t be done under QNX at all.
It is, usually, used to call into the BIOS, and most BIOS functions aren’t
callable from 32-bit protected mode. It happens that the PCI bios is
so callable, and that is, basically, what the _CA_PCI library routines
do, but this isn’t safe to do from an irq handler.

I know the PCI BIOS spec suggests not mapping the configuration space
directly – then again, I don’t think the spec suggests that an IO card
should clobber its configuration space on every interrupt either. The only
solution I see that might work is directly mapping the config space.

But, this is broken hardware – what else might it be doing wrong? As
others have said, can you get hardware that isn’t broken?

-David

QNX Training Services
dagibbs@qnx.com

Thanks for your reply, David.

The hardware is inconvenient, but there is a good reason for the way it
behaves. The PCI interface is in a big Xilinx FPGA, along with user back end
“hardware”. The board is designed to be reconfigured during runtime, which
incidentally wipes the PCI interface. When the board is reconfigured, it
informs the OS through an interrupt that it is ready. The interrupt handler is
the first piece of code that touches the board after reconfiguration, and hence
must be able to set the PCI configuration.

I will try to figure out how to directly map PCI configuration memory. If you
know the procedure, I’d appreciate an email.

Thanks,
Ted Hildum


David Gibbs wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote:
I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base address,
interrupt vector, command) when it requests an interrupt. This means I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

This sounds like badly broken hardware.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space into my
process because its frowned upon in the PCI BIOS spec, but I guess I
will if I have to. The functions I am using to access config space at
the moment use the int386() function, which is not documented, but is in
the library. Is int386() safe to use in an interrupt handler?

int386() is not safe to use in an irq handler. In fact, most things you
would normally want to do with int386() can’t be done under QNX at all.
It is, usually, used to call into the BIOS, and most BIOS functions aren’t
callable from 32-bit protected mode. It happens that the PCI bios is
so callable, and that is, basically, what the _CA_PCI library routines
do, but this isn’t safe to do from an irq handler.

I know the PCI BIOS spec suggests not mapping the configuration space
directly – then again, I don’t think the spec suggests that an IO card
should clobber its configuration space on every interrupt either. The only
solution I see that might work is directly mapping the config space.

But, this is broken hardware – what else might it be doing wrong? As
others have said, can you get hardware that isn’t broken?

-David

QNX Training Services
dagibbs@qnx.com

Edward A. Hildum <ehildum@mail.arc.nasa.gov> wrote in message
news:3A8861A7.C42116BE@mail.arc.nasa.gov

Thanks for your reply, David.

The hardware is inconvenient, but there is a good reason for the way it

^^^^^^ really??!!

behaves. The PCI interface is in a big Xilinx FPGA, along with user back
end
“hardware”. The board is designed to be reconfigured during runtime,
which
incidentally wipes the PCI interface. When the board is reconfigured, it

This is the bad design part - why does it incidentally wipe the PCI
interface??
What needs to change in this situation??
Bear in mind that the PCI stuff is the stuff the host computer needs to
have straight in order to communicate properly with the PCI card.
If you change this stuff on the fly - “under the feet” of the host machine
(once successfully configured), you are asking for all sorts of trouble!
Little things like changing the latencies and similar stuff I can see. But
changing the base address and interrupt vector normally calls for a reboot
of the host system…
(Or a tear-down and re-build of configuration stuff like PCCard uses - but
that has a seperate interrupt designed to tell the OS that hw has been
removed or added)
What happens if some part of the driver code is accessing the card - using
the former base address - and suddenly that changes - the app will get
totally unexpected hardware errors! (Or even worse - spurious data without
any notification of error)

Assuming that you have good answers for this…

Another possible stumbling block…
If you change the interrupt vector, how is underlying OS going to know which
ISR to schedule so
that the aforesaid ISR can re-configure the hardware interface (or at least
get the process going)?

I understand that the user can re-configure the board during runtime, but
what part of the interface with the host computer needs to be
re-configured that way??

Still, putting all of this aside…

informs the OS through an interrupt that it is ready. The interrupt
handler is
the first piece of code that touches the board after reconfiguration, and
hence
must be able to set the PCI configuration.

Why must the ISR set the PCI configuration??
Why can it not just follow the normal “QNX paradigm” of noting the interrupt
and scheduling non ISR code to do the heavy work? The interrupt would be
masked off - not allowing recursive ISR invocations, and the non-ISR “worker
code” would handle re-configuring the PCI registers, etc., and then reset
and re-enable the interrupt.

I will try to figure out how to directly map PCI configuration memory. If
you
know the procedure, I’d appreciate an email.

Thanks,
Ted Hildum


David Gibbs wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote:
I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base
address,
interrupt vector, command) when it requests an interrupt. This means
I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

This sounds like badly broken hardware.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space into
my
process because its frowned upon in the PCI BIOS spec, but I guess I
will if I have to. The functions I am using to access config space at
the moment use the int386() function, which is not documented, but is
in
the library. Is int386() safe to use in an interrupt handler?

int386() is not safe to use in an irq handler. In fact, most things you
would normally want to do with int386() can’t be done under QNX at all.
It is, usually, used to call into the BIOS, and most BIOS functions
aren’t
callable from 32-bit protected mode. It happens that the PCI bios is
so callable, and that is, basically, what the _CA_PCI library routines
do, but this isn’t safe to do from an irq handler.

I know the PCI BIOS spec suggests not mapping the configuration space
directly – then again, I don’t think the spec suggests that an IO card
should clobber its configuration space on every interrupt either. The
only
solution I see that might work is directly mapping the config space.

But, this is broken hardware – what else might it be doing wrong? As
others have said, can you get hardware that isn’t broken?

-David

QNX Training Services
dagibbs@qnx.com

Steve,
The board addresses a problem that isn’t addressed by any other hardware I’m
aware of, that is providing a reconfigurable interface to the CPU, in this case
via PCI. If I were doing it, I’d use a PLX PCI interface chip and put the
reconfigurable interface in an FPGA, but I haven’t got the resources to do
that. It isn’t the PCI interface that needs to be reconfigured anyway, its the
backend user configuration. With the FPGAs available these days, I can put a
pretty fancy active system in the part of the FPGA not used by the PCI
interface.

There is only one major chip on the board, the FPGA itself, and it has the
PCI interface in it. Reconfiguring the FPGA is an all or nothing operation, and
the design that gets written into it can’t be aware of the base address, etc.
that the BIOS assigns it at boot time. The reconfiguration process really
doesn’t remap the board, it just unmaps it. The ISR has to put back what the
BIOS assigned it at boot time. Sure, the driver could change the mapping, but
it can do that anyway by writing anything it wants to config space.

If the board or the driver were in the middle of some operation when the
board got reconfigured, it would be a problem, but one of the reasons for having
a driver is to centralize operations and control access to the board. The
reason that the ISR can’t let non-ISR code do this work is that it has to reset
the interrupt request before the interrupt is re-enabled. If it doesn’t, the
CPU goes into a tight loop getting re-interrupted as soon as it leaves the ISR.
The ISR has to write to registers on the board to do that, and the board has to
be mapped in order for it to touch the registers.

Ted Hildum


“Steve Munnings, Corman Technologies” wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote in message
news:> 3A8861A7.C42116BE@mail.arc.nasa.gov> …
Thanks for your reply, David.

The hardware is inconvenient, but there is a good reason for the way it

^^^^^^ really??!!
behaves. The PCI interface is in a big Xilinx FPGA, along with user back
end
“hardware”. The board is designed to be reconfigured during runtime,
which
incidentally wipes the PCI interface. When the board is reconfigured, it

This is the bad design part - why does it incidentally wipe the PCI
interface??
What needs to change in this situation??
Bear in mind that the PCI stuff is the stuff the host computer needs to
have straight in order to communicate properly with the PCI card.
If you change this stuff on the fly - “under the feet” of the host machine
(once successfully configured), you are asking for all sorts of trouble!
Little things like changing the latencies and similar stuff I can see. But
changing the base address and interrupt vector normally calls for a reboot
of the host system…
(Or a tear-down and re-build of configuration stuff like PCCard uses - but
that has a seperate interrupt designed to tell the OS that hw has been
removed or added)
What happens if some part of the driver code is accessing the card - using
the former base address - and suddenly that changes - the app will get
totally unexpected hardware errors! (Or even worse - spurious data without
any notification of error)

Assuming that you have good answers for this…

Another possible stumbling block…
If you change the interrupt vector, how is underlying OS going to know which
ISR to schedule so
that the aforesaid ISR can re-configure the hardware interface (or at least
get the process going)?

I understand that the user can re-configure the board during runtime, but
what part of the interface with the host computer needs to be
re-configured that way??

Still, putting all of this aside…

informs the OS through an interrupt that it is ready. The interrupt
handler is
the first piece of code that touches the board after reconfiguration, and
hence
must be able to set the PCI configuration.


Why must the ISR set the PCI configuration??
Why can it not just follow the normal “QNX paradigm” of noting the interrupt
and scheduling non ISR code to do the heavy work? The interrupt would be
masked off - not allowing recursive ISR invocations, and the non-ISR “worker
code” would handle re-configuring the PCI registers, etc., and then reset
and re-enable the interrupt.

I will try to figure out how to directly map PCI configuration memory. If
you
know the procedure, I’d appreciate an email.

Thanks,
Ted Hildum


David Gibbs wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote:
I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base
address,
interrupt vector, command) when it requests an interrupt. This means
I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

This sounds like badly broken hardware.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space into
my
process because its frowned upon in the PCI BIOS spec, but I guess I
will if I have to. The functions I am using to access config space at
the moment use the int386() function, which is not documented, but is
in
the library. Is int386() safe to use in an interrupt handler?

int386() is not safe to use in an irq handler. In fact, most things you
would normally want to do with int386() can’t be done under QNX at all.
It is, usually, used to call into the BIOS, and most BIOS functions
aren’t
callable from 32-bit protected mode. It happens that the PCI bios is
so callable, and that is, basically, what the _CA_PCI library routines
do, but this isn’t safe to do from an irq handler.

I know the PCI BIOS spec suggests not mapping the configuration space
directly – then again, I don’t think the spec suggests that an IO card
should clobber its configuration space on every interrupt either. The
only
solution I see that might work is directly mapping the config space.

But, this is broken hardware – what else might it be doing wrong? As
others have said, can you get hardware that isn’t broken?

-David

QNX Training Services
dagibbs@qnx.com

Previously, Edward A. Hildum wrote in qdn.public.qnx4:

Steve,
The board addresses a problem that isn’t addressed by any other hardware I’m
aware of, that is providing a reconfigurable interface to the CPU, in this case
via PCI. If I were doing it, I’d use a PLX PCI interface chip and put the
reconfigurable interface in an FPGA, but I haven’t got the resources to do
that. It isn’t the PCI interface that needs to be reconfigured anyway, its the
backend user configuration. With the FPGAs available these days, I can put a
pretty fancy active system in the part of the FPGA not used by the PCI
interface.

There is only one major chip on the board, the FPGA itself, and it has the
PCI interface in it. Reconfiguring the FPGA is an all or nothing operation, and
the design that gets written into it can’t be aware of the base address, etc.
that the BIOS assigns it at boot time. The reconfiguration process really
doesn’t remap the board, it just unmaps it. The ISR has to put back what the
BIOS assigned it at boot time. Sure, the driver could change the mapping, but
it can do that anyway by writing anything it wants to config space.

If the board or the driver were in the middle of some operation when the
board got reconfigured, it would be a problem, but one of the reasons for having
a driver is to centralize operations and control access to the board. The
reason that the ISR can’t let non-ISR code do this work is that it has to reset
the interrupt request before the interrupt is re-enabled. If it doesn’t, the
CPU goes into a tight loop getting re-interrupted as soon as it leaves the ISR.
The ISR has to write to registers on the board to do that, and the board has to
be mapped in order for it to touch the registers.

An alternative would be to mask off the interrupt in the ISR by writing to
the PIC and then doing the reconfiguration outside the ISR and then
unmasking the interrupt.

Ted Hildum


“Steve Munnings, Corman Technologies” wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote in message
news:> 3A8861A7.C42116BE@mail.arc.nasa.gov> …
Thanks for your reply, David.

The hardware is inconvenient, but there is a good reason for the way it

^^^^^^ really??!!
behaves. The PCI interface is in a big Xilinx FPGA, along with user back
end
“hardware”. The board is designed to be reconfigured during runtime,
which
incidentally wipes the PCI interface. When the board is reconfigured, it

This is the bad design part - why does it incidentally wipe the PCI
interface??
What needs to change in this situation??
Bear in mind that the PCI stuff is the stuff the host computer needs to
have straight in order to communicate properly with the PCI card.
If you change this stuff on the fly - “under the feet” of the host machine
(once successfully configured), you are asking for all sorts of trouble!
Little things like changing the latencies and similar stuff I can see. But
changing the base address and interrupt vector normally calls for a reboot
of the host system…
(Or a tear-down and re-build of configuration stuff like PCCard uses - but
that has a seperate interrupt designed to tell the OS that hw has been
removed or added)
What happens if some part of the driver code is accessing the card - using
the former base address - and suddenly that changes - the app will get
totally unexpected hardware errors! (Or even worse - spurious data without
any notification of error)

Assuming that you have good answers for this…

Another possible stumbling block…
If you change the interrupt vector, how is underlying OS going to know which
ISR to schedule so
that the aforesaid ISR can re-configure the hardware interface (or at least
get the process going)?

I understand that the user can re-configure the board during runtime, but
what part of the interface with the host computer needs to be
re-configured that way??

Still, putting all of this aside…

informs the OS through an interrupt that it is ready. The interrupt
handler is
the first piece of code that touches the board after reconfiguration, and
hence
must be able to set the PCI configuration.


Why must the ISR set the PCI configuration??
Why can it not just follow the normal “QNX paradigm” of noting the interrupt
and scheduling non ISR code to do the heavy work? The interrupt would be
masked off - not allowing recursive ISR invocations, and the non-ISR “worker
code” would handle re-configuring the PCI registers, etc., and then reset
and re-enable the interrupt.

I will try to figure out how to directly map PCI configuration memory. If
you
know the procedure, I’d appreciate an email.

Thanks,
Ted Hildum


David Gibbs wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote:
I’m attempting to write an interrupt service routine for a PCI card
which clobbers some of its configuration space registers (base
address,
interrupt vector, command) when it requests an interrupt. This means
I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

This sounds like badly broken hardware.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space into
my
process because its frowned upon in the PCI BIOS spec, but I guess I
will if I have to. The functions I am using to access config space at
the moment use the int386() function, which is not documented, but is
in
the library. Is int386() safe to use in an interrupt handler?

int386() is not safe to use in an irq handler. In fact, most things you
would normally want to do with int386() can’t be done under QNX at all.
It is, usually, used to call into the BIOS, and most BIOS functions
aren’t
callable from 32-bit protected mode. It happens that the PCI bios is
so callable, and that is, basically, what the _CA_PCI library routines
do, but this isn’t safe to do from an irq handler.

I know the PCI BIOS spec suggests not mapping the configuration space
directly – then again, I don’t think the spec suggests that an IO card
should clobber its configuration space on every interrupt either. The
only
solution I see that might work is directly mapping the config space.

But, this is broken hardware – what else might it be doing wrong? As
others have said, can you get hardware that isn’t broken?

-David

QNX Training Services
dagibbs@qnx.com

If the FPGA is reprogammable, make it also deactivate the
IRQ when it initialises.
Also possibly add a register to enable the IRQ so that
you can control when the IRQ can be asserted.
WIth this in place, you can do things the QNX way :slight_smile: and just
return an appropriate proxy to the main loop to tell it to reconfigure
the interface safely.

“Edward A. Hildum” wrote:

Steve,
The board addresses a problem that isn’t addressed by any other hardware I’m
aware of, that is providing a reconfigurable interface to the CPU, in this case
via PCI. If I were doing it, I’d use a PLX PCI interface chip and put the
reconfigurable interface in an FPGA, but I haven’t got the resources to do
that. It isn’t the PCI interface that needs to be reconfigured anyway, its the
backend user configuration. With the FPGAs available these days, I can put a
pretty fancy active system in the part of the FPGA not used by the PCI
interface.

There is only one major chip on the board, the FPGA itself, and it has the
PCI interface in it. Reconfiguring the FPGA is an all or nothing operation, and
the design that gets written into it can’t be aware of the base address, etc.
that the BIOS assigns it at boot time. The reconfiguration process really
doesn’t remap the board, it just unmaps it. The ISR has to put back what the
BIOS assigned it at boot time. Sure, the driver could change the mapping, but
it can do that anyway by writing anything it wants to config space.

If the board or the driver were in the middle of some operation when the
board got reconfigured, it would be a problem, but one of the reasons for having
a driver is to centralize operations and control access to the board. The
reason that the ISR can’t let non-ISR code do this work is that it has to reset
the interrupt request before the interrupt is re-enabled. If it doesn’t, the
CPU goes into a tight loop getting re-interrupted as soon as it leaves the ISR.
The ISR has to write to registers on the board to do that, and the board has to
be mapped in order for it to touch the registers.

Hi Edward,

Edward A. Hildum <ehildum@mail.arc.nasa.gov> wrote in message
news:3A897342.FF529BED@mail.arc.nasa.gov

Steve,
The board addresses a problem that isn’t addressed by any other
hardware I’m
aware of, that is providing a reconfigurable interface to the CPU, in this
case
via PCI. If I were doing it, I’d use a PLX PCI interface chip and put the
reconfigurable interface in an FPGA, but I haven’t got the resources to do
that. It isn’t the PCI interface that needs to be reconfigured anyway,
its the
backend user configuration. With the FPGAs available these days, I can
put a
pretty fancy active system in the part of the FPGA not used by the PCI
interface.

There is only one major chip on the board, the FPGA itself, and it has
the
PCI interface in it. Reconfiguring the FPGA is an all or nothing
operation, and
the design that gets written into it can’t be aware of the base address,
etc.
that the BIOS assigns it at boot time. The reconfiguration process really
doesn’t remap the board, it just unmaps it. The ISR has to put back what
the
BIOS assigned it at boot time. Sure, the driver could change the
mapping, but
it can do that anyway by writing anything it wants to config space.

If the board or the driver were in the middle of some operation when
the
board got reconfigured, it would be a problem, but one of the reasons for
having
a driver is to centralize operations and control access to the board. The
reason that the ISR can’t let non-ISR code do this work is that it has to
reset
the interrupt request before the interrupt is re-enabled. If it doesn’t,
the
CPU goes into a tight loop getting re-interrupted as soon as it leaves the
ISR.
The ISR has to write to registers on the board to do that, and the board
has to
be mapped in order for it to touch the registers.

Ted Hildum

O.K. (as I interpret what you are saying…feel free to correct me if I am
wrong):
For cost reasons, the hardware design is not as good as it should be, but
you are trying to compensate for that in software.

Well and good - if it can be done, and you are willing to accept all of the
subsequent trade-offs. {I believe that this is how WinModems came to be!)

This still leaves one big large conceptual problem…
If the PCI configuration also assigns the interrupt line (line A, B, C, or
D) how is the unmapped board going to trigger the interrupt to the PC
hardware that gets interpreted as a particular IRQ that an ISR is already
assigned to?
(On the other hand if this particular piece of configuration is fixed by the
hardware - i.e. always use line A - then there is no problem, is there?)
And since the ISR cannot read the registers on the card, how is it going to
tell that this particular IRQ is a request for it to re-map the board - as
opposed to some other interrupt event? That is, unless this is the only IRQ
ever handled from this board, or you have some other arrangement <though for
the life of me, I don’t know what it might be> to tell the ISR that this is
a “re-map the board” interrupt - it cannot read device registers anymore
with any guarantee of their contents…

If you get past those items, then (as Hugh mentions in his post) it is not
really a big deal to mask off the interrupt (in the PC hardware) - this was
what I was trying to suggest…
Then you will not get a tight ISR loop. And then the non-ISR code can
configure the card to its hearts content until it is ready to clear the
interrupt, and then re-enable the line through the PIC.


“Steve Munnings, Corman Technologies” wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote in message
news:> 3A8861A7.C42116BE@mail.arc.nasa.gov> …
Thanks for your reply, David.

The hardware is inconvenient, but there is a good reason for the way
it

^^^^^^ really??!!
behaves. The PCI interface is in a big Xilinx FPGA, along with user
back
end
“hardware”. The board is designed to be reconfigured during runtime,
which
incidentally wipes the PCI interface. When the board is reconfigured,
it

This is the bad design part - why does it incidentally wipe the PCI
interface??
What needs to change in this situation??
Bear in mind that the PCI stuff is the stuff the host computer needs
to
have straight in order to communicate properly with the PCI card.
If you change this stuff on the fly - “under the feet” of the host
machine
(once successfully configured), you are asking for all sorts of trouble!
Little things like changing the latencies and similar stuff I can see.
But
changing the base address and interrupt vector normally calls for a
reboot
of the host system…
(Or a tear-down and re-build of configuration stuff like PCCard uses -
but
that has a seperate interrupt designed to tell the OS that hw has been
removed or added)
What happens if some part of the driver code is accessing the card -
using
the former base address - and suddenly that changes - the app will get
totally unexpected hardware errors! (Or even worse - spurious data
without
any notification of error)

Assuming that you have good answers for this…

Another possible stumbling block…
If you change the interrupt vector, how is underlying OS going to know
which
ISR to schedule <since they are scheduled based on the interrupt number
so
that the aforesaid ISR can re-configure the hardware interface (or at
least
get the process going)?

I understand that the user can re-configure the board during runtime,
but
what part of the interface with the host computer needs to be
re-configured that way??

Still, putting all of this aside…

informs the OS through an interrupt that it is ready. The interrupt
handler is
the first piece of code that touches the board after reconfiguration,
and
hence
must be able to set the PCI configuration.


Why must the ISR set the PCI configuration??
Why can it not just follow the normal “QNX paradigm” of noting the
interrupt
and scheduling non ISR code to do the heavy work? The interrupt would
be
masked off - not allowing recursive ISR invocations, and the non-ISR
“worker
code” would handle re-configuring the PCI registers, etc., and then
reset
and re-enable the interrupt.

I will try to figure out how to directly map PCI configuration memory.
If
you
know the procedure, I’d appreciate an email.

Thanks,
Ted Hildum


David Gibbs wrote:

Edward A. Hildum <> ehildum@mail.arc.nasa.gov> > wrote:
I’m attempting to write an interrupt service routine for a PCI
card
which clobbers some of its configuration space registers (base
address,
interrupt vector, command) when it requests an interrupt. This
means
I
need to rewrite the configuration space registers in the interrupt
handler before I can reset the interrupt request.

This sounds like badly broken hardware.

Is there a way to access the PCI configuration space at interrupt
time? I haven’t tried directly mmaping PCI configuration space
into
my
process because its frowned upon in the PCI BIOS spec, but I guess
I
will if I have to. The functions I am using to access config
space at
the moment use the int386() function, which is not documented, but
is
in
the library. Is int386() safe to use in an interrupt handler?

int386() is not safe to use in an irq handler. In fact, most things
you
would normally want to do with int386() can’t be done under QNX at
all.
It is, usually, used to call into the BIOS, and most BIOS functions
aren’t
callable from 32-bit protected mode. It happens that the PCI bios
is
so callable, and that is, basically, what the _CA_PCI library
routines
do, but this isn’t safe to do from an irq handler.

I know the PCI BIOS spec suggests not mapping the configuration
space
directly – then again, I don’t think the spec suggests that an IO
card
should clobber its configuration space on every interrupt either.
The
only
solution I see that might work is directly mapping the config space.

But, this is broken hardware – what else might it be doing wrong?
As
others have said, can you get hardware that isn’t broken?

-David

QNX Training Services
dagibbs@qnx.com