⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysepic.c

📁 VxWorks的bootloader实现
💻 C
📖 第 1 页 / 共 2 页
字号:
                pCurrHandler->next = pNewHandler;        sharing = TRUE;	}    if ((int)vector >= 0 && (int)vector < INT_VEC_IRQ0)        {        /* EPIC IRQ set EPIC registers, priority = WB_PRIO + vector */        if (!sharing)            epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY,                              EPIC_SENSE_LVL, (int) vector, (int) vector);        }    else    if ((int)vector == EPIC_DUART1_INT_VECT) /* setup duart 1 */ 	{	if (!sharing)	    epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY, \			      EPIC_SENSE_LVL, 0x03, (int)vector);	}    else    if ((int)vector == EPIC_DUART2_INT_VECT) /* setup duart 2 */	{	if (!sharing)	    epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY, \			      EPIC_SENSE_LVL, 0x05, (int)vector);        }    intUnlock (intVal);    return (OK);    }/********************************************************************************* sysEpicIntHandlerExec  - execute the handlers for a given vector* * This routine executes all the handlers chained to a given vector.* If a vector has no handlers attached to it, a logMsg is generated.** NOMANUAL** RETURNS: N/A**/void sysEpicIntHandlerExec    (    UCHAR intVec    )    {        INT_HANDLER_DESC * pCurrHandler;    /*  call each respective interrupt handler */	    if ((pCurrHandler = sysIntTbl [intVec]) == NULL)        {	logMsg ("uninitalized PIC interrupt vector %x\r\n",                intVec, 0,0,0,0,0);        }    else        {	if (epicIntTrace)	    {            /* execute duart interrupts */            if ((intVec == EPIC_DUART1_INT_VECT) || (intVec == EPIC_DUART2_INT_VECT))	        logMsg ("sysEpicIntHandlerExec, duart interrupt vector %x\r\n",intVec, 0,0,0,0,0);	    }	/* call Each respective chained interrupt handler  */	while (pCurrHandler != NULL)            {  	    (*pCurrHandler->vec) (pCurrHandler->arg);	    pCurrHandler = pCurrHandler->next;            }        } /* else */    }/********************************************************************************* sysEpicIntHandler - handles the EPIC interrupts to the CPU** This routine handles interrupts originating from the embedded interrupt* controller on the MPC8240 Power PC processor.* This handler is entered from the 0x500 exception.** This routine is entered with CPU external interrupts enables.** Since the EPIC is the primary interrupt controller this driver* first initiates an Epic acknowledge call and reads the vector* put out by the EPIC. Subsequent vectors have to be obtained if* an external interrupt controller is connected to one of the* epic handlers. ** This routine then processes the interrupt by calling all the interrupt* service routines chained to the vector.** Finally, this routine re-arms the interrupt at the PIC by performing an * PIC EOI for both the EPIC and the 8259s.** RETURNS:  N/A**/void  sysEpicIntHandler (void)    {    int		dontCare;    UCHAR 	epicIntVec;#if FALSE    int 	oldLevel;#endif    epicIntVec = epicIntAck ();	/* clear int, return the vec for highest IRQ */    /* loop till all interrupts are cleared */    while (epicIntVec != 0xff)        {        if (epicIntTrace)	    {            /* execute duart interrupt handler */            if ((epicIntVec == EPIC_DUART1_INT_VECT) || (epicIntVec == EPIC_DUART2_INT_VECT))                logMsg ("sysEpicIntHandler: duart interrupt vector %x\r\n",epicIntVec, 0,0,0,0,0);	    }#ifdef INCLUDE_WINDVIEW    WV_EVT_INT_ENT (epicIntVec);#endif     #if FALSE        /* block all lower priority interrupts */        if ((oldLevel = epicCurTaskPrioSet (epicIntVec)) == EPIC_INV_PRIO_ERROR)            {            return;            }    #endif        /* Allow external interrupts to the CPU. */        CPU_INT_UNLOCK (_PPC_MSR_EE);        sysEpicIntHandlerExec (epicIntVec);        /*         * Disable External Interrupts         * External Interrupts will be re-enabled in the kernel's wrapper         * of this Interrupt.         */        CPU_INT_LOCK (&dontCare);        WRS_ASM ("sync");        epicEOI ();				/* signal end of interrupt on EPIC */        WRS_ASM ("sync");        epicIntVec = epicIntAck ();    #if FALSE        epicCurTaskPrioSet (oldLevel); 	/* Allow the next interrupt to occur */    #endif        } /* while */    }/********************************************************************************* epicCurTaskPrioSet - set the priority of the current task.** NOTES** epicCurTaskPrioSet sets the priority of the Processor Current Task* Priority register to the value of the prioNum parameter.  This function* should be called after sysEpicInit() to lower the priority of the processor* current task. Note that valid priority values are 0 through 15 (15 being* the highest priority)** NOMANUAL* * RETURNS: previous priority of the task.*/ULONG epicCurTaskPrioSet    (    int prioNum    )    {    ULONG oldPrio;    if ((prioNum < EPIC_PRIORITY_MIN) || (prioNum > EPIC_PRIORITY_MAX))        {        return (EPIC_INV_PRIO_ERROR);	}    oldPrio = sysEUMBBARRead (EPIC_PROC_CTASK_PRI_REG);    sysEUMBBARWrite (EPIC_PROC_CTASK_PRI_REG, prioNum);    return (oldPrio);    }/********************************************************************************* epicIntEnable - enable an EPIC interrupt, given its IVPR** This function clears the mask bit of an external, an internal or* a Timer register to enable the interrupt.** <srcAddr> is the address offset of the Vector Priority register  ** NOMANUAL* * RETURNS: OK or an error code if the IVPR passed in was invalid.*/int epicIntEnable    (    int 	srcAddr    )    {    ULONG 	srcVal;    int 	errCode;      errCode = epicsrcAddrCheck (srcAddr);    if (errCode != EPIC_INV_INTER_SOURCE)        {        srcVal = sysEUMBBARRead (srcAddr);        srcVal &= ~(EPIC_IVPR_INTR_MSK);	/* clear the mask bit */        if (srcAddr < 0x51120)            {            sysEUMBBARWrite(srcAddr, srcVal);            if (epicIntTrace)	        {                logMsg("epicIntEnable: ext intr enabled, %x \n", srcAddr,0,0,0,0,0);	        }            }        else	if ((srcAddr == EPIC_DUART1_INT_VEC_REG) || (srcAddr == EPIC_DUART2_INT_VEC_REG))	    {            sysEUMBBARWrite(srcAddr, srcVal);            if (epicIntTrace)	        {                logMsg("epicIntEnable: duart intr enabled, %x \n", srcAddr,0,0,0,0,0);	        }	    }        return (OK);        }    else        {        logMsg("epicIntEnable failed at epicsrcAddrCheck, srsAddr: %x \n", srcAddr,0,0,0,0,0);        return (errCode);        }    }/********************************************************************************* epicIntDisable - disable an EPIC interrupt, given its IVPR** This function sets the mask bit of an external, an internal or* a Timer register to disable the interrupt.* <srcAddr> is the address offset of the Vector Priority register.** NOMANUAL* * RETURNS: OK or an error code if the IVPR passed in was invalid.*/               int epicIntDisable    (    int 	srcAddr    )    {    ULONG 	srcVal;    int 	errCode;      errCode = epicsrcAddrCheck (srcAddr);    if (errCode != EPIC_INV_INTER_SOURCE)        {        srcVal = sysEUMBBARRead (srcAddr);        srcVal |= EPIC_IVPR_INTR_MSK;	/* set the mask bit */        sysEUMBBARWrite (srcAddr, srcVal);        return OK;        }     else        {        return (errCode);        }    }/********************************************************************************* epicIntAck - read the IACK register and return vector* * NOTES** epicIntAck reads the Interrupt acknowldge register and return* the vector number of the highest pending interrupt.** NOMANUAL* * RETURNS: the vector number of the highest priority pending interrupt.*/int epicIntAck(void)    {    int eumbVal;    eumbVal = sysEUMBBARRead (EPIC_PROC_INT_ACK_REG);    WRS_ASM ("eieio");    return eumbVal;    }/********************************************************************************* epic EOI 0 signal end of interrupt on the EPIC** NOTES** epicEOI writes 0x0 to the EOI register to signal end of interrupt.* This function is usually called after an interrupt routine is served.** NOMANUAL* * RETURNS: N/A*/void epicEOI(void)    {    sysEUMBBARWrite (EPIC_PROC_EOI_REG, 0x0);    }/********************************************************************************* epicsrcAddrCheck - check if the IVPR address passed in is internal or external** NOTES** Check if the address of a vector priority register is of an internal* interrupt vector or an external interrupt vector.** NOMANUAL* * RETURNS: EPIC_INTERNAL_INTERRUPT for internal interrupt sources,*          or EPIC_EXTERNAL_INTERRUPT for external ones, or*          EPIC_INV_INTER_SOURCE if an invalid IVPR was passed.*/STATUS epicsrcAddrCheck    (    ULONG srcAddr    )    {    switch(srcAddr)        {        case EPIC_TM0_VEC_REG:        case EPIC_TM1_VEC_REG:        case EPIC_TM2_VEC_REG:        case EPIC_TM3_VEC_REG:        case EPIC_I2C_INT_VEC_REG:        case EPIC_DMA0_INT_VEC_REG:        case EPIC_DMA1_INT_VEC_REG:        case EPIC_MSG_INT_VEC_REG:        case EPIC_DUART1_INT_VEC_REG:    /* added duart vectors */        case EPIC_DUART2_INT_VEC_REG:            return (EPIC_INTERNAL_INTERRUPT);        case EPIC_SR_INT0_VEC_REG:        case EPIC_SR_INT1_VEC_REG:        case EPIC_SR_INT2_VEC_REG:        case EPIC_SR_INT3_VEC_REG:        case EPIC_SR_INT4_VEC_REG:        case EPIC_SR_INT5_VEC_REG:        case EPIC_SR_INT6_VEC_REG:        case EPIC_SR_INT7_VEC_REG:        case EPIC_SR_INT8_VEC_REG:        case EPIC_SR_INT9_VEC_REG:        case EPIC_SR_INT10_VEC_REG:        case EPIC_SR_INT11_VEC_REG:        case EPIC_SR_INT12_VEC_REG:        case EPIC_SR_INT13_VEC_REG:        case EPIC_SR_INT14_VEC_REG:        case EPIC_SR_INT15_VEC_REG:            return (EPIC_EXTERNAL_INTERRUPT);        default:            return (EPIC_INV_INTER_SOURCE);        }    }/********************************************************************************* epicIntSourceSet - set interrupt parameters for an interrupt register** This function sets the interrupt parameters for an External Interrupt* Source Vector Priority register, an Internal Interrupt Source Vector* Priority register, or a Global Timer register.  The interrupt parameters* can only be set when the current source is not in-request or in-service,* which is determined by the Activity bit.  This routine reads the Activity* bit; if the value of this bit is 1 (in-request or in-service), it returns* error; otherwise, it sets the value of the parameters to the register* offset defined in srcAddr.** inputs:  srcAddr:   Address Offset of the source interrupt register.  This*		      routine assumes that the srcAddr passed in is an valid*		      Source Vector Priority address.*          polarity: Use by external interrupts only, internal and timer*                    interrupts ignore this parameter.*                    1 -  Enable active high or positive edge*                    0 -  Enable active low or negative edge*          sense:    Use by external interrupts only, internal and timer*                    interrupts ignore this parameter.*                    1 -  Enable level sensitive interrupts*                    0 -  Enable edge sensitive interrupts*          priority: valid number 0 to 15   *          vector:   valid number 0 - 128  (8 bits)** Errors:  Invalid Source Address,*          Invalid Priority error,*          Unable to set parameters** NOMANUAL* * RETURNS: OK or ERROR*/STATUS epicIntSourceSet    (    ULONG 	srcAddr,    int 	polarity,    int 	sense,    int 	priority,    int 	vector    )    {    ULONG 	srcVal;    ULONG	errCode;      errCode = epicsrcAddrCheck(srcAddr);    if (errCode == EPIC_INV_INTER_SOURCE)        {        return (errCode);        }    srcVal = sysEUMBBARRead(srcAddr);    if (srcVal & EPIC_IVPR_INTR_ACTIVE)        {        return (EPIC_INTER_IN_SERVICE);	/* interrupt in process */        }    /* polarity and sense doesn't apply to internal interrupts */        if (errCode == EPIC_INTERNAL_INTERRUPT)        {      	polarity = 0;        sense    = 0;        }    /* erase previously set polority, sense, prority and vector values */        srcVal &= ~(EPIC_IVPR_INTR_POLARITY | EPIC_IVPR_INTR_SENSE |                EPIC_IVPR_PRIORITY_MSK  | EPIC_IVPR_VECTOR_MSK);    srcVal |= (EPIC_IVPR_POLARITY (polarity) | EPIC_IVPR_SENS (sense) |               EPIC_IVPR_PRIORITY (priority) | EPIC_IVPR_VECTOR (vector));    sysEUMBBARWrite(srcAddr, srcVal);    return (OK);    }/********************************************************************************* epicIntSourceGet - retrieve information of an EPIC source vector register.** This function retrieves information of an epic source vector register.* The information includes the Enable bit, the polarity, sense bits, the* interrupt priority and interrupt vector number.* Input:  srcAddr   - address of the source vector register* Output: enable   - whether the interrupt is enabled*          polarity - interrupt polarity (high or low)*          sense    - interrupt sense (level or edge)*          Priority     - interrupt priority*          Vector     - interrupt vector number** NOMANUAL* * RETURNS: N/A*/STATUS epicIntSourceGet    (    ULONG 	srcAddr,    int *	pEnableMask,    int *	pPolarity,    int *	pSense,    int *	pPriority,    int *	pVector    )    {    ULONG 	srcVal;    int 	errCode;      errCode = epicsrcAddrCheck (srcAddr);    if (errCode == EPIC_INV_INTER_SOURCE)        {        return errCode;        }    srcVal = sysEUMBBARRead(srcAddr);        *pEnableMask  = (srcVal & 0x80000000) >> 31; /* retrieve enable mask-b31 */    *pPolarity    = (srcVal & 0x00800000) >> 23;    *pSense       = (srcVal & 0x00400000) >> 22;    *pPriority    = (srcVal & 0x000F0000) >> 16;    *pVector      = (srcVal & 0x000000FF);    return OK;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -