📄 syslib.c
字号:
** 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 by 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 */ cacheDisable (0); /* Disable the Instruction Cache */ cacheDisable (1); /* Disable the Data Cache */#if (CPU == PPC604) vxHid0Set (vxHid0Get () & ~_PPC_HID0_SIED); /* Enable Serial Instr Exec */#endif /* (CPU == PPC604) */ sysUniverseReset (); /* reset Universe chip */ sysSerialReset (); /* reset serial devices */ /* Clear the MSR */ vxMsrSet (0); /* Reset the EPIC */ sysPciOutLong((UINT32)EPIC_GLOBAL_CONFIG_REG, EPIC_GC_RESET); /* set the Board Fail LED */ *(UINT8 *)MV2100_SYS_STAT_REG2 |= MV2100_BD_FAIL; (*pRom) (startType); return (OK); /* in case we ever continue from ROM monitor */ }/******************************************************************************** sysHwInit2 - initialize additional system hardware** This routine connects system interrupt vectors and configures any * required features not configured by sysHwInit().** RETURNS: N/A*/void sysHwInit2 (void) { static BOOL configured = FALSE; /* Int connects for various devices */ if (!configured) {#ifdef INCLUDE_AUX_CLK sysAuxClkInit (); intConnect (INUM_TO_IVEC(TIMER0_INT_VEC), sysAuxClkInt, 0); intEnable (TIMER0_INT_LVL);#endif /* INCLUDE_AUX_CLK */ /* connect Vme to PCI interrupt */ intConnect (INUM_TO_IVEC(UNIV_INT_VEC), sysUnivVmeIntr, 0); /* interrupts can only be turned on ultimately by the PIC int ctrlr */ intEnable (UNIV_INT_LVL); /* initialize serial interrupts */ sysSerialHwInit2(); configured = TRUE; } }/******************************************************************************** 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. It also maps local resources onto* the VMEbus.** RETURNS: N/A** SEE ALSO: sysProcNumGet()**/void sysProcNumSet ( int procNum /* processor number */ ) { /* * Init global variable - this needs to be done before * calling sysUniverseInit2() because it calls sysProcNumGet() * via the MACRO definition. */ sysProcNum = procNum; /* * Set up the node's VME slave decoders. */ sysUniverseInit2(procNum); }/* miscellaneous support routines *//******************************************************************************** sysLocalToBusAdrs - convert a local address to a bus address** This routine returns a VMEbus address as it would be seen on the bus.* The local address that is passed into this routine is the address of* the local resource as seen by the CPU.** 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 VME_AM_EXT_SUP_PGM: case VME_AM_EXT_SUP_DATA: case VME_AM_EXT_USR_PGM: case VME_AM_EXT_USR_DATA: if ((VME_A32_SLV_SIZE != 0) && ((ULONG)localAdrs >= VME_A32_SLV_LOCAL) && ((ULONG)localAdrs < (VME_A32_SLV_LOCAL + VME_A32_SLV_SIZE))) { *pBusAdrs = localAdrs + (VME_A32_SLV_BUS - VME_A32_SLV_LOCAL); return (OK); } else return (ERROR); case VME_AM_STD_SUP_PGM: case VME_AM_STD_SUP_DATA: case VME_AM_STD_USR_PGM: case VME_AM_STD_USR_DATA: if ((VME_A24_SLV_SIZE != 0) && ((ULONG)localAdrs >= VME_A24_SLV_LOCAL) && ((ULONG)localAdrs < (VME_A24_SLV_LOCAL + VME_A24_SLV_SIZE))) { *pBusAdrs = localAdrs + (VME_A24_SLV_BUS - VME_A24_SLV_LOCAL); return (OK); } else return (ERROR); case VME_AM_SUP_SHORT_IO: case VME_AM_USR_SHORT_IO: if ((VME_A16_SLV_SIZE != 0) && ((ULONG)localAdrs >= VME_A16_SLV_LOCAL) && ((ULONG)localAdrs < (VME_A16_SLV_LOCAL + VME_A16_SLV_SIZE))) { *pBusAdrs = localAdrs + (VME_A16_SLV_BUS - VME_A16_SLV_LOCAL); return (OK); } else return (ERROR); default: return (ERROR); } }/******************************************************************************** sysBusToLocalAdrs - convert a bus address to a local address** This routine returns a local address that is used to access the VMEbus.* The bus address that is passed into this routine is the VMEbus address* as it would be seen on the bus.** 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 VME_AM_EXT_SUP_PGM: case VME_AM_EXT_USR_PGM: case VME_AM_EXT_SUP_DATA: case VME_AM_EXT_USR_DATA: if ((VME_A32_MSTR_SIZE != 0) && ((ULONG) busAdrs >= VME_A32_MSTR_BUS) && ((ULONG) busAdrs < (VME_A32_MSTR_BUS + VME_A32_MSTR_SIZE))) { *pLocalAdrs = (char *)busAdrs + (VME_A32_MSTR_LOCAL - VME_A32_MSTR_BUS); return (OK); } /* * This handles the VME LM/SIG/SEM regs window */ if (((ULONG) busAdrs >= VME_LM_MSTR_BUS) && ((ULONG) busAdrs < (VME_LM_MSTR_BUS + VME_LM_MSTR_SIZE))) { *pLocalAdrs = (char *)busAdrs + (VME_LM_MSTR_LOCAL - VME_LM_MSTR_BUS); return (OK); } return (ERROR); break; case VME_AM_STD_SUP_PGM: case VME_AM_STD_USR_PGM: case VME_AM_STD_SUP_DATA: case VME_AM_STD_USR_DATA: if ((VME_A24_MSTR_SIZE == 0) || ((ULONG) busAdrs < VME_A24_MSTR_BUS) || ((ULONG) busAdrs >= (VME_A24_MSTR_BUS + VME_A24_MSTR_SIZE))) { return (ERROR); } *pLocalAdrs = (char *) busAdrs + (VME_A24_MSTR_LOCAL - VME_A24_MSTR_BUS); return (OK); break; case VME_AM_SUP_SHORT_IO: case VME_AM_USR_SHORT_IO: if ((VME_A16_MSTR_SIZE == 0) || ((ULONG) busAdrs < VME_A16_MSTR_BUS) || ((ULONG) busAdrs >= (VME_A16_MSTR_BUS + VME_A16_MSTR_SIZE))) { return (ERROR); } *pLocalAdrs = (char *) busAdrs + (VME_A16_MSTR_LOCAL - VME_A16_MSTR_BUS); return (OK); default: return (ERROR); } }/********************************************************************************* sysBusTas - test and set a specified location** This routine performs a test-and-set (TAS) instruction on the specified* address. To prevent deadlocks, interrupts are disabled during the* test-and-set operation. The following table defines the method used to* insure an atomic operation.** .CS* Master Slave_1 Slave_2** VME Chip Don't Care U1 U1* ---------- ---- ----* Method VOWN VOWN VOWN** VME Chip Don't Care U1 U2* ---------- ---- ----* Method VOWN VOWN RMW** VME Chip U1 or U2 U2* U2+* ---------- ---- ----* Method VOWN+++ RMW RMW** VME Chip U2++ U2 U2* PCI Bridge or Raven3* ---------- ---- ----* Method lwarx/stwcx RMW RMW** + = Refer to target.txt file for explanation of older boards* with Universe II (U2).* ++ = Refer to target.txt file for explanation of newer boards* with Universe II (U2).* +++ = The master's hardware does not preserve the atomic RMW.* ++++ = If SM_OFF_BOARD == TRUE, the method used will be the same* as if the master board is acting like a slave board; namely:* RMW for UNIVERSE_II and VOWN for UNIVERSE_I* .CE** NOTE: Although the address passed-in to sysBusTas() is defined as* "char *", vxTas() operates on the address as a "void *".* For PowerPC, this implies that the location tested-and-set is* actually a 32-bit entity.* * RETURNS: TRUE if the value had not been set but is now, or* FALSE if the value was set already.** SEE ALSO: vxTas(), sysBusTasClear()*/BOOL sysBusTas ( char * adrs /* address to be tested and set */ ) { /* Check for master node */ if (sysProcNumGet() == 0) {#ifdef ANY_BRDS_IN_CHASSIS_NOT_RMW /* * A slave board in the chassis cannot generate a VMEbus RMW, * and/or the master board cannot translate an incoming VMEbus * RMW into an atomic operation, and/or the master board cannot * generate a VMEbus RMW; therefore, the master must set * VOWN before doing a TAS. */ return (sysVmeVownTas(adrs));#else#if (SM_OFF_BOARD == FALSE) BOOL state = FALSE; /* semaphore state */ int lockKey; /* interrupt lock key */ /* * All slave boards in the chassis are generating a VMEbus RMW, and * the master board can translate an incoming VMEbus RMW into an * atomic operation; therefore, the master can simply call vxTas() * (lwarx/stwcx sequence) because the write portion of the RMW will * be detected. */ /* lock interrupts so that vxTas() can execute without preemption */ lockKey = intLock (); /* Perform TAS on local address */ state = vxTas ((UINT *)adrs); SYNC; intUnlock (lockKey); /* return TAS test result */ return (state);#else /* The master board can generate a VMEbus RMW */ return (sysVmeRmwTas(adrs));#endif /* SM_OFF_BOARD */#endif /* ANY_BRDS_IN_CHASSIS_NOT_RMW */ } else /* Slave node */ { if (pciToVmeDev == UNIVERSE_II) { /* A board with the UNIVERSE_II can generate a VMEbus RMW */ return (sysVmeRmwTas(adrs)); } else /* UNIVERSE_I */ { /* * A slave board with the UNIVERSE_I cannot generate a VMEbus * RMW; therefore, it must set VOWN before doing a TAS. */ return (sysVmeVownTas(adrs)); } } }/******************************************************************************** sysBusTasClear - clear a location set by sysBusTas()** This routine clears the specified 32-bit location typically set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -