Can't generate DUART1 interrupt

OK, so far so good. Now I’m getting to the Nuetrino prompt (My
display_msg from build file.) However, it appears on the console 1
character at a time, very S-L-O-O-O-W-L-Y, about 1 character per
second. I’m betting that I still don’t have interrupts right, and that
the driver is written with a timeout which basically empties the
transmit buffer 1 character at a time after a timeout if it never gets
the interrupt.

Now, from the debug code in the interrupt callout (basically a
putchar(‘J’), I can see the kernel issuing the “unmask” command (the ‘J’
appears on my console just before the ‘Welcome…’ message.
Furthermore, I’ve stepped through the assembler code and verified the
hardware addresses, etc. The unmask is definitely clearing the ‘MASK’
bit in the MPC8245 EPIC controller, and I can see the proper vector
number when the code reads the vector_priority register. However, I
never see evidence of the _id routine or the _eoi routine being called,
suggesting that something is still amiss. Furthermore, pressing keys on
the keyboard does nothing.

I’m running a simple configuration (build file attached).

Obviously I’m missing something…any ideas?

-Chris Hallinan

[virtual=ppcbe,binary +raw +compress] .bootstrap = {
startup-pdna -vvvvv -D8250.0xfc004500.9600.66000000.16
PATH=/proc/boot procnto-600 -vvvvvv
}

[+script] .script = {
devc-ser8250 -e -c66000000 -b9600 0xfc004500,137 &
reopen
display_msg Welcome to Neutrino on UEI PowerDNA!

reopen /dev/ser1
[+session] esh
}

[type=link] /dev/console=/dev/ser1
[type=link] /usr/lib/ldqnx.so.2=/proc/boot/libc.so

libc.so

[data=c]
devc-ser8250
esh

Chris Hallinan <clh@net1plus.com> wrote:

OK, so far so good. Now I’m getting to the Nuetrino prompt (My
display_msg from build file.) However, it appears on the console 1
character at a time, very S-L-O-O-O-W-L-Y, about 1 character per
second. I’m betting that I still don’t have interrupts right, and that
the driver is written with a timeout which basically empties the
transmit buffer 1 character at a time after a timeout if it never gets
the interrupt.

Now, from the debug code in the interrupt callout (basically a
putchar(‘J’), I can see the kernel issuing the “unmask” command (the ‘J’
appears on my console just before the ‘Welcome…’ message.
Furthermore, I’ve stepped through the assembler code and verified the
hardware addresses, etc. The unmask is definitely clearing the ‘MASK’
bit in the MPC8245 EPIC controller, and I can see the proper vector
number when the code reads the vector_priority register. However, I
never see evidence of the _id routine or the _eoi routine being called,
suggesting that something is still amiss. Furthermore, pressing keys on
the keyboard does nothing.

Just a guess…

Looking at the 8245 docs, I see bit 3 in the DUART Configuration Register
determines whether DUART interrupts are routed to the core via the
EPIC, or to the PCI bus… is it possible that this bit is set,
preventing the EPIC from getting the interrupt?


I’m running a simple configuration (build file attached).

Obviously I’m missing something…any ideas?

-Chris Hallinan

[virtual=ppcbe,binary +raw +compress] .bootstrap = {
startup-pdna -vvvvv -D8250.0xfc004500.9600.66000000.16
PATH=/proc/boot procnto-600 -vvvvvv
}

[+script] .script = {
devc-ser8250 -e -c66000000 -b9600 0xfc004500,137 &
reopen
display_msg Welcome to Neutrino on UEI PowerDNA!

reopen /dev/ser1
[+session] esh
}

[type=link] /dev/console=/dev/ser1
[type=link] /usr/lib/ldqnx.so.2=/proc/boot/libc.so

libc.so

[data=c]
devc-ser8250
esh

David Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

I have double checked both my code and put debug code in to read it…it
is not set. The default value is zero and I never set it. Therefore,
it is correctly configured to pass the INT to the EPIC.

Curiously, when the *_unmask function in callout_interrupt_sandpoint.c
executes, it outputs a debug byte composed of a ‘J’ added to the
interrupt vector number. When the code runs by itself (i.e. no
breakpoints, no debugging, etc.) it outputs just the ‘J’, indicating the
the IRQ passed into the *_unmask function has a Zero IRQ vector. Here’s
what I get on the screen:

JWelcome to Neutrino on the UEI PowerDNA

However, as you can see from the build file in my previous post, and in
the intrinfo info in the sys_page, the 137 is present in both. I’m
assuming the kernel can only do what it is told to by the information in
the intrinfo section of the sys_page?? Hmmmm…

Any more suggestions?

dgreen@qnx.com wrote:

Chris Hallinan <> clh@net1plus.com> > wrote:

OK, so far so good. Now I’m getting to the Nuetrino prompt (My
display_msg from build file.) However, it appears on the console 1
character at a time, very S-L-O-O-O-W-L-Y, about 1 character per
second. I’m betting that I still don’t have interrupts right, and that
the driver is written with a timeout which basically empties the
transmit buffer 1 character at a time after a timeout if it never gets
the interrupt.


Now, from the debug code in the interrupt callout (basically a
putchar(‘J’), I can see the kernel issuing the “unmask” command (the ‘J’
appears on my console just before the ‘Welcome…’ message.
Furthermore, I’ve stepped through the assembler code and verified the
hardware addresses, etc. The unmask is definitely clearing the ‘MASK’
bit in the MPC8245 EPIC controller, and I can see the proper vector
number when the code reads the vector_priority register. However, I
never see evidence of the _id routine or the _eoi routine being called,
suggesting that something is still amiss. Furthermore, pressing keys on
the keyboard does nothing.


Just a guess…

Looking at the 8245 docs, I see bit 3 in the DUART Configuration Register
determines whether DUART interrupts are routed to the core via the
EPIC, or to the PCI bus… is it possible that this bit is set,
preventing the EPIC from getting the interrupt?



I’m running a simple configuration (build file attached).


Obviously I’m missing something…any ideas?


-Chris Hallinan


[virtual=ppcbe,binary +raw +compress] .bootstrap = {
startup-pdna -vvvvv -D8250.0xfc004500.9600.66000000.16
PATH=/proc/boot procnto-600 -vvvvvv
}


[+script] .script = {
devc-ser8250 -e -c66000000 -b9600 0xfc004500,137 &
reopen
display_msg Welcome to Neutrino on UEI PowerDNA!


reopen /dev/ser1
[+session] esh
}


[type=link] /dev/console=/dev/ser1
[type=link] /usr/lib/ldqnx.so.2=/proc/boot/libc.so


libc.so


[data=c]
devc-ser8250
esh
\

Chris Hallinan <clh@net1plus.com> wrote:

I have double checked both my code and put debug code in to read it…it
is not set. The default value is zero and I never set it. Therefore,
it is correctly configured to pass the INT to the EPIC.

Curiously, when the *_unmask function in callout_interrupt_sandpoint.c
executes, it outputs a debug byte composed of a ‘J’ added to the
interrupt vector number. When the code runs by itself (i.e. no
breakpoints, no debugging, etc.) it outputs just the ‘J’, indicating the
the IRQ passed into the *_unmask function has a Zero IRQ vector. Here’s
what I get on the screen:

Interrupt callouts are always relative to 0, regardless of
the interrupt number in the overall interrupt map.

Imagine a system with a top level interrupt controller which had 32 interrupts,
a secondary interrupt controller which cascaded into the first one,
and which had 8 interrupt levels, and a third interrupt controller
which cascaded into the second one, and had 5 interrupts. Since each
controller is different, you’d have a different set of callouts (ID, EOI,
mask, unmask) for each one. In the init_intrinfo routine, you’d describe
the overall layout of the interrupt scheme, defining the top level
vectors for each controller, and describing the cascade vectors for
each one as well.

Now, you can decide to number your interrupts however you want for
the overall interrupt system - you could say the top level interrupts
are 64 - 95, the secondary ones are 100 - 108, and the tertiary ones
are 0x1000 to 0x1004. When attaching a device driver to a particular
interrupt, the user needs to know the proper interrupt from this scheme.
However, within the callout, the numbers used are always relative to
0. So, the first level callouts deal with vectors 0 to 31, the second
level callouts deal with vectors 0 to 7, and the third level callouts
deal with vectors 0 to 4.

So, when the unmask callout gets called, in your case it will pass 0
as the vector to unmask, since you only have one level of interrupts,
with only one vector on that level. The code in your unmask callout
should unmask DUART 0 in the EPIC, based on that value of 0. Likewise
for the mask callout. Your ID callout should return 0 as well, so the
kernel will know to notify device drivers attached to irq 137 (this
association is defined in init_intrinfo).

JWelcome to Neutrino on the UEI PowerDNA

However, as you can see from the build file in my previous post, and in
the intrinfo info in the sys_page, the 137 is present in both. I’m
assuming the kernel can only do what it is told to by the information in
the intrinfo section of the sys_page?? Hmmmm…

Any more suggestions?

dgreen@qnx.com > wrote:
Chris Hallinan <> clh@net1plus.com> > wrote:

OK, so far so good. Now I’m getting to the Nuetrino prompt (My
display_msg from build file.) However, it appears on the console 1
character at a time, very S-L-O-O-O-W-L-Y, about 1 character per
second. I’m betting that I still don’t have interrupts right, and that
the driver is written with a timeout which basically empties the
transmit buffer 1 character at a time after a timeout if it never gets
the interrupt.


Now, from the debug code in the interrupt callout (basically a
putchar(‘J’), I can see the kernel issuing the “unmask” command (the ‘J’
appears on my console just before the ‘Welcome…’ message.
Furthermore, I’ve stepped through the assembler code and verified the
hardware addresses, etc. The unmask is definitely clearing the ‘MASK’
bit in the MPC8245 EPIC controller, and I can see the proper vector
number when the code reads the vector_priority register. However, I
never see evidence of the _id routine or the _eoi routine being called,
suggesting that something is still amiss. Furthermore, pressing keys on
the keyboard does nothing.


Just a guess…

Looking at the 8245 docs, I see bit 3 in the DUART Configuration Register
determines whether DUART interrupts are routed to the core via the
EPIC, or to the PCI bus… is it possible that this bit is set,
preventing the EPIC from getting the interrupt?



I’m running a simple configuration (build file attached).


Obviously I’m missing something…any ideas?


-Chris Hallinan


[virtual=ppcbe,binary +raw +compress] .bootstrap = {
startup-pdna -vvvvv -D8250.0xfc004500.9600.66000000.16
PATH=/proc/boot procnto-600 -vvvvvv
}


[+script] .script = {
devc-ser8250 -e -c66000000 -b9600 0xfc004500,137 &
reopen
display_msg Welcome to Neutrino on UEI PowerDNA!


reopen /dev/ser1
[+session] esh
}


[type=link] /dev/console=/dev/ser1
[type=link] /usr/lib/ldqnx.so.2=/proc/boot/libc.so


libc.so


[data=c]
devc-ser8250
esh

\

David Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

OK! It’s working, (even if I don’t fully understand how to describe my
interrupt architecture via the intrinfo syspage structure!) but I think
I have enough to figure it out. To test your logic, I simply hard-coded
the unmask and id callouts to use zero, and voila: I now have QNX
working on my custom MPC8245 board. Stripped down, but functional!
Thank you for all your help.

I’m sure I’ll be back w/ more Q’s!

-Chris Hallinan

ps: It’s always fun using a serial port to debug the interrupt routines
on that same serial port. Generates some pretty cool recursions…
(Example: enable the debug character output on the *_id function!!)

dgreen@qnx.com wrote:

Chris Hallinan <> clh@net1plus.com> > wrote:

I have double checked both my code and put debug code in to read it…it
is not set. The default value is zero and I never set it. Therefore,
it is correctly configured to pass the INT to the EPIC.


Curiously, when the *_unmask function in callout_interrupt_sandpoint.c
executes, it outputs a debug byte composed of a ‘J’ added to the
interrupt vector number. When the code runs by itself (i.e. no
breakpoints, no debugging, etc.) it outputs just the ‘J’, indicating the
the IRQ passed into the *_unmask function has a Zero IRQ vector. Here’s
what I get on the screen:


Interrupt callouts are always relative to 0, regardless of
the interrupt number in the overall interrupt map.

Imagine a system with a top level interrupt controller which had 32 interrupts,
a secondary interrupt controller which cascaded into the first one,
and which had 8 interrupt levels, and a third interrupt controller
which cascaded into the second one, and had 5 interrupts. Since each
controller is different, you’d have a different set of callouts (ID, EOI,
mask, unmask) for each one. In the init_intrinfo routine, you’d describe
the overall layout of the interrupt scheme, defining the top level
vectors for each controller, and describing the cascade vectors for
each one as well.

Now, you can decide to number your interrupts however you want for
the overall interrupt system - you could say the top level interrupts
are 64 - 95, the secondary ones are 100 - 108, and the tertiary ones
are 0x1000 to 0x1004. When attaching a device driver to a particular
interrupt, the user needs to know the proper interrupt from this scheme.
However, within the callout, the numbers used are always relative to
0. So, the first level callouts deal with vectors 0 to 31, the second
level callouts deal with vectors 0 to 7, and the third level callouts
deal with vectors 0 to 4.

So, when the unmask callout gets called, in your case it will pass 0
as the vector to unmask, since you only have one level of interrupts,
with only one vector on that level. The code in your unmask callout
should unmask DUART 0 in the EPIC, based on that value of 0. Likewise
for the mask callout. Your ID callout should return 0 as well, so the
kernel will know to notify device drivers attached to irq 137 (this
association is defined in init_intrinfo).


JWelcome to Neutrino on the UEI PowerDNA


However, as you can see from the build file in my previous post, and in
the intrinfo info in the sys_page, the 137 is present in both. I’m
assuming the kernel can only do what it is told to by the information in
the intrinfo section of the sys_page?? Hmmmm…


Any more suggestions?


dgreen@qnx.com > wrote:

Chris Hallinan <> clh@net1plus.com> > wrote:


OK, so far so good. Now I’m getting to the Nuetrino prompt (My
display_msg from build file.) However, it appears on the console 1
character at a time, very S-L-O-O-O-W-L-Y, about 1 character per
second. I’m betting that I still don’t have interrupts right, and that
the driver is written with a timeout which basically empties the
transmit buffer 1 character at a time after a timeout if it never gets
the interrupt.


Now, from the debug code in the interrupt callout (basically a
putchar(‘J’), I can see the kernel issuing the “unmask” command (the ‘J’
appears on my console just before the ‘Welcome…’ message.
Furthermore, I’ve stepped through the assembler code and verified the
hardware addresses, etc. The unmask is definitely clearing the ‘MASK’
bit in the MPC8245 EPIC controller, and I can see the proper vector
number when the code reads the vector_priority register. However, I
never see evidence of the _id routine or the _eoi routine being called,
suggesting that something is still amiss. Furthermore, pressing keys on
the keyboard does nothing.


Just a guess…

Looking at the 8245 docs, I see bit 3 in the DUART Configuration Register
determines whether DUART interrupts are routed to the core via the
EPIC, or to the PCI bus… is it possible that this bit is set,
preventing the EPIC from getting the interrupt?




I’m running a simple configuration (build file attached).


Obviously I’m missing something…any ideas?


-Chris Hallinan


[virtual=ppcbe,binary +raw +compress] .bootstrap = {
startup-pdna -vvvvv -D8250.0xfc004500.9600.66000000.16
PATH=/proc/boot procnto-600 -vvvvvv
}


[+script] .script = {
devc-ser8250 -e -c66000000 -b9600 0xfc004500,137 &
reopen
display_msg Welcome to Neutrino on UEI PowerDNA!


reopen /dev/ser1
[+session] esh
}


[type=link] /dev/console=/dev/ser1
[type=link] /usr/lib/ldqnx.so.2=/proc/boot/libc.so


libc.so


[data=c]
devc-ser8250
esh


\