Enabling interrupts on a resource

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Enabling interrupts on a resource

Post by Jamie »

I'm working on a simple kernel that responds to events and interrupts generated on a channel, but I can't seem to get interrupts working with this properly -- I just to clarify what I'm doing to see if I have the right idea:

Interrupts and events are enabled (unconditionally) on a resource with 'eeu'. Then, events will occur when the thread's status register eeble bit is set and interrupts when ineble bit is set. So regarding interrupts from resources, it seems there are two cases:

1. If only the ineble bit is set, and an event occurs whilst something is executing on the thread an interrupt/TRAP should be generated; setting the pc to the preset resource vector (kernel entry point in my case), and saving the pc etc. (unlike an event).
2 .When an event occurs on the channel, e.g. a message arriving, but when both events and interrupts are disabled on the associated thread (i.e. when you are in kernel mode already), this is queued up until is can be serviced. Then by either enabling interrupts or events, an interrupt *or* event (respectively) would be generated.

I'm working with xsim traces at the moment and neither of these cases seem to be working properly. In both, by enabling events on the thread, they arrive as events (which is expected), but with only interrupts enabled nothing occurs! Any ideas?


User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Post by Jamie »

Here's a short example to better explain what I mean:

Code: Select all

#include <platform.h>

void foo(chanend c) {

    unsigned int x = 0;

    // Do some work
    for(int i=0; i<10; i++)
        continue;

    // Send something
    asm("out res[%0], %1" :: "r"(c), "r"(x));
}

void bar(chanend c) {
   
    // Enable events on the channel
    asm("eeu res[%0]" :: "r"(c)); 

    // Setup the resource event vector
    asm("ldap r11, handler" ::: "r11");
    asm("setv res[%0], r11" :: "r"(c) : "r11");

    // Enable interrupts
    asm("setsr 0x2");

    // Do some work
    while(1) {}
}

void handler() {
    
    // Wait
    asm("waiteu");
}
    
int main(void) {
    chan c;
    par {
        on stdcore[0] : foo(c);
        on stdcore[1] : bar(c);
    }   
    return 0;
}
So thread 0 initialises, foo does some work and outs a value:

Code: Select all

...
@4199	   A-.----000100ca (foo                 + 1e) : bu      -0xa 
@4203	   A-.----000100b8 (foo                 +  c) : ldw     r1(0xa), sp[0x2] L[0x1fee4] 
@4207	   A-.----000100ba (foo                 +  e) : ldc     r0(0xa), 0xa 
@4211	   A-.----000100bc (foo                 + 10) : lss     r0(0x0), r1(0xa), r0(0xa) 
@4215	   A-.----000100be (foo                 + 12) : bt      r0(0x0), 0x1 
@4219	   A-.----000100c0 (foo                 + 14) : bu      0x5 
@4223	   A-.----000100cc (foo                 + 20) : ldw     r1(0x102), sp[0x0] L[0x1fedc] 
@4227	   A-.----000100ce (foo                 + 22) : ldw     r0(0x0), sp[0x1] L[0x1fee0] 
@4235	   A-.----000100d0 (foo                 + 24) : out     res[r1(0x102)], r0(0x0) 
@4239	   A-.----000100d2 (foo                 + 26) : retsp   0x3 L[0x1fee8] 
Which should interrupt bar:

Code: Select all

@3826	   A-.----000100ac (bar                 +  0) : entsp   0x1 S[0x1fee8] 
@3830	   A-.----000100ae (bar                 +  2) : stw     r0(0x10102), sp[0x0] S[0x1fee4] 
@3838	   A-.----000100b0 (bar                 +  4) : ldw     r0(0x10102), sp[0x0] L[0x1fee4] 
@3842	   A-.----000100b2 (bar                 +  6) : eeu     res[r0(0x10102)] 
@3846	   A-.----000100b4 (bar                 +  8) : ldap    r11(0x100c8), 0x9 
@3850	   A-.----000100b6 (bar                 +  a) : ldw     r0(0x10102), sp[0x0] L[0x1fee4] 
@3854	   A-.----000100b8 (bar                 +  c) : setv    res[r0(0x10102)], r11(0x100c8) 
@3858	   A-.----000100ba (bar                 +  e) : setsr   0x2 
@3862	   Ai.----000100bc (bar                 + 10) : mkmsk   r0(0x1), 0x1 
@3866	   Ai.----000100be (bar                 + 12) : bt      r0(0x1), 0x1 
@3870	   Ai.----000100c2 (bar                 + 16) : bu      -0x4 
...
@4230	   Ai.----000100c2 (bar                 + 16) : bu      -0x4 
@4234	   Ai.----000100bc (bar                 + 10) : mkmsk   r0(0x1), 0x1 
@4238	   Ai.----000100be (bar                 + 12) : bt      r0(0x1), 0x1 
@4242	   Ai.----000100c2 (bar                 + 16) : bu      -0x4 
@4246	   Ai.----000100bc (bar                 + 10) : mkmsk   r0(0x1), 0x1 
@4250	   Ai.----000100be (bar                 + 12) : bt      r0(0x1), 0x1 
@4254	   Ai.----000100c2 (bar                 + 16) : bu      -0x4 
@4258	   Ai.----000100bc (bar                 + 10) : mkmsk   r0(0x1), 0x1 
@4262	   Ai.----000100be (bar                 + 12) : bt      r0(0x1), 0x1 
@4266	   Ai.----000100c2 (bar                 + 16) : bu      -0x4 
@4270	   Ai.----000100bc (bar                 + 10) : mkmsk   r0(0x1), 0x1 
@4274	   Ai.----000100be (bar                 + 12) : bt      r0(0x1), 0x1 
@4278	   Ai.----000100c2 (bar                 + 16) : bu      -0x4 
...
But which works only with events enabled (setsr 0x1):

Code: Select all

@4242	   Ab.----000100c2 (bar                 + 16) : bu      -0x4 
@4246	   Ab.----000100bc (bar                 + 10) : mkmsk   r0(0x1), 0x1 
@4250	   Ab.----000100be (bar                 + 12) : bt      r0(0x1), 0x1 
@4254	 Event caused by res 0x00010102, V=0x000100c8, EV=0x00010102 
@4262	 P Ai.----000100c8 (handler             +  0) : waiteu
Last edited by Jamie on Mon Jul 05, 2010 4:28 pm, edited 1 time in total.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

In their default state resources generate events and will not generate interrupts. You can switch the mode of a resource so that it generates interrupts instead of events using:

Code: Select all

setc res[r0], XS1_SETC_IE_MODE_INTERRUPT
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Post by Jamie »

Well at least it's a nice simple solution! Thanks Richard
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Is there any more describing documentation about this?
I didn't even know about that the option existed.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Post by Jamie »

All the documentation (at least that I've read) for interrupts and events is in the XS1 Architecture (Sec. 16) and XS1 Architecture Tutorial (Sec. 7) documents. It's quite a turse read but its all there.
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

Hi,

A bit more description is given in XMOS document portXS1.pdf.

It really would be helpful for XMOS to provide a more in-depth presentation of the port system.

There is a description in the very useful document, Programming XC on XMOS devices, chapter, XC IO Programming, but the code outlines provided leave out some of the control(?) lines shown in the block diagram. For example, what do the lines, rin and rout do?

John.