📄 sysmpic.c
字号:
/* 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; } /* * if the connect is for an MPIC interrupt, * then store the vector into the appropriate MPIC vector register */ connect.regAddr = getMpicVecOffset( (int)vector ); if ( connect.regAddr > 0 ) { /* read the vector register */ MPIC_READ(connect.regAddr, connect.regVal); /* store the interrupt vector number */ connect.regVal |= (int)vector; /* write the contents of the vector register back */ MPIC_WRITE(connect.regAddr, connect.regVal); } return (OK); } /********************************************************************************* sysMpicIntEnable - enable an Mpic interrupt level** This routine enables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported*/ LOCAL int sysMpicIntEnable ( int intLevel /* interrupt level to enable */ ) { LOCAL_INT_DATA enable; /* * if the int. level is not for ISA or MPIC, then it is not supported. * If not supported, just return. */ if ((intLevel < 0) || (intLevel > INTERNAL_INTERRUPT_BASE)) return (ERROR); /* If ISA interrupt level,call the IBC driver enable routine, */ if ( intLevel < EXT_INTERRUPT_BASE ) return (ERROR); enable.regAddr = getMpicVecOffset( intLevel ); if ( enable.regAddr > 0 ) { /* read the vector register */ MPIC_READ(enable.regAddr, enable.regVal); /* enable the interrupt */ enable.regVal &= ~(INT_MASK_BIT); /* write the contents of the vector register back */ MPIC_WRITE(enable.regAddr, enable.regVal); } return (OK); }/********************************************************************************* sysMpicIntDisable - disable an Mpic interrupt level** This routine disables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported*/ LOCAL int sysMpicIntDisable ( int intLevel /* interrupt level to disable */ ) { LOCAL_INT_DATA disable; /* * if the int. level is not for ISA or MPIC, then it is not supported. * If not supported, just return. */ if ((intLevel < 0) || (intLevel > INTERNAL_INTERRUPT_BASE)) return (ERROR); /* If ISA interrupt level, call the IBC driver disable routine, */ if (intLevel < EXT_INTERRUPT_BASE) return (ERROR); /* else, it is an MPIC interrupt level */ else { /* get the vector reg. offset value */ disable.regAddr = getMpicVecOffset(intLevel); if (disable.regAddr > 0) { /* read the vector register */ MPIC_READ(disable.regAddr, disable.regVal); /* disable the interrupt */ disable.regVal |= INT_MASK_BIT; /* write the contents of the vector register back */ MPIC_WRITE(disable.regAddr, disable.regVal); } } return (OK); }/******************************************************************************** sysMpicIntHandler - handle an interrupt received at the Mpic* * This routine will process interrupts received from PCI or ISA devices as* these interrupts arrive via the MPIC. This routine supports MPIC interrupt* nesting.** RETURNS: N/A*/void sysMpicIntHandler (void) { INT_HANDLER_DESC * currHandler; UINT32 vecNum = 0xFF; int dontCare; /* get the vector from the MPIC IACK reg. */ MPIC_READ (MPIC_CPU0_IACK_REG, vecNum); vecNum &= VECTOR_MASK; /* Ignore spurious interrupts */ if (vecNum == 0xFF) { logMsg ("MPIC Spurious Interrupt!\n", 0,0,0,0,0,0); return; } /* * 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);#ifdef INCLUDE_WINDVIEW WV_EVT_INT_ENT(vecNum)#endif /* call the necessary interrupt handlers */ if ((currHandler = sysIntTbl [vecNum]) == NULL) { logMsg ("uninitialized MPIC 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; } } CPU_INT_LOCK (&dontCare); /* issue an end-of-interrupt to the MPIC */ MPIC_EOI; return; }/********************************************************************************* sysMpicBusIntGen - generate an out-bound PCI bus interrupt using the MPIC** This routine generates an out-bound PCI interrupt using the CPU1 section of* the MPIC Inter-Processor Interrupt (IPI) mechanism. The board hardware* routes the CPU1 interrupt line to the PCU bus to permit this use.** RETURNS: OK or ERROR if interrupt vector not supported*/ int sysMpicBusIntGen ( int level, /* interrupt level to generate (not used) */ int vector /* interrupt vector for interrupt */ ) { /* Validate the vector number. */ if (vector != SM_BUS_INT_VEC) return (ERROR); /* Set the trigger bit in the proper IPI dispatch register. */ MPIC_WRITE( SM_BUS_INT_TRIGGER_OFFSET, (1 << SM_BUS_INT_BIT) ); return (OK); }/********************************************************************************* getMpicVecOffset - get the vector offset value of an MPIC register ** This routine calculates the appropriate MPIC register offset based on the* specified MPIC interrupt level.** RETURNS: MPIC register offset or zero if not a supported level.*/ LOCAL int getMpicVecOffset ( int intLevel ) { int offset = 0; /* check for external interrupt level */ for (;;) { if ((intLevel >= EXT_INTERRUPT_BASE) && (intLevel < TIMER_INTERRUPT_BASE)) { offset = intLevel - EXT_INTERRUPT_BASE; offset = MPIC_EXT_SRC0_VEC_PRI_REG + ( offset * REG_OFFSET * 2 ); break; } /* check for a timer interrupt level */ if ((intLevel >= TIMER_INTERRUPT_BASE) && (intLevel < IPI_INTERRUPT_BASE)) { offset = intLevel - TIMER_INTERRUPT_BASE; offset = MPIC_TIMER0_VEC_PRI_REG + ( offset * REG_OFFSET * 4 ); break; } /* check for an IPI interrupt level */ if ((intLevel >= IPI_INTERRUPT_BASE) && (intLevel < INTERNAL_INTERRUPT_BASE)) { offset = intLevel - IPI_INTERRUPT_BASE; offset = MPIC_IPI0_VEC_PRI_REG + ( offset * REG_OFFSET ); break; } /* check for the MPIC internal error interrupt */ if ((intLevel >= INTERNAL_INTERRUPT_BASE ) && (intLevel < (INTERNAL_INTERRUPT_BASE + 2))) { offset = intLevel - INTERNAL_INTERRUPT_BASE; offset = MPIC_FUNC_VEC_PRI_REG + ( offset * REG_OFFSET ); break; } break; } return (offset); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -