📄 syslib.c
字号:
/* resize the sysPhysMemDesc table entry for SBRAM */ sysPhysMemDesc[2].len = sysSbramSize; } return (sysPhysMemSize); }/********************************************************************************* sysMemTop - get the address of the top of VxWorks memory** This routine returns a pointer to the first byte of memory not* controlled or used by VxWorks.** The user can reserve memory space by defining the macro USER_RESERVED_MEM* in config.h. This routine returns the address of the reserved memory* area. The value of USER_RESERVED_MEM is in bytes.** RETURNS: The address of the top of VxWorks memory.*/char * sysMemTop (void) { static char * memTop = NULL; if (memTop == NULL) { memTop = sysPhysMemTop () - USER_RESERVED_MEM; } return memTop; }/******************************************************************************** sysToMonitor - transfer control to the ROM monitor** This routine transfers control to the ROM monitor. Normally, it is called* only by reboot()--which services ^X--and bus errors at interrupt level.* However, in some circumstances, the user may wish to introduce a* <startType> to enable special boot ROM facilities.** RETURNS: Does not return.*/STATUS sysToMonitor ( int startType /* parameter passed to ROM to tell it how to boot */ ) { FUNCPTR pRom = (FUNCPTR) (ROM_TEXT_ADRS + 4); /* Warm reboot */#ifdef INCLUDE_MOT_FEC /* make sure the FEC is disabled */ sysFecEnetDisable (vxImmrGet ());#endif /* INCLUDE_MOT_FEC */ sysSerialReset(); /* reset the serial device */ (*pRom) (startType); /* jump to bootrom entry point */ return (OK); /* in case we ever continue from ROM monitor */ }/******************************************************************************** sysHwInit2 - additional system configuration and initialization** This routine connects system interrupts and does any additional* configuration necessary.** RETURNS: N/A** NOMANUAL*/void sysHwInit2 (void) { static BOOL configured = FALSE; int immrVal; immrVal = vxImmrGet(); if (!configured) { /* Initialize CPM interrupts */ ppc860IntrInit2 (IV_LEVEL4); /* default vector level */ /* set SCC1 as highest SCC interrupt (A) */ *CICR(immrVal) &= ~(CICR_SCCAP_MSK | CICR_SCCBP_MSK | CICR_SCCCP_MSK | CICR_SCCDP_MSK); *CICR(immrVal) |= (CICR_SCCAP_SCC1 | CICR_SCCBP_SCC2 | CICR_SCCCP_SCC3 | CICR_SCCDP_SCC4); /* * NOTE: We must unfreeze the Time Base clock prior to calling * sysSerialHwInit2(). This is because sysSerialHwInit2() calls * kbdHrdInit() to initialize the keyboard which, in turn, calls * sysMsDelay() which depends upon the decrementer ticking. If * sysSerialHwInit2() is called first, we will hang in sysMsDelay() * forever because the decrementer won't be counting down. * * Unfreeze the Time Base clock. */ * TBSCR(immrVal) = TBSCR_TBE | TBSCR_TBF; /* initialize serial interrupts */ sysSerialHwInit2(); configured = TRUE; }#ifdef INCLUDE_DEC2155X sysQspanCapt(); /* Initialize Dec2155x interrupts */ sysDec2155xInit2();#endif /* INCLUDE_DEC2155X */#ifdef INCLUDE_SM_NET sysSmParamsCompute ();#endif /* INCLUDE_SM_NET */ /* * turn off the STAT1 and STAT3 LEDs * * if no startup error occurred, then clear the FAULT LED * * if the battery voltage is OK, the clear STAT2 LED */ sysLedUpdate (LED_STAT1, LED_OFF); sysLedUpdate (LED_STAT3, LED_OFF); if (sysInitStatus == 0) { sysLedUpdate (LED_FAULT, LED_OFF); sysLedUpdate (LED_STAT1, LED_ON); } if (*PIPR(immrVal) & BAT_BW) sysLedUpdate (LED_STAT2, LED_OFF); }/******************************************************************************** sysProcNumGet - get the processor number** This routine returns the processor number for the CPU board, which is* set with sysProcNumSet().* * RETURNS: The processor number for the CPU board.** SEE ALSO: sysProcNumSet()*/int sysProcNumGet (void) { return (sysProcNum); }/******************************************************************************** sysProcNumSet - set the processor number** This routine sets the processor number for the CPU board. Processor numbers* should be unique on a single backplane.** Not applicable for the busless 860Ads.** RETURNS: N/A** SEE ALSO: sysProcNumGet()**/void sysProcNumSet ( int procNum /* processor number */ ) { sysProcNum = procNum; }/******************************************************************************** sysLocalToBusAdrs - convert a local CPU address to a PCI bus address** Given a CPU address, this routine returns a corresponding local PCI bus* or Compact (backpanel) PCI bus address provided that such an address exists.* The target PCI bus (local or backpanel) is selected by the adrsSpace* parameter. Legal values for this parameter are found in "pci.h". If a* transparent bridge is used to access the Compact PCI bus, the local PCI bus* and the backpanel PCI bus share the same address space. In this case, the* local and backpanel address space designators are synonomous.** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysBusToLocalAdrs()*/STATUS sysLocalToBusAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * localAdrs, /* local address to convert */ char ** pBusAdrs /* where to return bus address */ ) { switch (adrsSpace) { case PCI_SPACE_IO_PRI: case PCI_SPACE_IO_SEC: /* convert from cpu address space to local pci space */ if ( sysCpuToPciAdrs (PCI_BAR_SPACE_IO, localAdrs, pBusAdrs) != OK ) return (ERROR);#ifdef INCLUDE_DEC2155X /* * if continuing on to the backpanel using the dec2155x, translate * from local pci space to compact pci space. */ if ( PCI_SPACE_IS_SEC(adrsSpace) ) return ( sysPciToCpciAdrs (PCI_BAR_SPACE_IO, *pBusAdrs, pBusAdrs) );#endif /* INCLUDE_DEC2155X */ break; case PCI_SPACE_MEMIO_PRI: case PCI_SPACE_MEM_PRI: case PCI_SPACE_MEMIO_SEC: case PCI_SPACE_MEM_SEC: /* convert from cpu address space to local pci address space */ if (sysCpuToPciAdrs (PCI_BAR_SPACE_MEM, localAdrs, pBusAdrs) != OK ) return (ERROR);#ifdef INCLUDE_DEC2155X /* * if continuing on to the backpanel using the dec2155x, translate * from local pci space to compact pci space. */ if ( PCI_SPACE_IS_SEC(adrsSpace) ) return ( sysPciToCpciAdrs(PCI_BAR_SPACE_MEM, *pBusAdrs, pBusAdrs) );#endif /* INCLUDE_DEC2155X */ break; default: return (ERROR); break; } return (OK); }/******************************************************************************** sysBusToLocalAdrs - convert a PCI bus address to a local CPU address** Given a local or Compact (backpanel) PCI address, this routine returns a* corresponding local CPU bus address provided such an address exists. The* originating PCI bus (local or backpanel) is selected by the adrsSpace* parameter. Legal values for this parameter are found in "pci.h". If a* transparent bridge is used to access the Compact PCI bus, the local PCI bus* and the Compact PCI bus share the same address space. In this case, the* local and backpanel address space designators are synonomous.** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysLocalToBusAdrs()*/STATUS sysBusToLocalAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * busAdrs, /* bus address to convert */ char ** pLocalAdrs /* where to return local address */ ) { switch (adrsSpace) { case PCI_SPACE_IO_SEC:#ifdef INCLUDE_DEC2155X /* * translate from compact PCI address space to local PCI address * space. */ if ( sysCpciToPciAdrs (PCI_BAR_SPACE_IO, busAdrs, &busAdrs) != OK ) return (ERROR); /* fall through */#endif /* INCLUDE_DEC2155X */ case PCI_SPACE_IO_PRI: /* * translate from local PCI address space to CPU address * space. */ return ( sysPciToCpuAdrs (PCI_BAR_SPACE_IO, busAdrs, pLocalAdrs) ); break; case PCI_SPACE_MEMIO_SEC: case PCI_SPACE_MEM_SEC:#ifdef INCLUDE_DEC2155X /* * translate from compact PCI address space to local PCI address * space. */ if ( sysCpciToPciAdrs (PCI_BAR_SPACE_MEM, busAdrs, &busAdrs) != OK) return (ERROR); /* fall through */#endif /* INCLUDE_DEC2155X */ case PCI_SPACE_MEMIO_PRI: case PCI_SPACE_MEM_PRI: /* * translate from local PCI address space to CPU address * space. */ return (sysPciToCpuAdrs (PCI_BAR_SPACE_MEM, busAdrs, pLocalAdrs) ); break; default: return (ERROR); break; } }/********************************************************************************* sysBusTas - test and set a location across the bus** The cPCI bridge chips do not support PCI target locking, therefore there is* no atomic RMW operation. This routine performs a software-based mutual* exclusion algorithm in place of a true test and set.** NOTE: This algorithm is performed through a PCI-to-PCI bridge to a shared* location that is subject to unprotected access by multiple simultaneous* processors. There is the possibility that the bridge will deliver a delayed* read completion to a PCI bus master which was not the original initiator of* the delayed read. The bridge delivers the delayed read completion to the new* requestor because it believes that the new delayed read request is actually* the original master performing a delayed read retry as required by the PCI* spec. When the original master comes back with the genuine retry, the bridge* treats it as a new request. When this "aliasing" occurs, a read performed* after a write can appear to complete ahead of the write, which is in violation* of PCI transaction ordering rules. Since this algorithm depends on a strict* time-ordered sequence of operations, it can deadlock under this condition.* To prevent the deadlock, a throw-away read must be performed after the initial* write. Since the bridge only remembers once instance of a queued delayed* read request, the throw-away read will "consume" the results of a* mis-directed read completion and subsequent read requests are guaranteed to* be queued and completed after the write.** RETURNS: TRUE if lock acquired.* FALSE if lock not acquired.** SEE ALSO: sysBusTasClear()*/BOOL sysBusTas ( char * adrs /* address to be tested and set */ ) { FAST int value; /* value to place in lock variable */ FAST int nChecks; /* number of times to re-check lock */ FAST int count; /* running count of re-checks */ int oldLvl; /* previous interrupt level */ volatile int * lockAdrs = (int *)adrs; if (smUtilTasValue == 0) smUtilTasValue = (TAS_CONST + sysProcNumGet ())<< 24; value = smUtilTasValue; /* special value to write */ nChecks = DEFAULT_TAS_CHECKS; /* number of checks to do */ /* Lock out interrupts */ oldLvl = intLock (); /* Test that lock variable is initially empty */ if (*lockAdrs != 0) { intUnlock (oldLvl); return (FALSE); /* someone else has lock */ } /* Set lock value */ *lockAdrs = value; /* Perform a preliminary read due to PCI bridge issues */ count = *lockAdrs; /* Check that no one else is trying to take lock */ for (count = 0; count < nChecks; count++) { if (*lockAdrs != value) { intUnlock (oldLvl); return (FALSE); /* someone else stole lock */ } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -