⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syslib.c

📁 SL811 USB接口芯片用于VxWorks系统的驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
* 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 (0);			  /* disable icache */
    cacheDisable (1);			  /* 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
*
*
* RETURNS: N/A.
*/
void sysLocalDelay
    (
    UINT32 ms_delay
    )
    {
    UINT32 start_upper;
    UINT32 start_lower;
    UINT32 end_upper;
    UINT32 end_lower;
    UINT32 upper;
    UINT32 lower;
    UINT32 delay;
    BOOL timesup = FALSE;

    /*
     *  Read the timebase twice to start
     */
    vxTimeBaseGet (&start_upper, &start_lower);
    vxTimeBaseGet (&end_upper, &end_lower);

    while (timesup == FALSE)
        {

        /*
         * Determine if the delay has been long enough
         */
        upper = end_upper - start_upper;
        if (start_lower > end_lower)
            upper--;
        lower = end_lower - start_lower;

        delay =  1000 * upper * (0xFFFFFFFF / sysTimerClkFreq);
        delay += lower / (sysTimerClkFreq / 1000);

        if (delay > ms_delay)
            {
            timesup = TRUE;
            }
            else
            {
            vxTimeBaseGet (&end_upper, &end_lower);
            }
        }
    return;
    }


/*******************************************************************************
*
* sysInfoGet - Determines system information (clock frequencies, etc.) based on
*              Walnut board switch settings.
*
* This routine returns information about the current operating environment of
* the Walnut 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 && sysInfo->freqVCOMhz <= VCO_MAX)
            {
            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, VCO_MAX);
                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_RA:
	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 */

    msgSize = strlen (wrongCpuMsg);

    sysSerialHwInit ();

    pSioChan = sysSerialChanGet (0);

    sioIoctl (pSioChan, SIO_MODE_SET, (void *) SIO_MODE_POLL);

    for (msgIx = 0; msgIx < msgSize; msgIx++)
    	{
    	while (sioPollOutput (pSioChan, wrongCpuMsg[msgIx]) == EAGAIN);
    	}

    sysToMonitor (BOOT_NO_AUTOBOOT);
    }

#ifdef INCLUDE_SHOW_ROUTINES
/*******************************************************************************
*
* sysInfoShow - Shows system information (clock frequencies, etc.) based on
*               Walnut board switch settings.
*
* This routine displays information about the current operating environment of
* the Walnut 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 + -