OpenCores
no use no use 1/1 no use no use
Enter ISR when interrupt gets called
by eschwede on Apr 3, 2012
eschwede
Posts: 9
Joined: Mar 19, 2012
Last seen: Jul 17, 2012
Hello all,

I would need some help to enter the interrupt service routine when an interrupt gets called. I have a TLM Sensor model attached to the or1ksim as a generic peripheral. It generates the interrupt, by writing '1' to the interrupt line for 100 us. The PIC seems to capture the interrupt correctly after 110 us (SPR_PICSR = 0x00000004), but the processor doesn't enter the isr. Since the interrupt isn't cleared, it then starts pending. I use the or1k-support.h functions.

My Or1ksim SW looks as follows:

#ifndef BASE_ADDR_ACTUATOR
#define BASE_ADDR_ACTUATOR 0X96000000
#endif

#ifndef BASE_ADDR_SENSOR
#define BASE_ADDR_SENSOR 0X95000000
#endif

struct sensordata
{
volatile float alpha;
volatile float dalpha;
volatile float theta;
volatile float dtheta;
};

struct actuatordata
{
volatile float u1;
volatile float u2;
volatile float v;
};

void sensor_isr(void *r){
int q;
q = (int) r;

printf("\nInterrupt Service Routine %u: SENSOR \n", q);
or1k_mtspr(SPR_PICSR, 0x00000000);
};

int main()
{
// Register Interface
struct sensordata *sensor_ptr = (struct sensordata *) BASE_ADDR_SENSOR;
struct sensordata sensor_local = {0,0,0,0};
struct actuatordata *actuator_ptr = (struct actuatordata *) BASE_ADDR_ACTUATOR;
struct actuatordata actuator_local = {0,0,0};

or1k_interrupt_handler_add(2, sensor_isr);
or1k_interrupt_enable(2);

printf("\nSPR_UPR = 0x%08lx\n", or1k_mfspr(SPR_UPR));
printf("PICMR = 0x%08lx\n", or1k_mfspr(SPR_PICMR));
printf("SPR_SR = 0x%08lx\n", or1k_mfspr(SPR_SR));
printf("SPR_PICPR = 0x%08lx\n", or1k_mfspr(SPR_PICPR));

while(1){
printf("SPR_PICSR = 0x%08lx\n", or1k_mfspr(SPR_PICSR));
}
return 0;
}

The Output looks as follows:
0 s
SPR_UPR = 0x00000601
PICMR = 0x00000007
SPR_SR = 0x00008201
10 us: PhyModel: [STATE_VAR]: x=0 y=0 al=0 th=0 da=0 dt=0 v=0
SPR_PICPR = 0x00000000
SPR_PICSR = 0x00000000
SPR_PICSR = 0x00000000
SPR_PICSR = 0x00000000
110 us: PhyModel: [STATE_VAR]: x=-nan y=-nan al=-nan th=-nan da=-nan dt=-nan v=-nan
SPR_PICSR = 0x00000000
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
210 us: PhyModel: [STATE_VAR]: x=-nan y=-nan al=-nan th=-nan da=-nan dt=-nan v=nan
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
310 us: PhyModel: [STATE_VAR]: x=-nan y=-nan al=-nan th=-nan da=-nan dt=-nan v=nan
Warning: Int on line 2 pending: ignored
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
410 us: PhyModel: [STATE_VAR]: x=-nan y=-nan al=-nan th=-nan da=-nan dt=-nan v=nan
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
510 us: PhyModel: [STATE_VAR]: x=-nan y=-nan al=-nan th=-nan da=-nan dt=-nan v=nan
Warning: Int on line 2 pending: ignored
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
SPR_PICSR = 0x00000004
...

I would really appreciate some help.

Regards,
Erik
RE: Enter ISR when interrupt gets called
by firefalcon on Apr 3, 2012
firefalcon
Posts: 99
Joined: Jan 10, 2011
Last seen: Mar 26, 2024
Check what your value of SR means. Interrupt exceptions are not enabled.
RE: Enter ISR when interrupt gets called
by eschwede on Apr 3, 2012
eschwede
Posts: 9
Joined: Mar 19, 2012
Last seen: Jul 17, 2012
Thank you for your response.

In the SR Register the Supervisor Mode, Condition flag and Fixed One bits are set. If I additionally set the Interrupt Exception Enable bit, the simulation crashes when the interrupt occurs or should occur:

...
110 us: PhyModel: [STATE_VAR]: x=-nan y=-nan al=-nan th=-nan da=-nan dt=-nan v=-nan
SPR_PICSR = 0xexit(39416)
@reset : cycles 0, insn #0
@exit : cycles 21491, insn #14705
diff : cycles 21491, insn #14705

RE: Enter ISR when interrupt gets called
by firefalcon on Apr 3, 2012
firefalcon
Posts: 99
Joined: Jan 10, 2011
Last seen: Mar 26, 2024
So, now your exception is being taken. That is progress. The problem now is that the handler for the exception is calling the exit function. You need to install/register your own handler for the exception. I see that you tried to do that in your code, but I am guessing that you used the wrong number.
RE: Enter ISR when interrupt gets called
by eschwede on Apr 4, 2012
eschwede
Posts: 9
Joined: Mar 19, 2012
Last seen: Jul 17, 2012
What do you mean by the "wrong number"? The interrupt request? If I change the interrupt request number the exception isn't taken anymore, so it should be right.
RE: Enter ISR when interrupt gets called
by firefalcon on Apr 4, 2012
firefalcon
Posts: 99
Joined: Jan 10, 2011
Last seen: Mar 26, 2024
If it were me, I would use GDB at this point, with a breakpoint set at 0x800.
RE: Enter ISR when interrupt gets called
by eschwede on Apr 13, 2012
eschwede
Posts: 9
Joined: Mar 19, 2012
Last seen: Jul 17, 2012
So I disassembled the binary file and traced the PC with gdb. The PC doesn't jump to the ISR address, but ends up in the exit function within the exception handler. Apparently the ISR is not set up correctly and instead of jumping to the ISR, exception_exit is executed (see attachment).

When the interrupt occurs the PC goes something like this:
0x800
or1k_exception_handler
exception_exit
exit
__call_exitprocs
__fini
__do_global_dtors_aux
__fini
__call_exitprocs
exit
_exit

Has anybody worked with the or1k-support.h functions, especially the ones concerning the interrupts and can assure that they are working properly or does anyone have an example application using them?

best regards,
Erik
code.out (821 kb)
RE: Enter ISR when interrupt gets called
by eschwede on Apr 16, 2012
eschwede
Posts: 9
Joined: Mar 19, 2012
Last seen: Jul 17, 2012
I've found a workaround by using the exception handling, but I believe it is not the way it is supposed to be.

Work Around: Exception Handling

or1k_mtspr(SPR_SR, or1k_mfspr(SPR_SR) | SPR_SR_IEE);
or1k_exception_handler_add (0x8, &exception_handling_function);
or1k_interrupt_enable(0x2);

1.Interrupt gets called: PC = 0x800
2.0x800 calls or1k_exception_handler()
3.IF no exception handler is set:exception_exit()
4.ELSE Enter exception_handling_function() (This is the case)


I believe it should be something like this:

or1k_mtspr(SPR_SR, or1k_mfspr(SPR_SR) | SPR_SR_IEE);
or1k_exception_handler_add (0x8, &or1k_interrupt_handler); //I'm not sure how to include or1k_interrupt_handler, since it is not defined in or1k-support.h
or1k_interrupt_handler_add(0x2, &ISR);
or1k_interrupt_enable(0x2);

1.Interrupt gets called: PC = 0x800
2.0x800 calls or1k_exception_handler()
3.IF no exception handler is set: exception_exit() (This is the case)
4.ELSE : or1k_exception_handler() should call or1k_interrupt_handler() to enter ISR()

Is there maybe a bug in the or1k-support.h library? The link between the exception handling and the interrupt handling seems to be missing.
RE: Enter ISR when interrupt gets called
by NeoBelerophon on Jul 10, 2012
NeoBelerophon
Posts: 10
Joined: Nov 29, 2011
Last seen: Jul 16, 2012
Hi,

I have the same problem as you described in this thread.
Where you able to solve this problem
or is your workaround the only working solution by now?

Best regards,
Stefan
RE: Enter ISR when interrupt gets called
by ClockworkRed on Jul 10, 2012
ClockworkRed
Posts: 19
Joined: May 6, 2011
Last seen: Oct 26, 2016
Hi Stefan,

from our understanding there is some code not working in the assembly code of the functions that handle external interrupts in the newlib library for calling the ISR.
We did some modifications to the file or1k-support-asm.S to handle interrupts correctly.
We attached the file to our bug report:
http://bugzilla.opencores.org/bugzilla4/show_bug.cgi?id=86

The new file works well with calling an ISR for single interrupt handling. We now consider the case that we have two sources for external interrupts and there we have encountered another problem with our modified version when two interrupts come simultaneously.
As soon as we have solved this problem we will upload an updated version of the file.

In order to use the new version you need to compile the newlib library with the modified or1k-support-asm.S. Is is located under gnu-src/newlib-1.18.0/newlib/libc/machine/or32.

You also need to declare the function or1k_interrupt_handler() in or1k-support.h
because you manually must register this function as exception handler for external interrupts (vector 0x800):

// Add External interrupt Handler
or1k_exception_handler_add (0x8, &or1k_interrupt_handler);

With best regards,
Daniel
RE: Enter ISR when interrupt gets called
by NeoBelerophon on Jul 12, 2012
NeoBelerophon
Posts: 10
Joined: Nov 29, 2011
Last seen: Jul 16, 2012
Thx for this hint.

I changed newlib according to your bug report and recompiled it.
Now the exception is handled and my openrisc program keeps running.

But as it seems there appears no interrupt in the SPR_PICSR.

What i did is:

void isr(void* null)
{
printf("interrupt received\n");
or1k_mtspr(SPR_PICSR, 0x00000000);
}

int main()
{
...
or1k_mtspr(SPR_SR, or1k_mfspr(SPR_SR) | SPR_SR_IEE);
or1k_exception_handler_add (0x8, &or1k_interrupt_handler);
or1k_interrupt_handler_add(6, &isr);
or1k_interrupt_enable(6);

while(1)
{
printf("SPR_PICSR = 0x%08lx\n", or1k_mfspr(SPR_PICSR));
}
}

the output is:

SPR_PICSR = 0x00000000
SPR_PICSR = 0x00000000
SPR_PICSR = 0x00000000
SPR_PICSR = 0x00000000
SPR_PIC
Or1ksim > firing Event 6
SR = 0x00000000
SPR_PICSR = 0x00000000 <-- not crashing but also no interrupt handling?
SPR_PICSR = 0x00000000
SPR_PICSR = 0x00000000

I connected the interrupt to the or1ksim this way:

SC_METHOD( intrMethod );
sensitive << myIntrrupt;

void intrMethod()
{
std::cout << "Or1ksim > firing Event 6" << std::endl;
or1ksim_interrupt(6);
}

Is there something missing to trigger the event?



RE: Enter ISR when interrupt gets called
by ClockworkRed on Jul 13, 2012
ClockworkRed
Posts: 19
Joined: May 6, 2011
Last seen: Oct 26, 2016
Did you use our complete file?

We modified the code at two places, once is in the interrupt_handler function()'s assembly code and once in the interrupt_handler_add() assembly code routine.

The interrupt_handler_add() function actually was in our eyes not consistent because adding an ISR to interrupt line 6 registered the ISR for interrupt line 5.

Otherwise, I do not know why your ISR does not get called. The code looks at first sight ok to me.
RE: Enter ISR when interrupt gets called
by NeoBelerophon on Jul 13, 2012
NeoBelerophon
Posts: 10
Joined: Nov 29, 2011
Last seen: Jul 16, 2012
I replaced the whole file .S file and added the declaration to the header file.
So I assume all changes are applied to the newlib?
RE: Enter ISR when interrupt gets called
by ClockworkRed on Jul 16, 2012
ClockworkRed
Posts: 19
Joined: May 6, 2011
Last seen: Oct 26, 2016
Hi,

maybe you have then a problem with your SystemC wrapper
because it works in our simulation.

Please consider, the or1ksim must use local time when you connect it to SystemC
because it is written in pure C.
For interrupts, the call to the or1ksim_interrupt routine
only registers the interrupt but does not make the or1ksim
simulate the execution of the interrupt handler nor ISR.

For this, you need to run the or1ksim_run function in a while loop with a
local time quantum. You may either synchronize it with the
SystemC simulation time when it makes an external memory access (in the address range given in the generics section) or after a quantum passed.
Anyway, the ISR will only be executed in a call to or1ksim_run
which synchronized with SystemC after the call to or1ksim_interrupt.

An example of a working SystemC wrapper is given in the Embecosm example.

I hope that helps,
Daniel
RE: Enter ISR when interrupt gets called
by ClockworkRed on Jul 17, 2012
ClockworkRed
Posts: 19
Joined: May 6, 2011
Last seen: Oct 26, 2016
We updated the file or1k-support-asm.S in
http://bugzilla.opencores.org/bugzilla4/show_bug.cgi?id=86
to Support nested interrupts from different sources.
no use no use 1/1 no use no use
© copyright 1999-2026 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.