// // Exception handler // // This is the exception handler for the packet ring and is designed to handle // the timer 3 interrupt by // managing a real time counter and check the current value against a requested // time. // // Only Timer 3 interrupts are enabled. All other interrupts or exceptions are fatal // errors, so this code jumps to FatalError and stays there forever in that case. #define SIMTIMEU 0x0001 #define SIMTIMEL 0x0000 // time for simulation: // when the counter (which begins @ first pkt arrival) // reaches this point, we enter a self-loop. #define r26TIMER r26 // Real time counter #define r27REQ r27 // Request time #define r20CTXINACT r20 // Current inactive context mfc0 r22CAUSE, CAUSE // Get cause of exception/interrupt ori r19TMP, r0, 0x9 // Code for BREAK ram r18TMP, r22CAUSE, CAUSE_EXCODE_POS, (32-CAUSE_EXCODE_SIZ), 0 // Get exception code in [3:0] beq r18TMP, r19TMP, GotBREAK // Test for a BREAK command bne r0, r18TMP, FatalError // Branch if not interrupt bbin r22CAUSE(CAUSE_BIUIP), FatalError // Branch if not BIU interrupt cfc0 r19TMP, BIUINT // Get the BIU Interrupt nop bbin r19TMP(BIUINT_TIMER3), FatalError // Branch if not Timer 3 Interrupt nop // **************************************************************************** // Timer 3 Error Interrupt Handler // **************************************************************************** Timer3Int: // Increment the real time counter in register r25TIMER ldw r26TIMER, REALTIME(r0) // Get the real time counter and request ctc0 r19TMP, BIUINT // Clear the interrupt bit addiu r26TIMER, r26TIMER, 1 // Increment the real time counter sw r26TIMER, (REALTIME+4)(r0) // Write real time back j TimerReturn //currently no need to implement sim timer. nop lw r26TIMER, (REALTIME+8)(r0) // Get the sim timer orui r27REQ, r0, SIMTIMEU ori r27REQ, r27REQ, SIMTIMEL // get the comparison value addiu r26TIMER, r26TIMER, 1 // increment the sim timer sw r26TIMER, (REALTIME+8)(r0) // write the sim timer back bne r26TIMER, r27REQ, TimerReturn // compare! nop loopydoo: j loopydoo nop // If here, the request matches the real time counter // For now, just increment another counter when this happens // lw r26TIMER, (REALTIME+8)(r0) // Get the match counter // nop // addiu r26TIMER, r26TIMER, 1 // Increment the match counter // sw r26TIMER, (REALTIME+8)(r0) // Write match counter back // addiu r27REQ, r27REQ, 256 // Move request ahead in time // sw r27REQ, (REALTIME+4)(r0) // Write it back // Activate selected inactive context ram r19TMP, r20CTXINACT, 28,26,4 addiu r19TMP, r19TMP, C0SBACT jr r19TMP .align 32 C0SBACT: cfc0 r18TMP, CTX0SB // Get Context Scoreboard andoi r18TMP, r18TMP, 0xfffe // Set active bit j ACTEXIT ctc0 r18TMP, CTX0SB // Write it back C1SBACT: cfc0 r18TMP, CTX1SB // Get Context Scoreboard andoi r18TMP, r18TMP, 0xfffe // Set active bit j ACTEXIT ctc0 r18TMP, CTX1SB // Write it back C2SBACT: cfc0 r18TMP, CTX2SB // Get Context Scoreboard andoi r18TMP, r18TMP, 0xfffe // Set active bit j ACTEXIT ctc0 r18TMP, CTX2SB // Write it back C3SBACT: cfc0 r18TMP, CTX3SB // Get Context Scoreboard andoi r18TMP, r18TMP, 0xfffe // Set active bit j ACTEXIT ctc0 r18TMP, CTX3SB // Write it back ACTEXIT: TimerReturn: // Start process to Return from interrupt ram r18TMP, r22CAUSE, CAUSE_ECTXT_POS, 28, 0 // Get interrupt context in [3:0] bbi r18TMP(3), IntDone // Branch if idle context // Check to see if interrupt occured during branch delay slot. // If so, EPC needs to be adjusted by -4. mfc0 r21EPC, EPC // Get EPC bbin r22CAUSE(CAUSE_BD), TimerInt1 // Branch if normal int nop addi r21EPC, r21EPC, -4 // Fixup EPC for branch dly slot INACTEXIT: TimerInt1: ram r19TMP, r22CAUSE, (CAUSE_ECTXT_POS-3), 27, 3 // Calc int context*8 addiu r19TMP,r19TMP, Ctx0Int jr r19TMP // Restore EPC to PC of interrupted context Ctx0Int: j IntDone mtc0 r21EPC, CTXPC0 Ctx1Int: j IntDone mtc0 r21EPC, CTXPC1 Ctx2Int: j IntDone mtc0 r21EPC, CTXPC2 Ctx3Int: mtc0 r21EPC, CTXPC3 IntDone: // Add nops to ensure 4 non-yielding instructions after mtc0 to CTXPCn nop nop jcr r18TMP // Return to interrupting context rfe // **************************************************************************** // Break Command Handler for control packet delay // **************************************************************************** GotBREAK: mfc0 r21EPC, EPC // Get EPC nop addi r21EPC, r21EPC, 4 // Fixup EPC for break instruction ram r18TMP, r22CAUSE, (CAUSE_ECTXT_POS-5), 23, 5 // Get interrupt context in [8:5] addiu r19TMP, r18TMP, C0SBINACT jr r19TMP .align 32 C0SBINACT: cfc0 r18TMP, CTX0SB // Get Context Scoreboard ori r20CTXINACT, r0, 0 // Save context ori r18TMP, r18TMP, 1 // Set inactive bit ctc0 r18TMP, CTX0SB // Write it back j INACTEXIT ori r18TMP, r0, 0xf // Select Idle context nop nop C1SBINACT: cfc0 r18TMP, CTX1SB // Get Context Scoreboard ori r20CTXINACT, r0, 1 // Save context ori r18TMP, r18TMP, 1 // Set inactive bit ctc0 r18TMP, CTX1SB // Write it back j INACTEXIT ori r18TMP, r0, 0xf // Select Idle context nop nop C2SBINACT: cfc0 r18TMP, CTX2SB // Get Context Scoreboard ori r20CTXINACT, r0, 2 // Save context ori r18TMP, r18TMP, 1 // Set inactive bit ctc0 r18TMP, CTX2SB // Write it back j INACTEXIT ori r18TMP, r0, 0xf // Select Idle context nop nop C3SBINACT: cfc0 r18TMP, CTX3SB // Get Context Scoreboard ori r20CTXINACT, r0, 3 // Save context ori r18TMP, r18TMP, 1 // Set inactive bit ctc0 r18TMP, CTX3SB // Write it back j INACTEXIT ori r18TMP, r0, 0xf // Select Idle context nop nop // **************************************************************************** // Exception and Unused Interrupt handler - treat as fatal errors // **************************************************************************** FatalError: // mfc0 r22CAUSE, CAUSE // mfc0 r21EPC, EPC nop nop j FatalError nop