在基于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,进行最初的中断分发。