📄 syslib.c
字号:
* which indicates the top of memory.** Normally, the user specifies the amount of physical memory with the* macro LOCAL_MEM_SIZE in config.h. If not defined, then LOCAL_MEM_SIZE* is assumed to be, and must be, the true size of physical memory.** NOTE: Do not adjust LOCAL_MEM_SIZE to reserve memory for application* use. See sysMemTop() for more information on reserving memory.** RETURNS: The address of the top of physical memory.** SEE ALSO: sysMemTop()*/char * sysPhysMemTop ( void ) { static char * physTop = NULL; if (physTop == NULL) { physTop = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE); } return physTop; }/**************************************************************************** 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 special 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 (INSTRUCTION_CACHE); /* disable icache */ cacheDisable (DATA_CACHE); /* disable dcache */ sysDcrUicsrClear (0xffffffff); /* clear pending interrupts */ vxMsrSet (0); /* clear MSR */ (*pRom) (startType); /* jump to bootrom */ return (OK); /* in case we ever continue from ROM monitor */ }/**************************************************************************** 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, always 0 (zero).** SEE ALSO: sysProcNumSet()*/int sysProcNumGet ( void ) { return (0); }/**************************************************************************** sysProcNumSet - set the processor number** This routine sets the processor number for the CPU board.* Processor numbers should be unique on a single backplane.** NOTE: This routine has no effect, since there is no VMEbus.* RETURNS: N/A** SEE ALSO: sysProcNumGet(),*/void sysProcNumSet ( int procNum /* processor number (ignored in SBC405GP BSP) */ ) { sysProcNum = sysProcNumGet (); }/**************************************************************************** sysIntLockLevelSet - set the current interrupt lock-out level** This routine sets the current interrupt lock-out level.** NOTE: This routine has no effect, since the facility is currently not* implemented.** RETURNS: ERROR, always.*/int sysIntLockLevelSet ( int newLvl /* new interrupt level */ ) { return (ERROR); }/**************************************************************************** sysLocalDelay - delay of <ms_delay> milliseconds used before kernel is up** This routine get an argument that say how many millisecond to delay.** RETURNS: N/A.*/void sysLocalDelay ( UINT32 ms_delay ) { UINT32 startUpper; UINT32 startLower; UINT32 endUpper; UINT32 endLower; UINT32 upper; UINT32 lower; UINT32 delay; BOOL timesup = FALSE; /* * Read the timebase twice to start */ vxTimeBaseGet (&startUpper, &startLower); vxTimeBaseGet (&endUpper, &endLower); while (timesup == FALSE) { /* * Determine if the delay has been long enough */ upper = endUpper - startUpper; if (startLower > endLower) upper--; lower = endLower - startLower; delay = 1000 * upper * (0xFFFFFFFF / sysTimerClkFreq); delay += lower / (sysTimerClkFreq / 1000); if (delay > ms_delay) { timesup = TRUE; } else { vxTimeBaseGet (&endUpper, &endLower); } } return; }/**************************************************************************** sysInfoGet - Determines system information (clock frequencies, etc.)* based on board switch settings.** This routine returns information about the current operating environment of* the board. Optionally, it prints the information out.** RETURNS: OK or ERROR.*/STATUS sysInfoGet ( SYS_INFO * sysInfo, int verbose ) { UINT32 pllmr; UINT32 sysClkPeriodNs = ONE_BILLION / SYS_CLK_FREQ; bzero((char *)sysInfo, sizeof(SYS_INFO)); /* * Read PLL Mode register */ pllmr = sysDcrPllmrGet(); if (verbose) printf("\n"); /* * Determine FWD_DIV. */ switch (pllmr & PLLMR_FWD_DIV_MASK) { case PLLMR_FWD_DIV_BYPASS: sysInfo->pllFwdDiv = 1; break; case PLLMR_FWD_DIV_3: sysInfo->pllFwdDiv = 3; break; case PLLMR_FWD_DIV_4: sysInfo->pllFwdDiv = 4; break; case PLLMR_FWD_DIV_6: sysInfo->pllFwdDiv = 6; break; default: if (verbose) printf("Invalid FWDDIV bits in PLL Mode reg: %8.8x\a\n", pllmr); return(ERROR); break; } /* * Determine FBK_DIV. */ switch (pllmr & PLLMR_FB_DIV_MASK) { case PLLMR_FB_DIV_1: sysInfo->pllFbkDiv = 1; break; case PLLMR_FB_DIV_2: sysInfo->pllFbkDiv = 2; break; case PLLMR_FB_DIV_3: sysInfo->pllFbkDiv = 3; break; case PLLMR_FB_DIV_4: sysInfo->pllFbkDiv = 4; break; } /* * Determine PLB_DIV. */ switch (pllmr & PLLMR_CPU_TO_PLB_MASK) { case PLLMR_CPU_PLB_DIV_1: sysInfo->pllPlbDiv = 1; break; case PLLMR_CPU_PLB_DIV_2: sysInfo->pllPlbDiv = 2; break; case PLLMR_CPU_PLB_DIV_3: sysInfo->pllPlbDiv = 3; break; case PLLMR_CPU_PLB_DIV_4: sysInfo->pllPlbDiv = 4; break; } /* * Determine PCI_DIV. */ switch (pllmr & PLLMR_PCI_TO_PLB_MASK) { case PLLMR_PCI_PLB_DIV_1: sysInfo->pllPciDiv = 1; break; case PLLMR_PCI_PLB_DIV_2: sysInfo->pllPciDiv = 2; break; case PLLMR_PCI_PLB_DIV_3: sysInfo->pllPciDiv = 3; break; case PLLMR_PCI_PLB_DIV_4: sysInfo->pllPciDiv = 4; break; } /* * Determine EXTBUS_DIV. */ switch (pllmr & PLLMR_EXB_TO_PLB_MASK) { case PLLMR_EXB_PLB_DIV_2: sysInfo->pllExtBusDiv = 2; break; case PLLMR_EXB_PLB_DIV_3: sysInfo->pllExtBusDiv = 3; break; case PLLMR_EXB_PLB_DIV_4: sysInfo->pllExtBusDiv = 4; break; case PLLMR_EXB_PLB_DIV_5: sysInfo->pllExtBusDiv = 5; break; } /* * Determine OPB_DIV. */ switch (pllmr & PLLMR_OPB_TO_PLB_MASK) { case PLLMR_OPB_PLB_DIV_1: sysInfo->pllOpbDiv = 1; break; case PLLMR_OPB_PLB_DIV_2: sysInfo->pllOpbDiv = 2; break; case PLLMR_OPB_PLB_DIV_3: sysInfo->pllOpbDiv = 3; break; case PLLMR_OPB_PLB_DIV_4: sysInfo->pllOpbDiv = 4; break; } /* * Check pllFwdDiv to see if running in bypass mode where the CPU speed * is equal to the 405GP SYS_CLK_FREQ. If not in bypass mode, check VCO * to make sure it is within the proper range. * spec: VCO = SYS_CLOCK x FBKDIV x PLBDIV x FWDDIV * Note freqVCO is calculated in Mhz to avoid errors introduced by rounding. */ if (sysInfo->pllFwdDiv == 1) { sysInfo->freqProcessor = SYS_CLK_FREQ; sysInfo->freqPLB = SYS_CLK_FREQ/sysInfo->pllPlbDiv; } else { sysInfo->freqVCOMhz = (1000 * sysInfo->pllFwdDiv * sysInfo->pllFbkDiv * sysInfo->pllPlbDiv) / sysClkPeriodNs; if (sysInfo->freqVCOMhz >= VCO_MIN_GP && sysInfo->freqVCOMhz <= VCO_MAX_GP) { sysInfo->freqPLB = (ONE_BILLION / ((sysClkPeriodNs * 10) / sysInfo->pllFbkDiv)) * 10; sysInfo->freqProcessor = sysInfo->freqPLB * sysInfo->pllPlbDiv; } else { if (verbose) { printf("Invalid VCO frequency calculated : %d MHz \a\n", sysInfo->freqVCOMhz); printf("It must be between %d-%d MHz \a\n", VCO_MIN_GP, VCO_MAX_GP); printf("PLL Mode reg : %8.8x\a\n", pllmr); } return(ERROR); } } return(OK); }/**************************************************************************** sysCpuCheck - confirm the CPU type** This routine validates the cpu type. If the wrong cpu type is discovered* a message is printed using the serial channel in polled mode.** RETURNS: N/A.*/void sysCpuCheck (void) { int msgSize; int msgIx; SIO_CHAN * pSioChan; /* serial I/O channel */ /* Check for a valid CPU type; If one is found, just return */ switch (vxPvrGet ()) { case PVR_405GP_RB: case PVR_405GP_RC: break; case PVR_405GP_RD: case PVR_405GP_RE: return; default: break; } /* * Invalid CPU type; print error message and terminate. * Check size of wrongCpuPvr[] above if changing this. */ sprintf(wrongCpuPvr, "[PVR=%08x]\r\n", vxPvrGet()); sysSerialHwInit (); pSioChan = sysSerialChanGet (0); sioIoctl (pSioChan, SIO_MODE_SET, (void *) SIO_MODE_POLL); msgSize = strlen (wrongCpuMsg); for (msgIx = 0; msgIx < msgSize; msgIx++) { while (sioPollOutput (pSioChan, wrongCpuMsg[msgIx]) == EAGAIN); } /* * Include the final NULL byte here, in case sysToMonitor() shuts * down the I/O before the last-written byte actually makes it * onto the line. (Such disappearances have been observed.) */ msgSize = strlen (wrongCpuPvr) + 1; for (msgIx = 0; msgIx < msgSize; msgIx++) { while (sioPollOutput (pSioChan, wrongCpuPvr[msgIx]) == EAGAIN); } sysToMonitor (BOOT_NO_AUTOBOOT); }#ifdef INCLUDE_SHOW_ROUTINES/**************************************************************************** sysInfoShow - Shows system information (clock frequencies, etc.) based on* board switch settings.** This routine displays information about the current operating environment of* the board.** RETURNS: OK or ERROR.*/STATUS sysInfoShow ( ) { SYS_INFO sysInfo; return(sysInfoGet(&sysInfo, 1)); }#endif /* INCLUDE_SHOW_ROUTINES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -