?? universe.c
字號(hào):
univVecNum = UNIV_MBOX3_INT_VEC; break; case UNIVERSE_LM1_INT: univVecNum = UNIV_LM1_INT_VEC; break; case UNIVERSE_LM2_INT: univVecNum = UNIV_LM2_INT_VEC; break; case UNIVERSE_LM3_INT: univVecNum = UNIV_LM3_INT_VEC; break; default: /* doesn't match one of the intr. types, so return an error */ return(ERROR); } /* install the handler in the vector table */ if (intConnect (INUM_TO_IVEC(univVecNum), routine, parameter) == ERROR) return(ERROR); return (OK); }/********************************************************************************* sysMailboxInt - mailbox interrupt handler** This routine calls the installed mailbox routine, if it exists.*/LOCAL void sysMailboxInt (void) { if (sysMailboxRoutine != NULL) sysMailboxRoutine (sysMailboxArg); }/********************************************************************************* sysMailboxConnect - connect a routine to the mailbox interrupt** This routine specifies the interrupt service routine to be called at each* mailbox interrupt.** NOTE: The mailbox interrupt is the Location Monitor 0 interrupt on the* UNIVERSE II chip.** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), sysMailboxEnable()*/STATUS sysMailboxConnect ( FUNCPTR routine, /* routine called at each mailbox interrupt */ int arg /* argument with which to call routine */ ) { static BOOL sysMailboxConnected = FALSE; if (!sysMailboxConnected && intConnect (INUM_TO_IVEC (UNIV_LM0_INT_VEC), sysMailboxInt, 0) == ERROR) { return (ERROR); } sysMailboxConnected = TRUE; sysMailboxRoutine = routine; sysMailboxArg = arg; return (OK); }/********************************************************************************* sysMailboxEnable - enable the mailbox interrupt** This routine enables the mailbox interrupt.** NOTE: The mailbox interrupt is the Location Monitor 0 interrupt on the* UNIVERSE II chip.** RETURNS: OK, if mailbox interrupt becomes enabled, else ERROR.** SEE ALSO: sysMailboxConnect(), sysMailboxDisable()*/STATUS sysMailboxEnable ( char *mailboxAdrs /* address of mailbox (ignored) */ ) { /* enable the location monitor 0 interrupt */ if (sysUnivIntEnable(UNIVERSE_LM0_INT) == OK) return (OK); else return (ERROR); }/********************************************************************************* sysMailboxDisable - disable the mailbox interrupt** This routine disables the mailbox interrupt.** NOTE: The mailbox interrupt is the Location Monitor 0 interrupt on the* UNIVERSE II chip.** RETURNS: OK, if the mailbox interrupt gets disabled, else ERROR** SEE ALSO: sysMailboxConnect(), sysMailboxEnable()*/STATUS sysMailboxDisable ( char *mailboxAdrs /* address of mailbox (ignored) */ ) { /* disable the mailbox interrupt */ if (sysUnivIntDisable(UNIVERSE_LM0_INT) == OK) return (OK); else return (ERROR); }/********************************************************************************* sysUnivVERRClr - Universe VMEbus Error Clear routine** This is the VMEbus Error clear routine for the Tundra Universe PCI to VME* Bridge. It counts the ocuurances at the specified counter and clears the* error condition in the three registers associated with VME Bus Errors:* LINT_STAT, VINT_STAT, and V_AMERR.** RETURNS: N/A*/void sysUnivVERRClr (void) { UINT32 status; /* Count occurances */ ++sysUnivVERRCnt; /* Get current address error status */ UNIV_IN_LONG(UNIVERSE_V_AMERR, &status); /* Clear any error */ status &= V_AMERR_V_STAT; UNIV_OUT_LONG(UNIVERSE_V_AMERR, status); /* Get current VME error status */ UNIV_IN_LONG(UNIVERSE_VINT_STAT, &status); /* Clear any error */ status &= VINT_STAT_VERR; UNIV_OUT_LONG(UNIVERSE_VINT_STAT, status); /* Get current PCI error status */ UNIV_IN_LONG(UNIVERSE_LINT_STAT, &status); /* Clear any error */ status &= LINT_STAT_VERR; UNIV_OUT_LONG(UNIVERSE_LINT_STAT, status); /* Force write due to Write-Posting and get updated status */ UNIV_IN_LONG(UNIVERSE_PCI_CSR, &status); }/********************************************************************************* sysUnivLevelDecode - decode highest pending priority Universe interrupt** This routine decodes the highest pending priority Universe interrupt from a* bit field of interrupts and returns the associated interrupt vector, priority* level and priority level bit mask.** RETURNS: highest pending interrupt priority level bit mask** SEE ALSO: register and bit field defs in universe.h*/int sysUnivLevelDecode ( int bitField, /* one interrupt per bit, up to 23 bits */ int * vecNum, /* where to return associated vector */ int * intLvl /* where to return associated Universe int level */ ) { int bitLvlMsk; int i; int vector; /* Compare bits in order of highest priority first */ for (i = UNIV_NUM_INT; i >= 0; --i) { if (bitField & univIntTable[i].bitMask) break; } /* Determine and return interrupt vector, priority level and level mask */ bitLvlMsk = univIntTable[i].bitMask; if (univIntTable[i].vector != -1) *vecNum = univIntTable[i].vector; else { switch (bitLvlMsk) { case LVL7: UNIV_IN_LONG(UNIVERSE_V7_STATID, &vector); break; case LVL6: UNIV_IN_LONG(UNIVERSE_V6_STATID, &vector); break; case LVL5: UNIV_IN_LONG(UNIVERSE_V5_STATID, &vector); break; case LVL4: UNIV_IN_LONG(UNIVERSE_V4_STATID, &vector); break; case LVL3: UNIV_IN_LONG(UNIVERSE_V3_STATID, &vector); break; case LVL2: UNIV_IN_LONG(UNIVERSE_V2_STATID, &vector); break; case LVL1: UNIV_IN_LONG(UNIVERSE_V1_STATID, &vector); break; } /* * Check for errors * At this point, if a VME bus error has occured, it must be * cleared by the sysUnivVERRClr() routine and the vector discarded. * The vector returned during a VME bus error is bogus. */ if ((vector & V1_STATID_ERR) != 0) { /* Clear VME bus error */ sysUnivVERRClr (); /* Discard bad vector */ *vecNum = 0; } else *vecNum = vector & 0xFF; /* only eight bits of useful info */ } *intLvl = i; return (bitLvlMsk); }/********************************************************************************* sysUnivVmeIntr - VMEbus interrupt handler** This is the VMEbus interrupt handler for the Motorola PCI Host* Bridge (PHB) and Embedded Processor Interrupt Controller (EPIC). It is* connected to the single VMEbus interrupt from the EPIC and examines the* Universe chip to determine the interrupt level and vector of the* interrupt source. Having obtained the vector number, this routine then* indexes into the system vector table, calling the specified interrupt* handler routine.** RETURNS: N/A*/void sysUnivVmeIntr (void) { int pendingIntr; int highestIntr; int prevIntLvl; int univIntLvl; int vec_num = 0; INT_HANDLER_DESC * currHandler; /* get pending interrupt level(s) */ UNIV_IN_LONG(UNIVERSE_LINT_STAT, &pendingIntr); pendingIntr &= LINT_STAT_INT_MASK; pendingIntr &= sysUnivIntsEnabled; /* * Handle pending interrupts in order of highest priority. * * For each interrupt, determine the level, get vector associated * with the interrupt, set the appropriate interrupt level, clear the * interrupt in the Universe, and dispatch to all associated ISRs. */ if (pendingIntr != 0) { /* Determine highest interrupt priority level and vector */ highestIntr = sysUnivLevelDecode (pendingIntr, &vec_num, &univIntLvl); /* Set intr level: mask out all ints at and below this level */ prevIntLvl = sysUnivIntLevelSet (univIntLvl); vec_num &= 0xff; if (vec_num == 0) { logMsg ("bad vme interrupt %d\n", vec_num, 0,0,0,0,0); } else if ((currHandler = sysIntTbl[vec_num]) == NULL) logMsg ("uninitialized vme interrupt %d\n", vec_num, 0,0,0,0,0); else { while (currHandler != NULL) { currHandler->vec (currHandler->arg); currHandler = currHandler->next; } } /* Clear interrupt request in Universe */ UNIV_OUT_LONG(UNIVERSE_LINT_STAT, highestIntr); /* restore previous interrupt level */ (void)sysUnivIntLevelSet (prevIntLvl); } return; }/******************************************************************************** sysBusRmwEnable - enable Read-Modify-Write (RMW) cycle on VMEbus** NOTE: These parameters are written to the SCG as Big-Endian values.* This is probably a bug because all other registers in the* Universe are Little-Endian.** RETURNS: N/A*/void sysBusRmwEnable ( UINT swapCompareEnable, /* Enabled bits involved in compare and swap */ UINT compareData, /* Data to compare with read portion of RMW */ UINT swapData, /* Data to write during write portion of RMW */ char * rmwAddress /* RMW address */ ) { *UNIVERSE_SCYC_EN = swapCompareEnable; *UNIVERSE_SCYC_CMP = compareData; *UNIVERSE_SCYC_SWP = swapData; /* Convert RMW address to a PCI address */#ifdef CHRP_ADRS_MAP UNIV_OUT_LONG(UNIVERSE_SCYC_ADDR, (UINT)rmwAddress);#else /* psuedo-PReP Mapping */ UNIV_OUT_LONG(UNIVERSE_SCYC_ADDR, (UINT)((UINT)rmwAddress + (UINT)(ISA_MSTR_IO_LOCAL << 16)));#endif /* CHRP_ADRS_MAP */ /* Configure Special Cycle Generator to generate a RMW cycle */ UNIV_OUT_LONG(UNIVERSE_SCYC_CTL, SCYC_CTL_RMW); }/******************************************************************************** sysBusRmwDisable - Disable Read-Modify-Write (RMW) cycle on the VMEbus.** Disable Read-Modify-Write (RMW) cycle on the VMEbus.** RETURNS: N/A*/void sysBusRmwDisable () { UNIV_OUT_LONG(UNIVERSE_SCYC_CTL, SCYC_CTL_DISABLE); }#ifdef INCLUDE_VME_DMA/* * The following routines whose names start with "sysVmeDma" * comprise the DMA driver. *//******************************************************************************** sysVmeDmaInit - Inititalize the Universe's DMA engine** This routine will initialize the Universe's DMA engine. This involves* using the following #defines listed in config.h as defaults to configure* the appropriate fields in the DMA's DCTL and DGCS registers.* .CS* VME_DMA_XFER_TYPE* VME_DMA_ADDR_SPACE* VME_DMA_DATA_TYPE* VME_DMA_USER_TYPE* .CE* The DMA engine will also be permanently configured so that the PCI Bus* will perform 64-bit transactions.
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -