在基于mips架构的vxworks中,中断来了之后执行的第一个指令再那里?
关于中断以及tlb异常函数存储再palDesc中,当然了其地址也再其中。
MIPS_PAL_DESC palDesc = { "unknown" };相关的结构体设置: typedef struct { char *version; /* PAL version string */ int coreNum; /* processor number */ MIPS_EXC_VECTOR tVec; MIPS_EXC_VECTOR xVec; MIPS_EXC_VECTOR cVec; MIPS_EXC_VECTOR eVec; MIPS_MMU_INFO tlb; MIPS_CACHE_INFO iCache; MIPS_CACHE_INFO dCache; MIPS_CACHE_INFO l2Cache; MIPS_CACHE_INFO l3Cache; int mmuType; /* CR bits 9:7 */ BOOL hasCP2; BOOL hasWatch; BOOL hasFPU; } MIPS_PAL_DESC; typedef struct { VIRT_ADDR * vectorAddr; /* typically [T,X,C,E]_Vec */ VIRT_ADDR * excHandler; /* typically exc[Tlb,Xtlb,Cache,Norm]Vec */ UINT excSize; /* size of handler copied to vectorAddr */ } MIPS_EXC_VECTOR; 其初始化的函数调用: usrInit-->sysStart-->palInit-->palDescInit写入的中断的向量的地址: void palDescInit (void) { bzero((char *)&palDesc, sizeof(palDesc)); palDesc.coreNum = 0; palDesc.version = "1.0"; /* executing a mapped kernel */ palDesc.tVec.vectorAddr = (VIRT_ADDR *)T_VEC; palDesc.tVec.excHandler = (VIRT_ADDR *)mmuMipsTlbVec; palDesc.tVec.excSize = mmuMipsTlbVecSize; palDesc.xVec.vectorAddr = (VIRT_ADDR *)X_VEC; palDesc.xVec.excHandler = (VIRT_ADDR *)mmuMipsXtlbVec; palDesc.xVec.excSize = (UINT)mmuMipsXtlbVecSize; palDesc.cVec.vectorAddr = (VIRT_ADDR *)C_VEC; palDesc.cVec.excHandler = (VIRT_ADDR*)excCacheVec; palDesc.cVec.excSize = (UINT)excCacheVecSize; palDesc.eVec.vectorAddr = (VIRT_ADDR *)E_VEC; palDesc.eVec.excHandler = (VIRT_ADDR *)excNormVmVec; palDesc.eVec.excSize = (UINT)excNormVmVecSize; } #define K0BASE 0x80000000 #define T_VEC K0BASE /* tlbmiss vector */ #define X_VEC (K0BASE+0x80) /* xtlbmiss vector */ #define C_VEC (K1BASE+0x100) /* cache exception vector */ #define E_VEC (K0BASE+0x180) /* exception vector */把函数写入到对应地址的函数调用:
usrInit-->excVecinit-->vecInit STATUS excVecInit(void) { ... /* Load tlb and Xtlb vectors */ vecInit (&palDesc.tVec); vecInit (&palDesc.xVec); /* Load cache exception vector */ vecInit (&palDesc.cVec); /* Load normal/interrupt vector */ vecInit (&palDesc.eVec); ... } /*把函数写入到对应的地址中去*/ LOCAL void vecInit ( MIPS_EXC_VECTOR * vectorDesc ) { /* load the handler routine and invalidate the I-cache */ if (vectorDesc->excSize) { bcopy ((const char *) vectorDesc->excHandler, (char *) vectorDesc->vectorAddr, vectorDesc->excSize); CACHE_TEXT_UPDATE (vectorDesc->vectorAddr, vectorDesc->excSize); } } 也就是说当中断来了之后,cpu会自动调转到地址E_VEC(0X8000_0180),去执行E_VEC地址出存储的函数excNormVmVec,进行最初的中断分发。