s3c2410xIntrCtl.c
上传用户:ske666
上传日期:2022-03-30
资源大小:371k
文件大小:11k
- /* s3c2410xIntrCtl.c - s3c2410x interrupt controller driver */
- /* Copyright 2004, HITSAT, Inc. */
- #include "vxWorks.h"
- #include "config.h"
- IMPORT FUNCPTR sysIntLvlVecAckRtn;
- IMPORT FUNCPTR sysIntLvlVecChkRtn;
- IMPORT FUNCPTR sysIntLvlEnableRtn;
- IMPORT FUNCPTR sysIntLvlDisableRtn;
- /* hardware access methods */
- #ifndef s3c2410x_INT_REG_READ
- #define s3c2410x_INT_REG_READ(reg,result)
- ((result) = *((volatile UINT32 *)(reg)))
- #endif
- #ifndef s3c2410x_INT_REG_WRITE
- #define s3c2410x_INT_REG_WRITE(reg,data)
- (*((volatile UINT32 *)(reg)) = (data))
- #endif
- #define s3c2410x_REG_READ(reg)
- (*((volatile UINT32 *)(reg)))
- /* Local data
- #define s3c2410x_INT_ALL_ENABLED (s3c2410x_INT_NUM_LEVELS)
- #define s3c2410x_INT_ALL_DISABLED (s3c2410x_INT_NUM_LEVELS-1)
- */
- /* Current interrupt level setting (s3c2410xIntLvlChg). */
- /*LOCAL UINT32 s3c2410xIntLvlCurrent = s3c2410x_INT_ALL_DISABLED; all levels disabled */
- /*
- * A mask word. Bits are set in this word when a specific level
- * is enabled. It is used to mask off individual levels that have
- * not been explicitly enabled.
- */
- LOCAL UINT32 s3c2410xIntLvlEnabled;
- /* forward declarations */
- STATUS s3c2410xIntLvlVecChk (int*, int*);
- STATUS s3c2410xInitLvVecAck (int, int);
- STATUS s3c2410xIntLvlEnable (int);
- STATUS s3c2410xIntLvlDisable(int);
- /*
- * s3c2410xIntDevInit - initialize the interrupt controller
- *
- * This routine will:
- * <1> Initialize the interrupt controller device;
- * <2> Disabling all interrupt sources;
- * <3> Connect the device driver specific routines into the architecture level hooks.
- *
- * If the BSP needs to create a wrapper routine around any of the arhitecture level routines,
- * it should install the pointer to the wrapper routine after calling this routine.
- *
- * RETURNS: N/A.
- */
- int s3c2410xIntDevInit (void)
- {
- UINT32 tempUINT32 = 0;
-
- /* <1> Initialize the interrupt controller device; */
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,0xfeffffbf); /* Mask all Interrupt. */
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,0x7ff); /* Mask all subInterrupt. */
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32); /* Clear SUBSRCPND */
-
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SRCPND,tempUINT32);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND,tempUINT32); /* Clear SRCPND */
-
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND,tempUINT32);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND,tempUINT32); /* Clear INTPND. */
-
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMOD,0); /* Select IRQ mode. */
-
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_PRIORITY,0); /* Set priority. */
-
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTSTYLE,EINT0_7_STYLE);
-
- /* <3> Install the driver routines in the architecture hooks */
- sysIntLvlVecChkRtn = s3c2410xIntLvlVecChk;
- sysIntLvlVecAckRtn = s3c2410xInitLvVecAck;
- sysIntLvlEnableRtn = s3c2410xIntLvlEnable;
- sysIntLvlDisableRtn = s3c2410xIntLvlDisable;
- /* all sources disabled */
- s3c2410xIntLvlEnabled = 0;
- return OK;
- }
- /*
- * s3c2410xIntLvlVecChk - check for and return any pending interrupts
- *
- * This routine interrogates the hardware to determine the highest priority
- * interrupt pending. It returns the vector associated with that interrupt, and
- * also the interrupt priority level prior to the interrupt (not the
- * level of the interrupt). The current interrupt priority level is then
- * raised to the level of the current interrupt so that only higher priority
- * interrupts will be accepted until this interrupt is finished.
- *
- * The return value ERROR indicates that no pending interrupt was found and
- * that the level and vector values were not returned.
- *
- * RETURNS: OK or ERROR if no interrupt is pending.
- */
- STATUS s3c2410xIntLvlVecChk
- (
- int* pLevel, /* ptr to receive old interrupt level */
- int* pVector /* ptr to receive current interrupt vector */
- )
- {
- UINT32 tempUINT32;
- UINT32 tempUINT32_1;
- UINT32 tempUINT32_2;
- UINT32 irq2 = INT_LVL_ADC;
- volatile unsigned int *p1,*p2,*p3;
- p1 = (volatile unsigned int *)(0x56000050);
- p2 = (volatile unsigned int *)(0x56000058);
- p3 = (volatile unsigned int *)(0x56000054);
- *p1 = 0x55aa;
- *p2 = 0x0;
-
-
- /* Read pending interrupt register and mask undefined bits */
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND, tempUINT32_2);
- /* If no interrupt is pending, return ERROR */
- if((tempUINT32_2 & s3c2410x_INT_CSR_MASK_VAL) == 0)
- {
- return ERROR;
- }
- /* get the number of the pending interrupt */
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTOFFSET, tempUINT32);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, (1<<tempUINT32));
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND, (1<<tempUINT32));
- /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, (1<<5));*/
- /*Ack interrupt for this level.*/
- if((1<<tempUINT32)&((1<<INT_LVL_ADC)|(1<<INT_LVL_UART_0)|(1<<INT_LVL_UART_1)|(1<<INT_LVL_UART_2)))
- {
- /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,s3c2410x_REG_READ(s3c2410x_INT_CSR_INTMSK)|(1<<28));*/
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK, 0x7ff);
- }
-
- if((tempUINT32_2 & (1<<5))||(tempUINT32_2 & (1<<4)))
- {
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_EINTPEND, tempUINT32_1);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND, tempUINT32_1);
-
- if (((tempUINT32_1) == 0)&&(tempUINT32 == 5))
- {
-
- *p3 = 0xFf;
- return ERROR;
- }
- if ((tempUINT32_1 & (~(0xf))) == 0)
- {
- /* *p3 = 0x2f;*/
- return ERROR;
- }
- tempUINT32_2 = tempUINT32_1;
-
- tempUINT32_1 = tempUINT32_1 >> 4;
-
- while (tempUINT32_1 != 0) {
- tempUINT32_1 >>= 1;
- irq2++;
- }
- tempUINT32 = irq2;
- if(tempUINT32 == 37)
- {/*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, (1<<5));*/
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK, s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)|(1<<9));
-
- /**p3 = 0x1f;*/
- }
- else
- {
- /* *p3 = 0x3f;*/
- }
-
-
- }
-
- *pVector = tempUINT32;
- return OK;
- }
- STATUS s3c2410xInitLvVecAck
- (
- int Level, /* ptr to receive old interrupt level */
- int Vector /* ptr to receive current interrupt vector */
- )
- {
- volatile unsigned int *p1,*p2,*p3;
- p1 = (volatile unsigned int *)(0x56000050);
- p2 = (volatile unsigned int *)(0x56000058);
- p3 = (volatile unsigned int *)(0x56000054);
- *p1 = 0x55aa;
- *p2 = 0x0;
- if (Vector == 37)
- {
- *p3 = 0x3f;
- /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,s3c2410x_REG_READ(s3c2410x_INT_CSR_INTMSK)&(~(1<<5)));*/
- /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)&(~(1<<9)));*/
- }
- #if 0
- int key;
- int temp;
- volatile unsigned int *p1,*p2,*p3;
- p1 = (volatile unsigned int *)(0x56000050);
p2 = (volatile unsigned int *)(0x56000058);
p3 = (volatile unsigned int *)(0x56000054);
*p1 = 0x55aa;
*p2 = 0x0;
-
- if(Vector < 0 || Vector >= s3c2410x_INT_NUM_LEVELS)
- {
- *p3 = 0x4F;
- return ERROR;
- }
- /* set bit in enable mask */
- key = intLock();
-
- if (Vector > IRQ_EINT7)
- {
- temp = (Vector - IRQ_EINT4);
- temp = 1<<(temp+4);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
- Vector = INT_LVL_EINT_8_23;
- }
- else if(Vector > INT_LVL_ADC)
- {
- temp = (Vector - IRQ_EINT4);
- temp = 1<<(temp+4);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
- Vector = INT_LVL_EINT_4_7;
- }
-
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, 1<<Vector);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND, 1<<Vector);
- intUnlock(key);
- *p3 = 0x5F;
- return OK;
- #endif
-
-
- }
-
- /*
- * s3c2410xIntLvlEnable - enable a single interrupt level
- *
- * Enable a specific interrupt level. The enabled level will be allowed to
- * generate an interrupt, when the overall interrupt level is set below the
- * specified level. Without being enabled, the interrupt is blocked regardless
- * of the overall interrupt level setting.
- *
- * RETURNS: OK or ERROR if the specified level cannot be enabled.
- */
- STATUS s3c2410xIntLvlEnable
- (
- int level /* level to be enabled */
- )
- {
- int key;
- int temp;
-
- if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;
- /* set bit in enable mask */
- key = intLock();
- /*
- if(level == 37)
- {
- volatile unsigned int *p1,*p2,*p3;
- p1 = (volatile unsigned int *)(0x56000050);
- p2 = (volatile unsigned int *)(0x56000058);
- p3 = (volatile unsigned int *)(0x56000054);
- *p1 = 0x55aa;
- *p2 = 0x0;
- *p3 = 0xef;
- }
- */
- if (level > IRQ_EINT7)
- {
- temp = (level - IRQ_EINT4);
- temp = 1<<(temp+4);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)&(~temp));
- level = INT_LVL_EINT_8_23;
- }
- else if(level > INT_LVL_ADC)
- {
- temp = (level - IRQ_EINT4);
- temp = 1<<(temp+4);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)&(~temp));
- level = INT_LVL_EINT_4_7;
- }
-
- s3c2410xIntLvlEnabled |= (1 << level);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND,1<<level);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND,1<<level);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, ((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
- intUnlock(key);
-
- return OK;
- }
- /*
- * s3c2410xIntLvlDisable - disable a single interrupt level
- *
- * Disable a specific interrupt level. The disabled level is prevented
- * from generating an interrupt even if the overall interrupt level is set
- * below the specified level.
- *
- * RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.
- */
- STATUS s3c2410xIntLvlDisable
- (
- int level /* level to be disabled */
- )
- {
- int key;
- unsigned int temp;
-
- if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;
- /* clear bit in enable mask */
- key = intLock();
-
- if (level > IRQ_EINT7)
- {
- temp = (level - IRQ_EINT4);
- temp = 1<<(temp+4);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)|(temp));
- level = INT_LVL_EINT_8_23;
- }
- else if(level > INT_LVL_ADC)
- {
- temp = (level - IRQ_EINT4);
- temp = 1<<(temp+4);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)|(temp));
- level = INT_LVL_EINT_4_7;
- }
-
- s3c2410xIntLvlEnabled &= ~(1 << level);
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, ((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
- intUnlock(key);
- return OK;
- }