📄 syslib_765.c
字号:
* sysDelay - delay for approximately one millisecond** Delay for approximately one milli-second.** RETURNS: N/A*/void sysDelay (void) { sysUsDelay (1000); }/******************************************************************************** sysMemProbeTrap - trap handler for vxMemProbe exception** This routine is called from the excConnectCode stub if sysMemProbeSup* generates an exception. This code simply increments a static variable each* time an exception is generated and advances to the next instruction.*/LOCAL int sysMemProbeTrap ( ESFPPC * pEsf /* pointer to exception stack frame */ ) { REG_SET *pRegSet = &pEsf->regSet; pRegSet->pc += (_RType)4; /* advance to next instruction */ sysProbeFault++; /* indicate trap occurred */ return (0); }/******************************************************************************** sysPciWriteFlush - flush posted PCI writes from buffer** This routine flushes the posted write buffer in the Hawk and the Dec2155x if* it is present.** RETURNS: OK if flush succeeded or ERROR if an error occured.*/STATUS sysPciWriteFlush(void) { UINT16 devId;#ifdef INCLUDE_DEC2155X char * temp;#endif /* INCLUDE_DEC2155X */ /* * Flush Hawk posted write buffer by doing a dummy read of one * of its MPC registers */ devId = sysIn16 ((UINT16 *)HAWK_ADDR(HAWK_MPC_DEVID));#ifdef INCLUDE_DEC2155X /* Flush the Dec2155x posted write buffer by reading from a cPCI location */ if (sysBusToLocalAdrs (PCI_SPACE_MEM_SEC, (char *) CPCI_FLUSH_ADDR, &temp) != OK) return (ERROR); temp = (char *)sysIn32 ((UINT32 *)temp);#endif /* INCLUDE_DEC2155X */ return (OK); }/******************************************************************************** sysMemProbeBus - probe an address on a bus.** This routine probes a specified address to see if it is readable or* writable, as specified by <mode>. The address will be read or written as* 1, 2, or 4 bytes as specified by <length> (values other than 1, 2, or 4* yield unpredictable results). If the probe is a VX_READ, the value read will* be copied to the location pointed to by <pVal>. If the probe is a VX_WRITE,* the value written will be taken from the location pointed to by <pVal>.* In either case, <pVal> should point to a value of 1, 2, or 4 bytes, as* specified by <length>.** This routine probes the specified address with interrupts disabled and* a special handler for Data Access and Alignment exceptions.** RETURNS: OK if probe succeeded or ERROR if an exception occured.*/LOCAL STATUS sysMemProbeBus ( 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 */ ) { FUNCPTR oldVec; STATUS status; /* clear fault flag */ sysProbeFault = 0; /* * Handle Data Access Exceptions locally * * Data Access Exceptions will occur when trying to probe addresses * that have not been mapped by the MMU. */ oldVec = excVecGet ((FUNCPTR *) _EXC_OFF_DATA); excVecSet ((FUNCPTR *) _EXC_OFF_DATA, FUNCREF(sysMemProbeTrap)); /* do probe */ if (mode == VX_READ) { status = sysMemProbeSup (length, adrs, pVal); } else { status = sysMemProbeSup (length, pVal, adrs); } /* restore original vector */ excVecSet ((FUNCPTR *) _EXC_OFF_DATA, oldVec); if (status == OK) /* no parameter errors during probe */ { /* if a PCI write was performed, flush the write post buffer(s) */ if (mode == VX_WRITE) status = sysPciWriteFlush (); } /* check for MMU fault */ if (sysProbeFault != 0) return (ERROR); else 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 as well as the* Hawk MERST and PCI_CFG_STATUS registers and the Universe PCI_CSR and* V_AMERR registers.** RETURNS: N/A*/void sysProbeErrClr (void) {#ifdef INCLUDE_DEC2155X sysDec2155xErrClr ();#endif /* INCLUDE_DEC2155X */ /* Clear Hawk MPC MERST Register */ sysOutByte ((ULONG)(HAWK_PHB_BASE_ADRS + HAWK_MPC_MERST), HAWK_MPC_MERST_CLR); /* Clear Hawk's Cnfg Hdr Status Reg */ pciConfigOutWord (sysHawkPciBusNo, sysHawkPciDevNo, sysHawkPciFuncNo, PCI_CFG_STATUS, HAWK_PCI_CFG_STATUS_CLR); /* 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. All probing is done with* interrupts disabled.** RETURNS: OK or ERROR if address cannot be probed*/LOCAL 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; int oldLevel; UINT16 mpcErrEnbl; /* Hawk MPC Error Enable reg */ UINT8 mpcErrStat; /* Hawk MPC Error Status reg */#ifdef INCLUDE_DEC2155X UINT16 secCmd; /* Dec2155x secondary command register image */ UINT16 chpCtrl0; /* Dec2155x chip control 0 register image */ UINT8 secSerr; /* Dec2155x secondary SERR control */#endif /* INCLUDE_DEC2155X */ /* probe performed with interrupts disabled */ oldLevel = intLock (); /* flush PCI posted write buffer(s) */ if ( (status = sysPciWriteFlush ()) != OK ) { intUnlock (oldLevel); return (status); } /* Clear any existing errors/exceptions */ sysProbeErrClr ();#ifdef INCLUDE_DEC2155X /* save current Dec2155x error reporting configuraion */ pciConfigInWord (0, DEC2155X_PCI_DEV_NUMBER, 0, PCI_CFG_COMMAND, &secCmd); pciConfigInWord (0, DEC2155X_PCI_DEV_NUMBER, 0, DEC2155X_CFG_CHP_CTRL0, &chpCtrl0); pciConfigInByte (0, DEC2155X_PCI_DEV_NUMBER, 0, DEC2155X_CFG_SEC_SERR_DISABLES, &secSerr); /* enable error reporting via Target Abort and SERR */ pciConfigOutWord (0, DEC2155X_PCI_DEV_NUMBER, 0, PCI_CFG_COMMAND, (secCmd | PCI_CMD_SERR_ENABLE)); pciConfigOutWord (0, DEC2155X_PCI_DEV_NUMBER, 0, DEC2155X_CFG_CHP_CTRL0, (chpCtrl0 | DEC2155X_CC0_MSTR_ABRT_MD)); pciConfigOutByte (0, DEC2155X_PCI_DEV_NUMBER, 0, DEC2155X_CFG_SEC_SERR_DISABLES, (secSerr & ~DEC2155X_SERR_DIS_PSTD_WRT_MSTR_ABRT));#endif /* save Hawk error reporting configuration */ mpcErrEnbl = sysIn16 ((UINT16 *)HAWK_ADDR(HAWK_MPC_MEREN)); /* * disable interrupts and machine checks for Target Abort, Master Abort and * SERR */ sysOut16 ((UINT16 *)HAWK_ADDR(HAWK_MPC_MEREN), (mpcErrEnbl & ~HAWK_ERR_DIS)); /* Perform probe */ status = sysMemProbeBus (adrs, mode, length, pVal); /* capture hawk error indications */ mpcErrStat = sysInByte (HAWK_ADDR(HAWK_MPC_MERST)); /* Clear any errors/exceptions */ sysProbeErrClr ();#ifdef INCLUDE_DEC2155X /* restore original Dec2155x error reporting configuration */ pciConfigOutWord (0, DEC2155X_PCI_DEV_NUMBER, 0, PCI_CFG_COMMAND, secCmd); pciConfigOutWord (0, DEC2155X_PCI_DEV_NUMBER, 0, DEC2155X_CFG_CHP_CTRL0, chpCtrl0); pciConfigOutByte (0, DEC2155X_PCI_DEV_NUMBER, 0, DEC2155X_CFG_SEC_SERR_DISABLES, secSerr);#endif /* INCLUDE_DEC2155X */ /* restore original hawk error reporting configuration */ sysOut16 ((UINT16 *)HAWK_ADDR(HAWK_MPC_MEREN), mpcErrEnbl); /* safe to re-enable interrupts */ intUnlock (oldLevel); /* check for hawk error indications */ if (mpcErrStat & HAWK_ERR_STS_MSK) status = ERROR; 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 calls an* architecture-specific probe routine.** RETURNS: ERROR if the probed address does not respond or causes a MMU fault.* Returns OK if the probed address responds.*/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 (); /* Handle PCI bus in special manner */ 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 */ ) { FAST UINT32 baselineTickCount; FAST UINT32 ticksToWait; /* * Get the Time Base Lower register tick count, this will be used * as the baseline. */ baselineTickCount = sysTimeBaseLGet(); /* * Convert delay time into ticks * * 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 */ if ((ticksToWait = delay * ((DEC_CLOCK_FREQ / 4) / 1000000)) == 0) return; while ((sysTimeBaseLGet() - baselineTickCount) < ticksToWait); }/******************************************************************************** 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. */ if (recovery == EXIT_TO_SYSTEM_MONITOR) sysToMonitor (BOOT_NO_AUTOBOOT); }/******************************************************************************* sysPciInsertLong - Insert field into PCI data long** This function writes a field into a PCI data long without altering any bits* not present in the field. It does this by first doing a PCI long read* (into a temporary location) of the PCI data long which contains the field* to be altered. It then alters the bits in the temporary location to match* the desired value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -