📄 intvectoralib.s
字号:
/* intVectorALib.s - assembly language vectored interrupt handling stubs *//* Copyright 2001 Wind River Systems, Inc. */ .data .globl copyright_wind_river/* * This file has been developed or significantly modified by the * MIPS Center of Excellence Dedicated Engineering Staff. * This notice is as per the MIPS Center of Excellence Master Partner * Agreement, do not remove this notice without checking first with * WR/Platforms MIPS Center of Excellence engineering management. *//*modification history--------------------01e,18jan02,agf add explicit align directive to data section(s)01d,01aug01,mem Diab integration.01c,16jul01,ros add CofE comment01b,12jun01,agf make vectored interrupt's arguement to WindView unique from non-vectored interrupt's01a,21may01,agf intiial creation*//*DESCRIPTIONThis module contains the assembly language vectored interrupt handlingstubs intVectorVec<0-15> and intVectorStub. The intVectorVec<0-15> areplaced at each of the addresses corresponding to a RM7K interruptvector address. The vector routines mark the vector and call the commonstub routine which saves the context and calls the appropriate ISR.intVectorVec15 is special in that it automatically calls the intStubroutine. This is done for the purpose of backwards compatibility. Ifonly one or two vectored interrupts are desired, the remaining vectorscan be set with an IPL of 15 and continue to work without any change.There are no user-callable routines in this module.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "private/eventP.h"#include "asm.h"#include "esf.h"#include "sysLib.h"/* registers */#define C0_1_IC $20 /* Interrupt control (CP0 set 1) */#define C0_1_IPLHI $19 /* Int Priority Level High */#define C0_1_IPLLO $18 /* Int Priority Level Low *//* bit masks/fields */#define VS_0 0x00 /* all IPLs use base vector */#define VS_32 0x01 /* 32 byte vector spacing */#define VS_64 0x02 /* 64 byte vector spacing */#define VS_128 0x04 /* 128 byte vector spacing */#define VS_256 0x08 /* 256 byte vector spacing */#define VS_512 0x10 /* 512 byte vector spacing */#define CAUSE_IV 0x01000000 /* Int Vectoring enable *//* constants */#define WV_VEC_INT_OFFSET 16 /* match to size of intPrioTable */#define IPL_DEFAULT_LO 0xffffffff /* IM[7:0] use priority 15 */#define IPL_DEFAULT_HI 0x00ffffff /* IM[13:0] use priority 15 */#define INTERRUPT_VECTOR_0 0 /* constant for mark of the */ /* active interrupt vector *//* WARNING!!! * The following defines must be updated whenever the routine * intVectorVec0 is touched */#define VS_VECTOR_MASK VS_32 /* VS set by intVectorVecInit */#define VECTOR_SPACING 32 /* num of bytes between the */ /* intVectorVec<0-14> routines */#define MAGIC_INSTRUCT_V14 0x241a000e /* combination of INTERRUPT_VECTOR_14 */ /* AND the preceding instruction; */ /* nec. for word alignment constraints */#define VECTOR_MARK_OFFSET 0 /* number of bytes from start of */ /* vector to locate the mark MOD 4 */#define IPL0_VECTOR_ADDR 0x80000200 /* memory location of intVectors */#define IPL1_VECTOR_ADDR 0x80000220 /* these all change based on the */#define IPL2_VECTOR_ADDR 0x80000240 /* VS value of VECTORVEC_SIZE */#define IPL3_VECTOR_ADDR 0x80000260#define IPL4_VECTOR_ADDR 0x80000280#define IPL5_VECTOR_ADDR 0x800002a0#define IPL6_VECTOR_ADDR 0x800002c0#define IPL7_VECTOR_ADDR 0x800002e0#define IPL8_VECTOR_ADDR 0x80000300#define IPL9_VECTOR_ADDR 0x80000320#define IPL10_VECTOR_ADDR 0x80000340#define IPL11_VECTOR_ADDR 0x80000360#define IPL12_VECTOR_ADDR 0x80000380#define IPL13_VECTOR_ADDR 0x800003a0#define IPL14_VECTOR_ADDR 0x800003c0#define IPL15_VECTOR_ADDR 0x800003e0/* end WARNING!!! */ /* internal */ .globl intVectorVecInit /* BSP initialization routine */ /* external */ .extern intCnt /* interrupt depth */ .extern areWeNested /* Boolean for int nesting */ .extern vxIntStackBase /* interrupt stack base */ .extern errno /* unix like errno */ .extern bcopy /* func ptr */ .extern cacheTextUpdate /* func ptr */ #ifdef WV_INSTRUMENTATION .extern _func_evtLogT0 /* _func_evtLogT0 func ptr */ .extern _func_trgCheck /* _func_trgCheck func ptr */ .extern evtAction .extern wvEvtClass .extern trgEvtClass #endif /* WV_INSTRUMENTATION */ .data .align 4intActiveIPL: .word 0 .text .set reorder/********************************************************************************* intVectorStub - save context and dispatch interrupt service routines** This is the interrupt dispatcher that is pointed to by the individual* interrupt vectors. In this routine we take care of saving state, and* jumping to the appropriate routines. On exit from handling we also* return here to restore state properly.** This routine is not callable!! This routine does not include save and* restore of floating point state.** INTERNAL* The goal here is to turn interrupts back on a quickly as possible.* Some guidelines we have followed are that k0 and k1 can ONLY be * used in non-interruptible sections. Control is finally passed to intExit* with interrupts disabled. Also, before we turn interrupts back on we must * save as a minimum the state of the processor that changed upon interrupt * generation (volatile registers). Volatile registers include the EPC, * and STATUS registers. Also saved before interrupts are enabled, are the * sp, v0, and at regs. These registers are not volatile, but used in reading * and saving volatile registers, and calculation of the interrupted processor * state. Saved registers (s regs) are not saved upon interrupts because the * MIPS compiler philosophy is to save any s-regs they use before any call.** at - so assembler can use at (non-volatile)* sp - we use interrupt stack (non-volatile)* epc - changed upon excpt generation (volatile)* cause - changed upon excpt generation (volatile)* status - must read to bugging int (volatile)* badva - changed upon excpt generation (volatile)* v0 - holds calculated int cause (non-volatile)** All interrupts that are are of a lower priority than the active one are* allowed. This is done by using the mask field from the intVecTable array* defined by the BSP author and turning those interrupt enables OFF.** NOMANUAL* void intVectorStub()*/ .globl intVectorStub .ent intVectorStubintVectorStub: .set noat/* * Are we nested interrupt ??? */ lw k1, areWeNested /* grab areWeNested */ bne k1, zero, nested /* if in isr don't reset sp */ lw k0, vxIntStackBase /* else {grab addr of int stack */ subu k0, ESTKSIZE /* make room for frame */ SW sp, E_STK_SP(k0) /* save sp on int stack */ move sp, k0 /* init new int stack ptr} */ b save_critical /* jump over stack manip */nested: SW sp, E_STK_SP-ESTKSIZE(sp) /* save sp in new intstk frame */ subu sp, ESTKSIZE /* make new int stk frame */save_critical: SW AT,E_STK_AT(sp) /* save as resvd reg */ .set at#ifndef WV_INSTRUMENTATION SW v0,E_STK_V0(sp) /* save return reg 0 */#endif /* WV_INSTRUMENTATION */ /* * The following code replaces intEnt so I don't need * to save ra while interrupts are masked */ addu k1, 1 /* increment areWeNested */ sw k1, areWeNested /* update value */ lw k1, intCnt /* load intCnt */ addu k1, 1 /* increment intCnt */ sw k1, intCnt /* update value */#ifdef WV_INSTRUMENTATION/* * Begin state save */intStateSave: SW zero,E_STK_ZERO(sp) /* init zero reg storage */ SW v0,E_STK_V0(sp) /* save func return 0 */ SW v1,E_STK_V1(sp) /* save func return 1 */ SW a0,E_STK_A0(sp) /* save passed param 0 */ SW a1,E_STK_A1(sp) /* save passed param 1 */ SW a2,E_STK_A2(sp) /* save passed param 2 */ SW a3,E_STK_A3(sp) /* save passed param 3 */ SW t0,E_STK_T0(sp) /* save temp reg 0 */ SW t1,E_STK_T1(sp) /* save temp reg 1 */ SW t2,E_STK_T2(sp) /* save temp reg 2 */ SW t3,E_STK_T3(sp) /* save temp reg 3 */ SW t4,E_STK_T4(sp) /* save temp reg 4 */ SW t5,E_STK_T5(sp) /* save temp reg 5 */ SW t6,E_STK_T6(sp) /* save temp reg 6 */ SW t7,E_STK_T7(sp) /* save temp reg 7 */ SW t8,E_STK_T8(sp) /* save temp reg 8 */ SW t9,E_STK_T9(sp) /* save temp reg 9 */ SW ra,E_STK_RA(sp) /* save return address */ mflo t2 /* read entry lo reg */ mfhi t3 /* read entry hi reg */ SW t2,E_STK_LO(sp) /* save entry lo reg */ SW t3,E_STK_HI(sp) /* save entry hi reg */0: #else /* WV_INSTRUMENTATION */ lw k0,errno sw k0,E_ERRNO(sp) /* save errno */#endif /* WV_INSTRUMENTATION */ .set noreorder mfc0 k1, C0_SR /* read status register */ mfc0 k0, C0_EPC /* read exception pc */ mfc0 v0, C0_CAUSE /* read cause register */ HAZARD_CP_READ sw k1, E_STK_SR(sp) /* save status on stack */ sw k0, E_STK_EPC(sp) /* save EPC on stack */ sw v0, E_STK_CAUSE(sp) /* save cause on stack */ .set reorder#ifdef WV_INSTRUMENTATION /* * windview instrumentation - BEGIN * enter an interrupt handler. */ lw t0, evtAction /* is instrumentation on? */ beqz t0, noIntEnt /* we are checking * if ((wvEvtClass&(WV_CLASS_1_ON)) != (WV_CLASS_1_ON)) * leave WV instrumentation and check triggering */ lw t0, wvEvtClass li t4, WV_CLASS_1_ON and t0, t0, t4 bne t4, t0, trgCheckIntEnt /* interrupts are locked */ /* all registers are saved */ lw t2, intActiveIPL /* get interrupting vector's mark */ addu a0, t2, MIN_INT_ID+WV_VEC_INT_OFFSET+1 lw t1, _func_evtLogT0 jal t1 /* call evtLogT0 routine */ lw v0, E_STK_CAUSE(sp) /* restore the value of v0. We */ /* might have lost it in evtLogT0 */trgCheckIntEnt: lw t0, trgEvtClass li t4, TRG_CLASS_1_ON and t0, t0, t4 bne t4, t0, noIntEnt lw t2, intActiveIPL /* get interrupting vector's mark */ addu a0, t2, MIN_INT_ID+WV_VEC_INT_OFFSET+1 li a1, TRG_CLASS1_INDEX li a2, 0x0 lw t1, _func_trgCheck jal t1 /* call evtLogT0 routine */ lw v0, E_STK_CAUSE(sp) /* restore the value of v0. We */noIntEnt: /* windview instrumentation - END */ lw k0,errno sw k0,E_ERRNO(sp) /* save errno */#else /* WV_INSTRUMENTATION */ SW t3,E_STK_T3(sp) /* save temp reg 3 (early) */ SW t2,E_STK_T2(sp) /* save temp reg 2 (early) */ SW t1,E_STK_T1(sp) /* save temp reg 1 (early) */#endif /* WV_INSTRUMENTATION *//* * Check for spurious interrupts -- SKIP for vectored interrupts *//* * Disable all lower priority interrupts */ /* k1 has STATUS and v0 has CAUSE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -