📄 sl82565intrctl.c
字号:
UCHAR intVec; /* Initialize the interrupt table */ for (vector = 0; vector < 256; vector++) sysIntTbl[vector] = NULL; /* Connect the interrupt demultiplexer to the PowerPC external interrupt */ excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, sysIbcIntHandler); /* Set up the BSP specific routines */ _func_intConnectRtn = sysIbcIntConnect; _func_intEnableRtn = sysIbcIntEnable; _func_intDisableRtn = sysIbcIntDisable; /* Initialize the Interrupt Controller #1 */ IBC_BYTE_OUT (PIC_port1 (PIC1_BASE_ADR),0x11); /* ICW1 */ IBC_BYTE_OUT (PIC_port2 (PIC1_BASE_ADR),sysVectorIRQ0); /* ICW2 */ IBC_BYTE_OUT (PIC_port2 (PIC1_BASE_ADR),0x04); /* ICW3 */ IBC_BYTE_OUT (PIC_port2 (PIC1_BASE_ADR),0x01); /* ICW4 */ /* * Mask interrupts IRQ 0, 1, and 3-7 by writing to OCW1 register * IRQ 2 is the cascade input */ IBC_BYTE_OUT (PIC_IMASK (PIC1_BASE_ADR),0xfb); /* Make IRQ 5 level sensitive */ IBC_BYTE_OUT (SL82565_INT1_ELC, 0x20); /* Initialize the Interrupt Controller #2 */ IBC_BYTE_OUT (PIC_port1 (PIC2_BASE_ADR),0x11); /* ICW1 */ IBC_BYTE_OUT (PIC_port2 (PIC2_BASE_ADR),sysVectorIRQ0+8); /* ICW2 */ IBC_BYTE_OUT (PIC_port2 (PIC2_BASE_ADR),0x02); /* ICW3 */ IBC_BYTE_OUT (PIC_port2 (PIC2_BASE_ADR),0x01); /* ICW4 */ /* Mask interrupts IRQ 8-15 by writing to OCW1 register */ IBC_BYTE_OUT (PIC_IMASK (PIC2_BASE_ADR),0xff); /* Make IRQ 15, 14, 11, 10, and 9 level sensitive */ IBC_BYTE_OUT (SL82565_INT2_ELC, 0x80 | 0x40 | 0x08 | 0x04 | 0x02); /* Permanently turn off ISA refresh by never completing init steps */ IBC_BYTE_OUT (SL82565_TMR1_CMOD, 0x74); /* Perform the PCI Interrupt Ack cycle */ IBC_BYTE_IN (RAVEN_BASE_ADRS + 0x30, &intVec); /* Perform the end of interrupt procedure */ sysIbcEndOfInt (15); sysIbcIntLevelSet (16); return (OK); }/********************************************************************************* sysIbcIntEnable - enable a IBC interrupt level** This routine enables a specified IBC interrupt level.** RETURNS: OK.** ARGSUSED0*/LOCAL int sysIbcIntEnable ( int intNum /* interrupt level to enable */ ) { if (intNum < 8) { sysPicMask1 &= ~(1 << intNum); IBC_BYTE_OUT (PIC_IMASK (PIC1_BASE_ADR), sysPicMask1 | sysPicLevel1); } else { sysPicMask2 &= ~(1 << (intNum - 8)); IBC_BYTE_OUT (PIC_IMASK (PIC2_BASE_ADR), sysPicMask2 | sysPicLevel2); } return (OK); }/********************************************************************************* sysIbcIntDisable - disable a IBC interrupt level** This routine disables a specified IBC interrupt level.** RETURNS: OK.** ARGSUSED0*/LOCAL int sysIbcIntDisable ( int intNum /* interrupt level to disable */ ) { if (intNum < 8) { sysPicMask1 |= (1 << intNum); IBC_BYTE_OUT (PIC_IMASK (PIC1_BASE_ADR), sysPicMask1 | sysPicLevel1 ); } else { sysPicMask2 |= (1 << (intNum - 8)); IBC_BYTE_OUT (PIC_IMASK (PIC2_BASE_ADR), sysPicMask2 | sysPicLevel2); } return (OK); }/******************************************************************************** sysIbcIntConnect - connect an interrupt handler to the system vector table** This function connects an interrupt handler to the system vector table.** RETURNS: OK or ERROR.*/LOCAL STATUS sysIbcIntConnect ( 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 */ newHandler = malloc (sizeof (INT_HANDLER_DESC)); /* check if the memory allocation succeed */ if (newHandler == 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); }/******************************************************************************** sysIbcIntHandler - sl82565 IBC interrupt handler** This routine is called to service interrupts generated by the sl82565 ISA* Bridge Controller (IBC).** RETURNS: N/A*/void sysIbcIntHandler (void) { UCHAR intNum; INT_HANDLER_DESC * currHandler; int dontCare; int oldLevel; /* Perform the PCI Interrupt Ack cycle */ IBC_BYTE_IN (RAVEN_BASE_ADRS + 0x30, &intNum);#ifdef INCLUDE_WINDVIEW WV_EVT_INT_ENT(intNum)#endif /* Save current level, reset pic masks to the new interrupt level */ oldLevel = sysPicLevelCur; sysIbcIntLevelSet (intNum); /* Re-arm (enable) the interrupt chip */ sysIbcEndOfInt (intNum); /* Allow external interrupts to the CPU. */ CPU_INT_UNLOCK (_PPC_MSR_EE); if ((currHandler = sysIntTbl [intNum]) == NULL) { logMsg ("uninitialized interrupt level %d\n", intNum, 0,0,0,0,0); } else { /* Call EACH respective 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); /* Restore original interrupt level */ sysIbcIntLevelSet (oldLevel); }/********************************************************************************* sysIbcEndOfInt - send EOI(end of interrupt) signal.** This routine is called at the end of the interrupt handler to* send a non-specific end of interrupt (EOI) signal.** The second PIC is acked only if the interrupt came from that PIC.* The first PIC is always acked.*/LOCAL void sysIbcEndOfInt ( int intNum ) { if (intNum > 7) { IBC_BYTE_OUT (PIC_IACK (PIC2_BASE_ADR), 0x20); } IBC_BYTE_OUT (PIC_IACK (PIC1_BASE_ADR), 0x20); }/********************************************************************************* sysIbcIntLevelSet - set the interrupt priority level** This routine masks interrupts with real priority equal to or lower than* <intNum>. The special* value 16 indicates all interrupts are enabled. Individual interrupt* numbers have to be specifically enabled by sysIbcIntEnable() before they* are ever enabled by setting the interrupt level value.** Note because of the IBM cascade scheme, the actual priority order for* interrupt numbers is (high to low) 0, 1, 8, 9, 10, 11, 12, 13, 14, 15,* 3, 4, 5, 6, 7, 16 (all enabled)** INTERNAL: It is possible that we need to determine if we are raising* or lowering our priority level. It may be that the order of loading the* two mask registers is dependent upon raising or lowering the priority.** RETURNS: N/A*/void sysIbcIntLevelSet ( int intNum /* interrupt level to implement */ ) { if (intNum > 16) intNum = 16; sysPicLevelCur = intNum; if (sysPicLevel2 != sysPicPriMask2[intNum]) { sysPicLevel2 = sysPicPriMask2[intNum]; IBC_BYTE_OUT (PIC_IMASK (PIC2_BASE_ADR), sysPicMask2 | sysPicLevel2); } if (sysPicLevel1 != sysPicPriMask1[intNum]) { sysPicLevel1 = sysPicPriMask1[intNum]; IBC_BYTE_OUT (PIC_IMASK (PIC1_BASE_ADR), sysPicMask1 | sysPicLevel1); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -