interrupt handler and alternate register set and non-nesting interrupt

I'm using ADSP21489. I'm trying to migrate CCES from VDSP++.

Now I have the next problem.

My VDSP++ project use the super-fast interrupt dispatcher (interrupts()) which uses the alternate register set and interrupt nesting is disabled.

I can't understand: What do I need that I get the non-nesting interrupt handler with alternate register set.

I'm stuck. If CCES can't support it I will return back VDSP++

Parents
  • Kenny, thanks very much for this!  It has been very useful to me and I am sure many others.

  • Starting with Kennie's code I shaved a few more instruction cycles off of interrupt dispatching.  I realize few people are worried about the fastest-possible interrupt, but I wanted to share an outline of it in case it helps anyone else.

    (1) Turn off NESTM (no nested interrupts) and compile with -restrict-hardware-loops 3

    (2) Use these macros to build IVT:

    // XXX - hang for interrupt vectors we do not use. Label the 4 vector instructions for map.xml
    // INT - save stack and frame pointers (i6 and i7) to SPFP, jump to our custom dispatcher,
    //         do explicit "push sts" [needed for most interrupts], and set to alternate registers.
    //         NB: "push sts" saves ASTATx, ASTATy, MODE1, and masks MODE1 using ~MMASK.
    // IRQ - like INT macro but without explicit "push sts" [for irq3-0 and core timer interrupts].
    //          NB: Hardware does an implicit "push sts" for irq3-0 and core timer interrupts.
    #define XXX(irp) .retain_name irp##_ivt; irp##_ivt: JUMP irp##_ivt; nop; nop; nop;
    #define INT(irp, tgt) .extern tgt; .retain_name irp##_##tgt; irp##_##tgt: \
                dm(SPFP) = i6 (LW); JUMP tgt (DB); push sts; bit set mode1 0x04fc;
    #define IRQ(irp, tgt) .extern tgt; .retain_name irp##_##tgt; irp##_##tgt: \
                dm(SPFP) = i6 (LW); JUMP tgt (DB); bit set mode1 0x04fc; nop;

    (3) Write dispatchers like this (one is shown for use with INT macro in IVT, another for IRQ):

    // These minimal super-fast dispatchers will:
    // - save the stack and frame pointers
    // - enable the alternate register set
    // - set up the alternate stack and frame pointers.
    // Overhead to enter ISR = 18 CCLK = 5(interrupt sequencer) + 5(ivt) + 8(dispatcher)
    // Overhead to exit ISR = 4 CCLK

    rti_sts: // shared exit for interrupt dispatchers that work with INT macro in ivt
       rti (db);
       pop sts; // restore ASTATx, ASTATy, MODE1 (enables primary regs)
       nop;
    .rti_sts.end: .type rti_sts,STT_FUNC; .global rti_sts;

    PSensorDispatch: .extern _PSensorIsr;
       //dm(SPFP) = i6 (LW); // done by INT macro (save stack and frame pointers)
       //push sts; // done by INT macro (save ASTATx,ASTATy,MODE1; modify MODE1)
       //bit set mode1 0x04fc; // done by INT macro (select alternate registers)
       //nop; // done by jump delay (mode1 latency)
       nop; // for silicon anomolies (mode1 latency)
       i6 = dm(SPFP) (LW); // set alt version stack and frame pointers
       cjump _PSensorIsr (db); // 2 pipeline stalls (cjump has implicit r2=i6, i6=i7)
       dm(i7, m7) = r2;
       dm(i7, m7) = rti_sts-1; // return to rti_sts (executes: rti (db); pop sts; nop)
    .PSensorDispatch.end: .type PSensorDispatch,STT_FUNC; .global PSensorDispatch;

    rtcDispatch: .extern _rtcIsr; // unusual dispatcher (via IRQ macro)
       //push sts; // implicit "push sts" for irq3-0 and core timer
       //dm(SPFP) = i6 (LW); // done by IRQ macro (save stack and frame pointers)
       //bit set mode1 0x04fc; // done by IRQ macro (select alternate registers)
       //nop; // done by IRQ macro (mode1 latency)
       //nop; // done by jump delay (for silicon anomolies)
       i6 = dm(SPFP) (LW); // set alt version stack and frame pointers
       cjump _rtcIsr (db); // 2 pipeline stalls (cjump has implicit r2=i6, i6=i7)
       dm(i7, m7) = r2;
       dm(i7, m7) = .ret_rtc-1;
    .ret_rtc:
       rti; // implicit "pop sts" done by rti for irq3-0 and core timer
    .rtcDispatch.end: .type rtcDispatch,STT_FUNC; .global rtcDispatch;

Reply
  • Starting with Kennie's code I shaved a few more instruction cycles off of interrupt dispatching.  I realize few people are worried about the fastest-possible interrupt, but I wanted to share an outline of it in case it helps anyone else.

    (1) Turn off NESTM (no nested interrupts) and compile with -restrict-hardware-loops 3

    (2) Use these macros to build IVT:

    // XXX - hang for interrupt vectors we do not use. Label the 4 vector instructions for map.xml
    // INT - save stack and frame pointers (i6 and i7) to SPFP, jump to our custom dispatcher,
    //         do explicit "push sts" [needed for most interrupts], and set to alternate registers.
    //         NB: "push sts" saves ASTATx, ASTATy, MODE1, and masks MODE1 using ~MMASK.
    // IRQ - like INT macro but without explicit "push sts" [for irq3-0 and core timer interrupts].
    //          NB: Hardware does an implicit "push sts" for irq3-0 and core timer interrupts.
    #define XXX(irp) .retain_name irp##_ivt; irp##_ivt: JUMP irp##_ivt; nop; nop; nop;
    #define INT(irp, tgt) .extern tgt; .retain_name irp##_##tgt; irp##_##tgt: \
                dm(SPFP) = i6 (LW); JUMP tgt (DB); push sts; bit set mode1 0x04fc;
    #define IRQ(irp, tgt) .extern tgt; .retain_name irp##_##tgt; irp##_##tgt: \
                dm(SPFP) = i6 (LW); JUMP tgt (DB); bit set mode1 0x04fc; nop;

    (3) Write dispatchers like this (one is shown for use with INT macro in IVT, another for IRQ):

    // These minimal super-fast dispatchers will:
    // - save the stack and frame pointers
    // - enable the alternate register set
    // - set up the alternate stack and frame pointers.
    // Overhead to enter ISR = 18 CCLK = 5(interrupt sequencer) + 5(ivt) + 8(dispatcher)
    // Overhead to exit ISR = 4 CCLK

    rti_sts: // shared exit for interrupt dispatchers that work with INT macro in ivt
       rti (db);
       pop sts; // restore ASTATx, ASTATy, MODE1 (enables primary regs)
       nop;
    .rti_sts.end: .type rti_sts,STT_FUNC; .global rti_sts;

    PSensorDispatch: .extern _PSensorIsr;
       //dm(SPFP) = i6 (LW); // done by INT macro (save stack and frame pointers)
       //push sts; // done by INT macro (save ASTATx,ASTATy,MODE1; modify MODE1)
       //bit set mode1 0x04fc; // done by INT macro (select alternate registers)
       //nop; // done by jump delay (mode1 latency)
       nop; // for silicon anomolies (mode1 latency)
       i6 = dm(SPFP) (LW); // set alt version stack and frame pointers
       cjump _PSensorIsr (db); // 2 pipeline stalls (cjump has implicit r2=i6, i6=i7)
       dm(i7, m7) = r2;
       dm(i7, m7) = rti_sts-1; // return to rti_sts (executes: rti (db); pop sts; nop)
    .PSensorDispatch.end: .type PSensorDispatch,STT_FUNC; .global PSensorDispatch;

    rtcDispatch: .extern _rtcIsr; // unusual dispatcher (via IRQ macro)
       //push sts; // implicit "push sts" for irq3-0 and core timer
       //dm(SPFP) = i6 (LW); // done by IRQ macro (save stack and frame pointers)
       //bit set mode1 0x04fc; // done by IRQ macro (select alternate registers)
       //nop; // done by IRQ macro (mode1 latency)
       //nop; // done by jump delay (for silicon anomolies)
       i6 = dm(SPFP) (LW); // set alt version stack and frame pointers
       cjump _rtcIsr (db); // 2 pipeline stalls (cjump has implicit r2=i6, i6=i7)
       dm(i7, m7) = r2;
       dm(i7, m7) = .ret_rtc-1;
    .ret_rtc:
       rti; // implicit "pop sts" done by rti for irq3-0 and core timer
    .rtcDispatch.end: .type rtcDispatch,STT_FUNC; .global rtcDispatch;

Children
No Data