📄 sysmpc107epic.c
字号:
/* sysMpc107Epic.c - Motorola MPC107 Interrupt Controller driver *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------01b,17dec01,g_h Add Wind View instrumentation.01a,12may01,g_h written*//*DESCRIPTIONThis module implements the MPC107 EPIC interrupt controller driver.INCLUDES: sysMpc107Epic.h*//* includes */#include "sysMpc107Epic.h"#ifdef INCLUDE_WINDVIEW#include "private/eventP.h"#endif /* INCLUDE_WINDVIEW *//* defines */#define LEVEL_SENSE EPIC_INT_SENSE#define EDGE_SENSE 0#define ACTIVE_HIGH EPIC_INT_POLARITY#define ACTIVE_LOW 0/* globals */IMPORT STATUS (*_func_intConnectRtn) (VOIDFUNCPTR *, VOIDFUNCPTR, int);IMPORT int (*_func_intEnableRtn) (int);IMPORT int (*_func_intDisableRtn) (int);IMPORT void sysOutByte (ULONG, UCHAR);IMPORT UCHAR sysInByte (ULONG);IMPORT void sysPciRead32 (UINT32, UINT32 *);IMPORT void sysPciWrite32 (UINT32, UINT32);IMPORT STATUS excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);void sysMpc107EpicIntHandler (void);IMPORT UINT sysVectorIRQ0; /* vector for IRQ0 */INT_HANDLER_DESC * sysIntTbl [256]; /* system interrupt table */int tpr;int spurIntCnt;/* forward declarations */LOCAL STATUS sysMpc107EpicIntConnect (VOIDFUNCPTR * vector, VOIDFUNCPTR routine, int parameter);LOCAL int sysMpc107EpicIntEnable (int);LOCAL int sysMpc107EpicIntDisable (int);#ifndef CPU_INT_LOCK#define CPU_INT_LOCK(x) (*x = intLock ())#endif#ifndef CPU_INT_UNLOCK#define CPU_INT_UNLOCK(data) (intUnlock (data))#endif/***************************************************************************** sysMpc107EpicInit - initialize the EPIC in the MPC107** This function initializes the Embedded Programmable * Interrupt Controller (EPIC) which is part of the MPC107.** It first initializes the system vector table, connects the EPIC interrupt* handler to the PPC external interrupt and attaches the local EPIC routines* for interrupt connecting, enabling and disabling to the corresponding system* routine pointers.** It then initializes the EPIC register and clears any pending EPIC interrupts.** RETURNS: OK always** SEE ALSO: sysMpc107EpicIntConnect(), sysMpc107EpicIntEnable(), * sysMpc107EpicIntDisable(), sysMpc107EpicIntHandler() */STATUS sysMpc107EpicInit ( void ) { int i; /* Initialize the interrupt table */ for (i = 0; i < 256; i++) { sysIntTbl[i] = NULL; } /* Connect the interrupt demultiplexer to the PowerPC external interrupt */ excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, sysMpc107EpicIntHandler); /* * Set up the BSP specific routines * Attach the local routines to the vxWorks system calls */ _func_intConnectRtn = sysMpc107EpicIntConnect; _func_intEnableRtn = sysMpc107EpicIntEnable; _func_intDisableRtn = sysMpc107EpicIntDisable; *EPIC_GCR = LONGSWAP(0xa0000000); /* reset the EPIC */ for (i=0;i < 1024;i++); /* wait for reset to complete */ *EPIC_GCR = LONGSWAP(0x20000000); /* put the EPIC into mixed mode */ /* initialize all interrupt sources */ /* external interrupts */ *EPIC_EISVP0 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_LOW | INT_VEC_IRQ0 | INT_PRI_IRQ0); *EPIC_EISVP1 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_LOW | INT_VEC_NONE | INT_PRI_NONE); *EPIC_EISVP2 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_LOW | INT_VEC_NONE | INT_PRI_NONE); *EPIC_EISVP3 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_LOW | INT_VEC_NONE | INT_PRI_NONE); *EPIC_EISVP4 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_HIGH | INT_VEC_IRQ4 | INT_PRI_IRQ4); /* timer interrupts */ *EPIC_GTVR0 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR0 | INT_PRI_TMR0); *EPIC_GTVR1 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR1 | INT_PRI_TMR1); *EPIC_GTVR2 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR2 | INT_PRI_TMR2); *EPIC_GTVR3 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR3 | INT_PRI_TMR3); /* DMA,I2C and I20 interrupts */ *EPIC_DMA0_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_DMA0 | INT_PRI_DMA0); *EPIC_DMA1_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_DMA1 | INT_PRI_DMA1); *EPIC_I2C_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_I2C | INT_PRI_I2C); *EPIC_I2O_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_I2O | INT_PRI_I2O); /* set the current processor priority level */ *EPIC_PCTP = LONGSWAP(0x00); /* clear out all possible pending interrupts */ while (*EPIC_PIACK != LONGSWAP(INT_VEC_SPURIOUS)) { *EPIC_PEOI = 0; } return OK; }/***************************************************************************** sysMpc107EpicIntConnect - connect an interrupt handler to the system vector table** This function connects an interrupt handler to the system vector table.** RETURNS: OK/ERROR.** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntEnable(), * sysMpc107EpicIntDisable(), sysMpc107EpicIntHandler() */ LOCAL STATUS sysMpc107EpicIntConnect ( VOIDFUNCPTR * vector, /* interrupt vector to attach */ VOIDFUNCPTR routine, /* routine to be called */ int parameter /* parameter to be passed to routine */ ) { INT_HANDLER_DESC * newHandler; INT_HANDLER_DESC * currHandler; if (((int)vector < 0) || ((int)vector > 0xff)) /* Out of Range? */ return (ERROR); /* create a new interrupt handler */ if ((newHandler = (INT_HANDLER_DESC *)calloc (1, sizeof (INT_HANDLER_DESC))) == NULL) return (ERROR); /* initialize the new handler */ newHandler->vec = routine; newHandler->arg = parameter; newHandler->next = NULL; /* install the handler in the system interrupt table */ if (sysIntTbl[(int) vector] == NULL) sysIntTbl [(int ) vector] = newHandler; /* single int. handler case */ else { currHandler = sysIntTbl[(int) vector]; /* multiple int. handler case */ while (currHandler->next != NULL) { currHandler = currHandler->next; } currHandler->next = newHandler; } return (OK); } /***************************************************************************** sysMpc107EpicIntEnable - enable an EPIC external interrupt level** This routine enables a specified EPIC interrupt level.** RETURNS: OK or ERROR if interrupt level not supported** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntConnect(), * sysMpc107EpicIntDisable(), sysMpc107EpicIntHandler() */ LOCAL int sysMpc107EpicIntEnable ( int intLevel /* interrupt level to enable */ ) { /* * if the int. level is not a valid IRQ * If not supported, just return. */ if ((intLevel < 0) || (intLevel > 4)) return (ERROR); /* clear the interrupt mask bit * Note: * on pointer arithmetic subtlety below - * External Interrupt Vector Priority registers are 8 longwords apart */ (EPIC_EISVP0)[intLevel*8] &= LONGSWAP(~EPIC_INT_MASK) ; return (OK); }/***************************************************************************** sysMpc107EpicIntDisable - disable an Mpic interrupt level** This routine disables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntConnect(), * sysMpc107EpicIntEnable(), sysMpc107EpicIntHandler() */ LOCAL int sysMpc107EpicIntDisable ( int intLevel /* interrupt level to disable */ ) { /* * if the int. level is not a valid IRQ * If not supported, just return. */ if ((intLevel < 0) || (intLevel > 4)) return (ERROR); /* set the interrupt mask bit Note: on pointer arithmetic subtlety below - External Interrupt Vector Priority registers are 8 longwords apart */ (EPIC_EISVP0)[intLevel*8] |= LONGSWAP(EPIC_INT_MASK) ; return (OK); }/***************************************************************************** sysMpc107EpicIntHandler - handle an interrupt received at the Mpic* * This routine will process interrupts received EPIC interrupt sources.** RETURNS: N/A** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntConnect(), * sysMpc107EpicIntEnable(), sysMpc107EpicIntDisable() */void sysMpc107EpicIntHandler ( void ) { int dontCare; INT_HANDLER_DESC * currHandler; UINT32 vecNum; /* get the vector from the EPIC IACK reg. */ vecNum = *EPIC_PIACK ; EIEIO ; vecNum = LONGSWAP(vecNum) & VECTOR_MASK ; #ifdef INCLUDE_WINDVIEW WV_EVT_INT_ENT (vecNum);#endif /* INCLUDE_WINDVIEW */ /* Ignore spurious interrupts */ if (vecNum == 0xFF) spurIntCnt++ ; while (vecNum != 0xff) { /* * Allow maskable interrupts to the CPU. MPIC will hold off * lower and equal interrupts until MPIC_EOI is performed. */ CPU_INT_UNLOCK(_PPC_MSR_EE); /* call the necessary interrupt handlers */ if ((currHandler = sysIntTbl [vecNum]) == NULL) { logMsg ("uninitialized MPC107 EPIC interrupt %d\r\n", vecNum, 0,0,0,0,0); } else { /* Call EACH respective chained interrupt handler */ while (currHandler != NULL) { currHandler->vec (currHandler->arg); currHandler = currHandler->next; } } /* * Disable External Interrupts * External Interrupts will be re-enabled in the kernel's wrapper * of this Interrupt. */ CPU_INT_LOCK (&dontCare); /* issue an end-of-interrupt to the EPIC */ *EPIC_PEOI = 0 ; EIEIO ; /* get the next vector from the EPIC IACK reg. */ vecNum = *EPIC_PIACK ; EIEIO ; vecNum = LONGSWAP(vecNum) & VECTOR_MASK ; } return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -