当cpu使能后(使能时就会进行初始化),就可以正行运行了,当然也包括处理中断,但是这个时候,中断还没有路由到对应的cpu上。
整理的函数正确运行后,中断就路由到对应的cpu上了。
这里呢就分析一下中断是怎么路由到它自己对应的cpu上的。
看一下函数调用:
usrRoot-->usrSmpInit-->usrEnableCpu-->usrSmpCpuEnableHook-->vxbIntToCpuRoute-->vxbDevMethodRun-->vxbIntCtlrCpuReroute-->vxbMipsSbIntCtlrCpuReroute
整理的函数正确运行后,中断就路由到对应的cpu上了。
看一下最后一个函数做了什么动作:
LOCAL STATUS vxbMipsSbIntCtlrCpuReroute
(
VXB_DEVICE_ID pDev,
void * destCpu
)
{
struct intCtlrHwConf *isrHandle = &(pVxbPMipsSbIntCtlrDrvCtrl->isrHandle);
int i, cpunum, outputPin, configCpu;
BOOL flag;
void (*func)();
/* move interrupts to requested cpu */
for (i = 0;i < SB1_NUM_INT_SOURCES;i++)
{
/*判断对应的引脚有没有设置*/
VXB_INTCTLR_PINENTRY_ALLOCATED(isrHandle, i, flag);
if (flag)
{
/*获取这个引脚的处理函数,如果函数为空或者等于intCtlrStrayISR就跳过*/
MIPS_SBE_ISR(isrHandle, i, func);
if (func == NULL || func == intCtlrStrayISR)
continue;
/*获取这个引脚对应的cpu号*/
MIPS_SBE_DESTCPU(isrHandle, i, configCpu);
if (configCpu == (int)destCpu)
{
/*把其他cpu上这个中断源禁止掉,也就是只有对应的cpu可以处理*/
for (cpunum = 0; cpunum < SB_NUM_CORES; cpunum++)
sb1IntDisableCore (i, cpunum);
/*获取这个引脚对应的输出引脚*/
MIPS_SBE_OUTPUTPIN(isrHandle, i, outputPin);
/*把这个输出引脚路由到对应的cpu上*/
sb1IntConnectCore (i, outputPin, (int)destCpu);
/*并使能中断*/
VXB_INTCTLR_PINENTRY_ENABLED(isrHandle, i, flag);
/*使能中断*/
if (flag)
sb1IntEnableCore (i, (int)destCpu);
}
}
}
/*记录已经使能的cpu*/
pVxbPMipsSbIntCtlrDrvCtrl->enabledCpus |= (1 << (int)destCpu);
return (OK);
}
看一下上面使用的一些宏操作:
/*获取中断函数*/
#define MIPS_SBE_ISR(pEnt,inputPin,func) \
{ \
struct vxbIntCtlrPin * pPin = \
vxbIntCtlrPinEntryGet(pEnt,inputPin); \
func = pPin->isr; \
}
/*获取一个引脚的输出引脚*/
#define MIPS_SBE_OUTPUTPIN(pEnt,inputPin,outputPin) \
{ \
struct vxbIntCtlrPin * pPin = \
vxbIntCtlrPinEntryGet(pEnt,inputPin); \
outputPin = pPin->pinOutput; \
}
/*获取一个引脚中断要路由到哪个cpu*/
#define MIPS_SBE_DESTCPU(pEnt,inputPin,destCpu) \
{ \
struct vxbIntCtlrPin * pPin = \
vxbIntCtlrPinEntryGet(pEnt,inputPin); \
destCpu = pPin->pinCpu; \
}
挂接到对应cpu的函数:
LOCAL STATUS sb1IntConnectCore
(
int intrSource, /* interrupt level / sb1 source number */
int intrLine, /* interrupt output line */
int cpunum /* core number to operate on */
)
{
#ifdef SOUTH_BRIDGE2H
if(intrSource == HT1_INT0)
intrSource = SYS_INT0;
#endif
/*设置对应的中断的额路由寄存器,根据输入的参数设置要路由到哪个cpu核哪个输出引脚上,核间通信寄存器*/
MIPS_SB64((((unsigned int)(SB1_INT_CTLR(bcm1xxxIntMapBaseH)))+intrSource),(1<<(intrLine+4))|(1<<cpunum));
return (OK);
}
使能对应核的cpu上的中断:
LOCAL STATUS sb1IntEnableCore
(
int intrSource,
int cpunum
)
{
STATUS retStatus;
#ifdef SOUTH_BRIDGE2H
if(intrSource == HT1_INT0)
intrSource = SYS_INT0;
#endif
retStatus = OK;
/*设置对应中断的使能寄存器置位,这里的寄存器是核间通信寄存器*/
MIPS_SW64((unsigned int)SB1_INT_CTLR(bcm1xxxIntMaskL),(unsigned int)(1<<intrSource));
return (retStatus);
}