Passing parameters to interrupt callouts

Hi,
I have a MIPS based system that has several “PICs” connected to it.
The structure of all the PICs is similar (16 bit status and 16bit ctrl
registers)
the only difference is their address.

I would like to use the same set of callouts for handling all of them (i.e.
use the same interrupt_id,
interrupt_eoi, interrupt_mask and interrupt_unmask callouts)

for the interrupt_id I can use the INTR_GENFLAG_LOAD_INTRINFO and use the
vector_base field
in order to realize which PIC to work with.
For the interrupt_eoi, I can use the address calculated in interrupt_id (a
nice side-effect)

But I have no idea what to do in the interrupt_mask and interrupt_unmask
routines.
interrupt# won’t work since it is being normalized to the PIC int# prior of
calling the routines, and I didnt find
a way to ask the kernel to load the inerrupt info (as done in the EOI
routine)

any Idea will be appreciated.
Moti H

In article <cmv9rg$bgo$1@inn.qnx.com>, motih <a@b.com> wrote:

I have a MIPS based system that has several “PICs” connected to it.
The structure of all the PICs is similar (16 bit status and 16bit ctrl
registers)
the only difference is their address.

I would like to use the same set of callouts for handling all of them (i.e.
use the same interrupt_id,
interrupt_eoi, interrupt_mask and interrupt_unmask callouts)

But I have no idea what to do in the interrupt_mask and interrupt_unmask
routines.
interrupt# won’t work since it is being normalized to the PIC int# prior of
calling the routines, and I didnt find
a way to ask the kernel to load the inerrupt info (as done in the EOI
routine)

Look at the ‘“Patching” the callout code’ section of the
‘Building Embedded Systems’ manual. It explains how to modify
the callouts as they’re being installed into the system page. The
“startup/lib/mips/callout_debug_8250.S” file has an example of
it as well.


Brian Stecher (bstecher@qnx.com) QNX Software Systems, Ltd.
phone: +1 (613) 591-0931 (voice) 175 Terence Matthews Cr.
+1 (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

Patching a callout deals with a device that may appear in different
locations on different boards .
I need to address the issue of a device that has multiple instances on the
same board.
How will I use the patcher in this case ?
I thought of doing the following:

  1. add a patcher routine that will reference a “pic address” global
    variable.
  2. fill the global variable with the physical address of the PIC its callout
    routines I am about to add.
  3. use “add_interrupt” for adding the callout.
  4. The patcher will be invoked, filling the patched address with the address
    taken from the “pic address”
    (and after converting it to a virtual address).
  5. Do the above in a loop for all the onboard PICs.

PROBLEM: I am not sure when the patcher routine is invoked.
if it is invoked when calling “add_interrupt” then all
is fine. But if it is called
later on then the above will not work.

If this solution doesn’t work what other ways can I use the patcher routine
for adding the correct address ?

Moti




copied to its final position. The third parameter of the CALLOUT START macro
is
“Brian Stecher” <bstecher@qnx.com> wrote in message
news:cn2jq3$177$1@inn.qnx.com

In article <cmv9rg$bgo$> 1@inn.qnx.com> >, motih <> a@b.com> > wrote:
I have a MIPS based system that has several “PICs” connected to it.
The structure of all the PICs is similar (16 bit status and 16bit ctrl



registers)
the only difference is their address.

I would like to use the same set of callouts for handling all of them
(i.e.
use the same interrupt_id,
interrupt_eoi, interrupt_mask and interrupt_unmask callouts)

But I have no idea what to do in the interrupt_mask and interrupt_unmask
routines.
interrupt# won’t work since it is being normalized to the PIC int# prior
of
calling the routines, and I didnt find
a way to ask the kernel to load the inerrupt info (as done in the EOI
routine)

Look at the ‘“Patching” the callout code’ section of the
‘Building Embedded Systems’ manual. It explains how to modify
the callouts as they’re being installed into the system page. The
“startup/lib/mips/callout_debug_8250.S” file has an example of
it as well.


Brian Stecher (> bstecher@qnx.com> ) QNX Software Systems, Ltd.
phone: +1 (613) 591-0931 (voice) 175 Terence Matthews Cr.
+1 (613) 591-3579 (fax) Kanata, Ontario, Canada K2M
1W8

In article <cn837a$4fn$1@inn.qnx.com>, motih <a@b.com> wrote:

Patching a callout deals with a device that may appear in different
locations on different boards .
I need to address the issue of a device that has multiple instances on the
same board.

Same idea, just different details.

How will I use the patcher in this case ?
I thought of doing the following:

  1. add a patcher routine that will reference a “pic address” global
    variable.
  2. fill the global variable with the physical address of the PIC its callout
    routines I am about to add.
  3. use “add_interrupt” for adding the callout.
  4. The patcher will be invoked, filling the patched address with the address
    taken from the “pic address”
    (and after converting it to a virtual address).
  5. Do the above in a loop for all the onboard PICs.

PROBLEM: I am not sure when the patcher routine is invoked.
if it is invoked when calling “add_interrupt” then all
is fine. But if it is called later on then the above will not work.

The callouts are copied to the system page (and the patchers invoked)
during the init_system_private() call. Your scheme will work, with
some modifications. The interrupt callouts are done in order that the
entries are added to the intrinfo section of the system page, so the
patcher can just keep a counter of the number of times that it’s been
called and use that to index into an array of “pic address”'s - remember
to allow for the fact that the patcher will get called once for each
callout in an startup_intrinfo structure, so you’ll have to divide
by the number of callouts being patched for each structure before
indexing into the array (or have multiple entries in the array, one
for each callout rather one for each structure).

However, if you’re using 6.3.0, this is all much easier. The 6.3.0
startup_intrinfo structure has a “patch_data” field at the end of
it. You can put whatever data you want there (e.g. the pic address)
and it will be passed to the patcher routine as the fifth parameter
(yes, it’s undocumented - I forgot to let the docs people know about it).

If you happen to have the IBM PPC440 BSP, you can actually see thing
in practice. The 440 processor has two identical interrupt controller
blocks and the routines in callout_interrupt_ibm_uic.s are used to control
them both, with the base addresses being supplied in the patch_data
field.


Brian Stecher (bstecher@qnx.com) QNX Software Systems, Ltd.
phone: +1 (613) 591-0931 (voice) 175 Terence Matthews Cr.
+1 (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

Thanks,
I will implement it as suggested by you.

I now implement the following scheme which also works but its not a neat
solution:

CALLOUT_START(interrupt_mask_pic_1, 0, 0)
li t5, PIC_1_REG_BASE
b 1f
nop
CALLOUT_START(interrupt_mask_pic_2, 0, 0)
li t5, PIC_2_REG_BASE
b 1f
nop
CALLOUT_START(interrupt_mask_pic_3, 0, 0)
li t5, PIC_3_REG_BASE

2:
mask the interrupt

CALLOUT_END(interrupt_mask_pic_3)
CALLOUT_END(interrupt_mask_pic_2)
CALLOUT_END(interrupt_mask_pic_1)



Moti H.

“Brian Stecher” <bstecher@qnx.com> wrote in message
news:cnag1n$saf$1@inn.qnx.com

In article <cn837a$4fn$> 1@inn.qnx.com> >, motih <> a@b.com> > wrote:
Patching a callout deals with a device that may appear in different
locations on different boards .
I need to address the issue of a device that has multiple instances on
the
same board.

Same idea, just different details.

How will I use the patcher in this case ?
I thought of doing the following:

  1. add a patcher routine that will reference a “pic address” global
    variable.
  2. fill the global variable with the physical address of the PIC its
    callout
    routines I am about to add.
  3. use “add_interrupt” for adding the callout.
  4. The patcher will be invoked, filling the patched address with the
    address
    taken from the “pic address”
    (and after converting it to a virtual address).
  5. Do the above in a loop for all the onboard PICs.

PROBLEM: I am not sure when the patcher routine is invoked.
if it is invoked when calling “add_interrupt” then
all
is fine. But if it is called later on then the above will not work.

The callouts are copied to the system page (and the patchers invoked)
during the init_system_private() call. Your scheme will work, with
some modifications. The interrupt callouts are done in order that the
entries are added to the intrinfo section of the system page, so the
patcher can just keep a counter of the number of times that it’s been
called and use that to index into an array of “pic address”'s - remember
to allow for the fact that the patcher will get called once for each
callout in an startup_intrinfo structure, so you’ll have to divide
by the number of callouts being patched for each structure before
indexing into the array (or have multiple entries in the array, one
for each callout rather one for each structure).

However, if you’re using 6.3.0, this is all much easier. The 6.3.0
startup_intrinfo structure has a “patch_data” field at the end of
it. You can put whatever data you want there (e.g. the pic address)
and it will be passed to the patcher routine as the fifth parameter
(yes, it’s undocumented - I forgot to let the docs people know about it).

If you happen to have the IBM PPC440 BSP, you can actually see thing
in practice. The 440 processor has two identical interrupt controller
blocks and the routines in callout_interrupt_ibm_uic.s are used to control
them both, with the base addresses being supplied in the patch_data
field.


Brian Stecher (> bstecher@qnx.com> ) QNX Software Systems, Ltd.
phone: +1 (613) 591-0931 (voice) 175 Terence Matthews Cr.
+1 (613) 591-3579 (fax) Kanata, Ontario, Canada K2M
1W8