📄 syslib.c
字号:
/* Disable Machine Check Exceptions */ vxMsrSet(ppcMsr); /* Disable Machine Check Pin (EMCP) */ vxHid0Set(ppcHid0); /* restore original vectors and unlock */ excVecSet ((FUNCPTR *) _EXC_OFF_DATA, oldVec2); excVecSet ((FUNCPTR *) _EXC_OFF_MACH, oldVec1); intUnlock (oldLevel); return (status); }/******************************************************************************** sysProbeErrClr - clear errors associated with probing an address on a bus.** This routine clears the error flags and conditions in the DAR, DSISR, SRR0* and SRR1 PowerPC registers arising from probing addresses.** RETURNS: N/A*/void sysProbeErrClr (void) { /* Clear PowerPC Data Access Exception Registers */ vxDarSet (0); vxDsisrSet (0); vxSrr0Set (0); vxSrr1Set (0); }/******************************************************************************** sysPciProbe - probe a PCI bus address** This routine probes an address on the PCI bus. The PCI bridge chip* must have a special setup to enable generation of Master Abort cycles on* write probes and reception of Target Abort cycles on read probes.* The CPU must be configured to enable Machine Check exceptions. * All probing is done with interrupts disabled.** RETURNS: OK or ERROR if address cannot be probed*/STATUS sysPciProbe ( char * adrs, /* address to be probed */ int mode, /* VX_READ or VX_WRITE */ int length, /* 1, 2 or 4 byte probe */ char * pVal /* address of value to write OR */ /* address of location to place value read */ ) { STATUS status = ERROR; /* Perform probe */ status = sysMemProbeBus (adrs, mode, length, pVal); return (status); }/******************************************************************************** sysBusProbe - probe a bus address based on bus type.** This routine is a function hook into vxMemProbe. It determines which bus,* PCI or local is being probed based on the address to be probed.* If the PCI bus is being probed, the sysPciProbe()* routine is called to do the special PCI probing. If the local bus is being* probed, the routine returns ERROR which indicates that the default local* bus probe in vxMemProbe() should be used.** RETURNS: ERROR if local bus is being probed, OK if PCI bus.*/STATUS sysBusProbe ( char * adrs, /* address to be probed */ int mode, /* VX_READ or VX_WRITE */ int length, /* 1, 2 or 4 byte probe */ char * pVal /* address of value to write OR */ /* address of location to place value read */ ) { STATUS status; /* Clear any existing errors/exceptions */ sysProbeErrClr (); if (IS_PCI_ADDRESS(adrs)) status = sysPciProbe (adrs, mode, length, pVal); /* Handle local bus in architecture-specific manner */ else status = vxMemArchProbe (adrs, mode, length, pVal); /* Clear any errors/exceptions before exiting */ sysProbeErrClr (); return (status); }/******************************************************************************** sysUsDelay - delay at least the specified amount of time (in microseconds)** This routine will delay for at least the specified amount of time using the* lower 32 bit "word" of the Time Base register as the timer. The accuracy of* the delay increases as the requested delay increases due to a certain amount* of overhead. As an example, a requested delay of 10 microseconds is* accurate within approximately twenty percent, and a requested delay of 100* microseconds is accurate within approximately two percent.** NOTE: This routine will not relinquish the CPU; it is meant to perform a* busy loop delay. The minimum delay that this routine will provide is* approximately 10 microseconds. The maximum delay is approximately the* size of UINT32; however, there is no roll-over compensation for the total* delay time, so it is necessary to back off two times the system tick rate* from the maximum.** RETURNS: N/A*/void sysUsDelay ( UINT32 delay /* length of time in microsec to delay */ ) { register UINT baselineTickCount; register UINT curTickCount; register UINT terminalTickCount; register int actualRollover = 0; register int calcRollover = 0; UINT ticksToWait; UINT requestedDelay; UINT oneUsDelay; /* Exit if no delay count */ if ((requestedDelay = delay) == 0) return; /* * Get the Time Base Lower register tick count, this will be used * as the baseline. */ baselineTickCount = sysTimeBaseLGet(); /* * Calculate number of ticks equal to 1 microsecond * * The Time Base register and the Decrementer count at the same rate: * once per 4 System Bus cycles. * * e.g., 66666666 cycles 1 tick 1 second 16 tick * --------------- * ------ * -------- = ---------- * second 4 cycles 1000000 microsec microsec */ oneUsDelay = ((DEC_CLOCK_FREQ / 4) / 1000000); /* Convert delay time into ticks */ ticksToWait = requestedDelay * oneUsDelay; /* Compute when to stop */ terminalTickCount = baselineTickCount + ticksToWait; /* Check for expected rollover */ if (terminalTickCount < baselineTickCount) { calcRollover = 1; } do { /* * Get current Time Base Lower register count. * The Time Base counts UP from 0 to * all F's. */ curTickCount = sysTimeBaseLGet(); /* Check for actual rollover */ if (curTickCount < baselineTickCount) { actualRollover = 1; } if (((curTickCount >= terminalTickCount) && (actualRollover == calcRollover)) || ((curTickCount < terminalTickCount) && (actualRollover > calcRollover))) { /* Delay time met */ break; } } while (TRUE); /* Breaks when delay time is met */ }/******************************************************************************** sysDebugMsg - print a debug string to the console in polled mode.** This routine prints a message to the system console in polled mode and* optionally exits to the monitor.** RETURNS: N/A**/void sysDebugMsg ( char * str, UINT32 recovery ) { int msgSize; int msgIx; SIO_CHAN * pSioChan; /* serial I/O channel */ msgSize = strlen (str); sysSerialHwInit (); pSioChan = sysSerialChanGet (0); sioIoctl (pSioChan, SIO_MODE_SET, (void *) SIO_MODE_POLL); for (msgIx = 0; msgIx < msgSize; msgIx++) { while (sioPollOutput (pSioChan, str[msgIx]) == EAGAIN); } /* follow caller's error recovery policy. */#ifdef DEBUGMSG_RECOVERY if (recovery == EXIT_TO_SYSTEM_MONITOR) sysToMonitor (BOOT_NO_AUTOBOOT);#endif }/******************************************************************************* sysInWordString - reads a string of words from an io address.** This function reads a word string from a specified io address.** RETURNS: N/A*/void sysInWordString ( ULONG ioAddr, UINT16 * bufPtr, int nWords ) { int loopCtr; for (loopCtr = 0; loopCtr < nWords; loopCtr++) *bufPtr++ = *(short *)ioAddr; }/******************************************************************************* sysInWordStringRev - reads a string of words that are byte reversed** This function reads a string of words that are byte reversed from a* specified io address.** RETURNS: N/A*/void sysInWordStringRev ( ULONG ioAddr, UINT16 * bufPtr, int nWords ) { int loopCtr; for (loopCtr = 0; loopCtr < nWords; loopCtr++) *bufPtr++ = PCI_IN_WORD(ioAddr); }/******************************************************************************* sysOutWordString - writes a string of words to an io address.** This function writes a word string from a specified io address.** RETURNS: N/A*/void sysOutWordString ( ULONG ioAddr, UINT16 * bufPtr, int nWords ) { int loopCtr; for (loopCtr = 0; loopCtr < nWords; loopCtr++) *(short *)ioAddr = *bufPtr++; SYNC; }/******************************************************************************* sysInLongString - reads a string of longwords from an io address.** This function reads a longword string from a specified io address.** RETURNS: N/A*/void sysInLongString ( ULONG ioAddr, ULONG * bufPtr, int nLongs ) { int loopCtr; for (loopCtr = 0; loopCtr < nLongs; loopCtr++) *bufPtr++ = *(int *)ioAddr; }/******************************************************************************* sysOutLongString - writes a string of longwords to an io address.** This function writes a longword string from a specified io address.** RETURNS: N/A*/void sysOutLongString ( ULONG ioAddr, ULONG * bufPtr, int nLongs ) { int loopCtr; for (loopCtr = 0; loopCtr < nLongs; loopCtr++) *(int *)ioAddr = *bufPtr++; SYNC; }/******************************************************************************** sysAtuInit - initialize ATU** This function's purpose is to initialize the address translation* unit for use by the operating system.** RETURNS: Ok always*/STATUS sysAtuInit (void) { UINT32 value32; UINT16 value16; /* * initialize the inbound translation window and enable it, * the inbound translation window permits PCI bus masters to access * system memory, the enable is nothing more than enabling PCI memory * accesses in host's bridge PCI command configuration register */ sysPciOutLong( (UINT32)MPC107_ATU_ITWR, 0 ); pciConfigInLong (CNFG_PCI_HOST_BRDG_BUS, CNFG_PCI_HOST_BRDG_DEV, CNFG_PCI_HOST_BRDG_FCN, MPC107_CFG_LMBAR, &value32); value32 = (value32 & 0x00000FFF) | LOCAL_MEM_LOCAL_ADRS; pciConfigOutLong (CNFG_PCI_HOST_BRDG_BUS, CNFG_PCI_HOST_BRDG_DEV, CNFG_PCI_HOST_BRDG_FCN, MPC107_CFG_LMBAR, value32); pciConfigInWord (CNFG_PCI_HOST_BRDG_BUS, CNFG_PCI_HOST_BRDG_DEV, CNFG_PCI_HOST_BRDG_FCN, MPC107_CFG_COMMAND, &value16); value16 |= 0x0002; pciConfigOutWord (CNFG_PCI_HOST_BRDG_BUS, CNFG_PCI_HOST_BRDG_DEV, CNFG_PCI_HOST_BRDG_FCN, MPC107_CFG_COMMAND, value16); return (OK); }/******************************************************************************* vmxExcLoad - Loads exception code for VMX Exceptions.** This function copies the exception code located at address 0x100 and copies* it to offsets 0xf20 and 0x1600 for VMX Unavailable and VMX Assist,* respectively. These are to cover new support required for the MPC7400* (Max) processor.** The purpose of this is to make sure that vxWorks continues to run in case* an exception occurs on either of these new sources. This will be removed* when vxWorks arch/ppc support is upgraded to fully support the MPC7400.** RETURNS: N/A*/void vmxExcLoad (void) { bcopy ((char*) (LOCAL_MEM_LOCAL_ADRS + 0x0100), (char*) (LOCAL_MEM_LOCAL_ADRS + _EXC_VMX_UNAVAIL), SIZEOF_EXCEPTION); bcopy ((char*) (LOCAL_MEM_LOCAL_ADRS + 0x0100), (char*) (LOCAL_MEM_LOCAL_ADRS + _EXC_VMX_ASSIST), SIZEOF_EXCEPTION); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -