📄 i80312intrctl.c
字号:
else { /* None of above so must be PCI. */#ifdef I80312INT_DEBUG secondary_check = (I80310_PAL_XINT3_EXTND_INT_ISR_RD() & IQ80310_PAL_SINT_MASK); if (secondary_check & IQ80310_PAL_INT_MASK_SPCIA) serialStringOut ("*** INT: SPCIA ***\r\n"); if (secondary_check & IQ80310_PAL_INT_MASK_SPCIB) serialStringOut ("*** INT: SPCIB ***\r\n"); if (secondary_check & IQ80310_PAL_INT_MASK_SPCIC) serialStringOut ("*** INT: SPCIC ***\r\n");#endif while (i80312XInt0to2LvlCurrent < 3 && !i80312XInt0to2LvlEnable[i80312XInt0to2LvlCurrent]) i80312XInt0to2LvlCurrent++; /* Check Next XINT */ /* If none of the XINT0-2 is enabled/or all are called */ if (i80312XInt0to2LvlCurrent >= 3) { i80312XInt0to2LvlCurrent = 0; return ERROR; } isr = 1; newLevel = i80312XInt0to2LvlCurrent * I80312INT_LVL_MULTPLEX; /* Check Next PINT */ i80312XInt0to2LvlCurrent++; } } } /* * newLevel has the interrupt source. Now find out which level has * generated interrupt in that source. May be we can improve the code */ for (localLevel = 0; localLevel < 32 ; localLevel++) { if (isr & 1) break; else isr >>= 1; } /* Calculate the level number from source and local level */ newLevel += localLevel; *pLevel = i80312IntLvlCurrent; i80312IntLvlCurrent = newLevel; /* Switch off all interrupts */ /* Activate the enabled interrupts */ if ((i80312IntLvlCurrent >= I80312INT_LVL_BASE_XINT3) && (i80312IntLvlCurrent <= I80312INT_LVL_MAX_XINT3)) { UINT32 nLevelMask = 0xffffffff; nLevelMask <<= (i80312IntLvlCurrent - I80312INT_LVL_BASE_XINT3); nLevelMask |= i80312XInt3LvlDisabled; I80310_PAL_XINT3_INT_MASK_WR(nLevelMask); } /* fetch, or compute the interrupt vector number */ *pVector = I80312INT_INUM_TO_IVEC(newLevel); preLevel = newLevel; return OK; }/********************************************************************************* i80312IntLvlVecAck - acknowledge the current interrupt** Acknowledge the current interrupt cycle. The level and vector values are* those generated during the i80312IntLvlVecChk() routine for this interrupt* cycle. The basic action is to reset the current interrupt and return* the interrupt level to its previous setting.** RETURNS: OK or ERROR if a hardware fault is detected.* ARGSUSED*/STATUS i80312IntLvlVecAck ( int level, /* old interrupt level to be restored */ int vector /* current interrupt vector, if needed */ ) {#if defined(I80312INT_DEBUG) && defined(I80312INT_XINT3_DEBUG) serialStringOut ("i80312IntLvlVecAck \r\n Level 0x"); serialHexOut (level); serialStringOut ("\r\n Vector 0x"); serialHexOut (vector); serialStringOut ("\r\n");#endif /* restore the previous interrupt level */ i80312IntLvlCurrent = level; /* Activate the enabled interrupts */ if ((i80312IntLvlCurrent >= I80312INT_LVL_BASE_XINT3) && (i80312IntLvlCurrent <= I80312INT_LVL_MAX_XINT3)) { UINT32 nLevelMask = 0xffffffff; nLevelMask <<= (i80312IntLvlCurrent - I80312INT_LVL_BASE_XINT3); nLevelMask |= i80312XInt3LvlDisabled; I80310_PAL_XINT3_INT_MASK_WR(nLevelMask); } return OK; }/********************************************************************************* i80312IntLvlChg - change the interrupt level value** This routine implements the overall interrupt setting. All levels* up to and including the specifed level are disabled. All levels above* the specified level will be enabled, but only if they were specifically* enabled by the i80312IntLvlEnable() routine.** The specific priority level I80312INT_NUM_LEVELS is valid and represents* all levels enabled.** RETURNS: Previous interrupt level.*/int i80312IntLvlChg ( int level /* new interrupt level */ ) { int oldLevel; UINT32 nLevelMask = 0xffffffff; oldLevel = i80312IntLvlCurrent; /* * For XINT3 source, we change the current level. For other we will not * be changing the current level. */ if ((level >= I80312INT_LVL_BASE_XINT3) && (level <= I80312INT_LVL_MAX_XINT3)) { /* change current interrupt level */ i80312IntLvlCurrent = level; } /* Activate the enabled interrupts */ nLevelMask <<= (i80312IntLvlCurrent - I80312INT_LVL_BASE_XINT3); nLevelMask |= i80312XInt3LvlDisabled; I80310_PAL_XINT3_INT_MASK_WR(nLevelMask);#ifdef I80312INT_DEBUG serialStringOut (" IntLvlChg, New PAL IMR 0x"); serialHexOut (nLevelMask); serialStringOut ("\r\n");#endif return oldLevel; }/********************************************************************************* i80312IntLvlEnable - enable a single interrupt level** Enable a specific interrupt level. Since there are no masking registers of* all interrupts in Yavapai, regardless of the current level the interrupt will* be enabled.** RETURNS: OK or ERROR if the specified level cannot be enabled.*/STATUS i80312IntLvlEnable ( int level /* level to be enabled */ ) {#ifdef I80312INT_DEBUG serialStringOut ("i80312IntLvlEnable: Enabling Level 0x"); serialHexOut (level); serialStringOut ("\r\n");#endif if ((level >= I80312INT_LVL_BASE_XINT0) && (level <= I80312INT_LVL_MAX_XINT2)) { UINT32 nIndex = level / I80312INT_LVL_MULTPLEX; level %= I80312INT_LVL_MULTPLEX; i80312XInt0to2LvlEnable[nIndex] |= (1 << level); return OK; } /* Only XINT3 interrupts can Masked/Unmasked */ if ((level < I80312INT_LVL_BASE_XINT3) || (level > I80312INT_LVL_MAX_XINT3)) return ERROR; level -= I80312INT_LVL_BASE_XINT3; i80312XInt3LvlDisabled &= ~(1 << level); i80312IntLvlChg (-1);#ifdef I80312INT_DEBUG serialStringOut (" Current Mask 0x"); serialHexOut (i80312XInt3LvlDisabled); serialStringOut ("\r\n");#endif return OK; }/********************************************************************************* i80312IntLvlDisable - 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 i80312IntLvlDisable ( int level /* level to be disabled */ ) { /* Only XINT3 interrupts can Masked/Unmasked */#ifdef I80312INT_DEBUG serialStringOut ("i80312IntLvlDisable: Disabling Level 0x"); serialHexOut (level); serialStringOut ("\r\n");#endif if ((level >= I80312INT_LVL_BASE_XINT0) && (level <= I80312INT_LVL_MAX_XINT2)) { UINT32 nIndex = level / I80312INT_LVL_MULTPLEX; level %= I80312INT_LVL_MULTPLEX; i80312XInt0to2LvlEnable[nIndex] &= ~(1 << level); return OK; } if ((level < I80312INT_LVL_BASE_XINT3) || (level > I80312INT_LVL_MAX_XINT3)) return ERROR; level -= I80312INT_LVL_BASE_XINT3; /* Find XIN3 local level */ i80312XInt3LvlDisabled |= (1 << level); i80312IntLvlChg (-1); /* set the interrupt mask */#ifdef I80312INT_DEBUG serialStringOut (" Current Mask 0x"); serialHexOut (i80312XInt3LvlDisabled); serialStringOut ("\r\n");#endif return OK; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -