这篇blog主要分为三部分:
1,中断初始化
2,vxbus架构中断的挂接
3,非vxbus架构的中断的挂接
1,中断的初始化
函数调用:
usrInit->sysStart->palInit->palDescInit()
/*为了方便查看,这里对函数 进行了删减
*palDescInit()函数对默认的中断函数进行了初始化
*/
void palDescInit (void)
{
int idx;
#ifndef _WRS_MIPS_NONCOMPLIANT_CONFIG_REG
UINT32 config;
#endif /* _WRS_MIPS_NONCOMPLIANT_CONFIG_REG */
bzero((char *)&palDesc, sizeof(palDesc));
palDesc.coreNum = 0;
palDesc.version = "1.1";
/* Hopefully code further down will be able to refine these */
palDesc.iCache.present = FALSE;
palDesc.dCache.present = FALSE;
palDesc.l2Cache.present = FALSE;
palDesc.l3Cache.present = FALSE;
if (IS_KSEGM((UINT32) &palDescInit))
{
/* 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;
}
/* Reasonable defaults */
palDesc.tlb.supportedPageSizes = MMU_PAGE_MASK_8K;
palDesc.tlb.mmuCacheable=MMU_R4K_STATE_INVALID_STATE >> MMU_R4K_CACHE_START;
palDesc.tlb.mmuUncacheable = CFG_CCA_UNCACHED;
palDesc.tlb.mmuCacheCopyback = CFG_CCA_CACHEABLE;
palDesc.tlb.mmuCacheWritethrough = CFG_CCA_ALIAS_CACHEABLE;
palDesc.tlb.mmuCacheCoherency = CFG_CCA_COHERENT;
palDesc.iCache.modes = CACHE_MODES_SUPPORTED;
palDesc.dCache.modes = CACHE_MODES_SUPPORTED;
}
//重要的结构体说一下
#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 */
#define R_VEC (K1BASE+0x1fc00000) /* reset vector */
#define BEV_VEC (K1BASE+0x1fc00380) /* boot exception vector */
typedef struct
{
char *version; /* PAL version string */
int coreNum; /* processor number */
MIPS_EXC_VECTOR tVec; /*tlbmiss中断*/
MIPS_EXC_VECTOR xVec; /*xtlbmiss中断*/
MIPS_EXC_VECTOR cVec; /*cache异常中断*/
MIPS_EXC_VECTOR eVec; /*异常中断,包括中断(根据exccode码判别)*/
MIPS_MMU_INFO tlb; /**/
MIPS_CACHE_INFO iCache; /*指令cache相关*/
MIPS_CACHE_INFO dCache; /*数据cache相关*/
MIPS_CACHE_INFO l2Cache; /*二级cache相关*/
MIPS_CACHE_INFO l3Cache; /*三级cache相关*/
int mmuType; /* CR bits 9:7 */
BOOL hasCP2;
BOOL hasWatch;
BOOL hasFPU;
} MIPS_PAL_DESC;
默认中断函数的安装:
函数调用:
usrInit->excVecInit
/*在这里会安装默认的中断处理函数*/
STATUS excVecInit (void)
{
ULONG srValue; /* status register placeholder */
/* 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);
srValue = intSRGet();
srValue &= ~SR_BEV;
intSRSet(srValue);
return (OK);
}
LOCAL void vecInit
(
MIPS_EXC_VECTOR * vectorDesc
)
{
if (vectorDesc->excSize)
{
/*把函数拷贝到设置的地址处*/
bcopy ((const char *) vectorDesc->excHandler,
(char *) vectorDesc->vectorAddr, vectorDesc->excSize);
/*刷cache操作*/
CACHE_TEXT_UPDATE (vectorDesc->vectorAddr, vectorDesc->excSize);
}
}
到这里系统默认的中断处理函数就初始化完成。
这里找一个具体的中断控制器的初始化进行说明。(这是一个抽象出来的中断控制器,至于什么是抽象,也就是没有一个具体的物理硬件设备对应这个控制器,这只是一个软件层面的简化,这样对于中断的处理就更明显,直接。)
函数调用关系:
usrInit->sysHwInit->vxbMipsLsnIntCtlrRegister
当这个控制其注册之后:
vxbMipsLsnIntCtlrRegister->vxbDevRegister->vxbNewDriver->vxbDevInitRun
/*vxbDevInitRun函数会调用设备对应的初始化函数对设备进行初始化*/
LOCAL void vxbDevInitRun
(
VXB_DEVICE_ID devID,
struct vxbDevRegInfo * pDrv
)
{
/* first pass */
if (!(devID->flags &