The second call of CALLOUT_PATCH causes the microkernel cras

Hello,

In my callout interrupt patcher I need to pass two
parameters as a mapped addresses of registers.
Here is the patcher code:

patch_intr:
stmdb sp!, {r4,lr}
add r4, r0, r2

mov r0,#6
ldr r1, Lpaddr
bl callout_io_map

CALLOUT_PATCH r4, r0, r1, r2, ip

mov r0,#4
ldr r1, Raddr
bl callout_io_map

CALLOUT_PATCH r4, r0, r1, r2, ip

ldmia sp!,{r4,pc}

Lpaddr: .word 0x14100000
Raddr: .word 0x41000000

If I comment line with second call of the
CALLOUT_PATCH then patcher “works”
fine, but doesn’t transfer parameter.

Without comment the patcher causes the microkernel crash.

What is wrong ?
I saw a code where the patcher is passing up to four values.

My target is armle running QNX Neutrino 6.3.

Regards,
Jacek

A couple of things come to mind… the size values (the value in r0) that
you’re passing to callout_io_map seem rather small; The way you’ve got it
now, the callouts can only access the first six bytes from the base address
of Lpaddr (from 0x14100000 to 0x14100006), and only the first four bytes
from the base of Raddr, from 0x41000000 - 0x41000003; is this what you
intended?

Also, If you’re patching two different address ranges, the callout which
uses that patcher must have the corresponding code present.

A good example of an ARM patcher / callout which patches two address ranges
is present in the arm startup library, callout_interrupt_ixp425.S:


patch_intr_gpio:

stmdb sp!,{r4,lr}
add r4, r0, r2 // address of callout routine

mov r0, #IXP425_IRQ_SIZE
ldr r1, Lintr_base
bl callout_io_map
CALLOUT_PATCH r4, r0, r1, r2, ip

mov r0, #IXP425_GPIO_SIZE
ldr r1, Lgpio_base
bl callout_io_map
CALLOUT_PATCH r4, r0, r1, r2, ip

ldmia sp!,{r4,pc}

Lintr_base: .word IXP425_IRQ_BASE
Lgpio_base: .word IXP425_GPIO_BASE

CALLOUT_START(interrupt_unmask_ixp425, 0, patch_intr_gpio)
/*

  • Get the address of the interrupt registers (patched)
    */
    mov ip, #0x000000ff
    orr ip, ip, #0x0000ff00
    orr ip, ip, #0x00ff0000
    orr ip, ip, #0xff000000

mov r3, #0x000000ff
orr r3, r3, #0x0000ff00
orr r3, r3, #0x00ff0000
orr r3, r3, #0xff000000






Jacek Rudnicki <jacek.rudnicki@quantum.com.pl> wrote:

Hello,

In my callout interrupt patcher I need to pass two
parameters as a mapped addresses of registers.
Here is the patcher code:

patch_intr:
stmdb sp!, {r4,lr}
add r4, r0, r2

mov r0,#6
ldr r1, Lpaddr
bl callout_io_map

CALLOUT_PATCH r4, r0, r1, r2, ip

mov r0,#4
ldr r1, Raddr
bl callout_io_map

CALLOUT_PATCH r4, r0, r1, r2, ip

ldmia sp!,{r4,pc}

Lpaddr: .word 0x14100000
Raddr: .word 0x41000000

If I comment line with second call of the
CALLOUT_PATCH then patcher “works”
fine, but doesn’t transfer parameter.

Without comment the patcher causes the microkernel crash.

What is wrong ?
I saw a code where the patcher is passing up to four values.

My target is armle running QNX Neutrino 6.3.

Regards,
Jacek

David Green (dgreen@qnx.com)
QNX Software Systems Ltd.
http://www.qnx.com

CALLOUT_START(interrupt_unmask_ixp425, 0, patch_intr_gpio)
/*

  • Get the address of the interrupt registers (patched)
    */
    mov ip, #0x000000ff
    orr ip, ip, #0x0000ff00
    orr ip, ip, #0x00ff0000
    orr ip, ip, #0xff000000

mov r3, #0x000000ff
orr r3, r3, #0x0000ff00
orr r3, r3, #0x00ff0000
orr r3, r3, #0xff000000

I forgot to read the second address of the register (patched)
in the rest of callout interrupt routines.

Upss, I did this in the callout_interrupt_id only.

Now everything is ok.

Thank’s,
Jacek