www.pudn.com > nxplpc2204bsp.rar > sysLib.c


/* sysLib.c - Samsung SBC ARM7 system-dependent routines */ 
 
 
/* Copyright 1984-2002 Wind River Systems, Inc. */ 
#include "copyright_wrs.h" 
#include "smartarm.h" 
/* 
modification history 
-------------------- 
01o,29jul04,a_m  BSP定制 for 精英arm7开发板 
01k,26mar02,m_h  rename glbEnetAddr to sysSngks32cMacAddr 
01j,17jan02,m_h  fix cache issues and diab build warnings 
01i,27sep01,m_h  base MAC address on user DIP setting, Big Endian Support 
01h,23jul01,m_h  builds in UNIX 
01g,17jul01,g_h  add visionWARE 2.00 support 
01f,11jul01,g_h  disable cache in sysToMonitor() 
01e,10jul01,g_h  add INCLUDE_LCD & INCLUDE_LED & INCLUDE_NETWORK macros 
01d,09jul01,g_h  add #include "sbcCksum.c" instead of the makefile 
01c,26apr01,m_h  convert tabs to spaces for readability 
01b,25apr01,m_h  add comments to cache functions 
01a,12apr01,m_h  created from snds100 template. 
*/ 
 
/* 
DESCRIPTION 
This library provides board-specific routines for the WindRiver SBC ARM7 
Ver 1.0 Development Board BSP for the Samsung KS32C chip. 
 
It #includes the following chip drivers: 
    nullVme.c         -     dummy VMEbus routines 
    lpc2210Timer.c   -     SNGKS32CARM7 timer driver 
    lpc2210IntrCtl.c -     SNGKS32CARM7 interrupt controller driver 
    nullNvRam.c       -     dummy NVRAM routines 
 
It #includes the following BSP files: 
    sysSerial.c       -     serial device initialization routines 
    sysEnd.c          -     END network driver support routines. 
 
INCLUDE FILES: sysLib.h string.h intLib.h taskLib.h vxLib.h muxLib.h 
 
SEE ALSO: 
 
, 
, 
 
*/ 
 
/* includes */ 
 
#include "vxWorks.h" 
#include "config.h" 
 
#include "sysLib.h" 
#include "string.h" 
#include "intLib.h" 
#include "taskLib.h" 
#include "vxLib.h" 
#include "muxLib.h" 
#include "cacheLib.h" 
#include "memLib.h" 
 
#include "wrSbcArm7.h" 
 
#include "lpc2210.h" 
 
/* imports */ 
 
IMPORT char end;                            /* end of system, created by ld */ 
IMPORT VOIDFUNCPTR _func_armIntStackSplit;  /* ptr to fn to split stack */ 
 
 
/* globals */ 
 
int    sysBus         = BUS;            /* system bus type (VME_BUS, etc) */ 
int    sysCpu         = CPU;            /* system cpu type */ 
char * sysBootLine    = BOOT_LINE_ADRS; /* address of boot line */ 
char * sysExcMsg      = EXC_MSG_ADRS;   /* catastrophic message area */ 
int    sysProcNum;                      /* processor number of this cpu */ 
int    sysFlags;                        /* boot flags */ 
char   sysBootHost [BOOT_FIELD_LEN];    /* name of host from which we booted */ 
char   sysBootFile [BOOT_FIELD_LEN];    /* name of file from which we booted */ 
 
CACHE_FUNCS   sngks32cCacheFuncs; 
/*  : sysSngks32cMacAddr->ne2000EnetAddr */ 
unsigned char ne2000EnetAddr[] = ETHERNET_MAC_ADRS; 
 
/* locals */ 
 
 
/* defines */ 
 
     
/* externals */ 
 
IMPORT void   lpc2210IntDevInit (void); 
IMPORT void   sysIntStackSplit (char *, long); 
 
/*local defines*/ 
#ifndef SBCARM7_CTRL_REG_READ 
#   define SBCARM7_CTRL_REG_READ(x,result) \ 
        ((result) = *(volatile UINT32 *)(x)) 
#endif    /*SBCARM7_READ*/ 
 
#ifndef SBCARM7_CTRL_REG_WRITE 
#   define SBCARM7_CTRL_REG_WRITE(x,data) \ 
        (*((volatile UINT32 *)(x)) = (data)) 
#endif /*SBCARM7_WRITE*/ 
 
 
 
/* globals */ 
 
 
/* forward LOCAL functions declarations */ 
 
 
/* forward declarations */ 
 
char *    sysPhysMemTop (void); 
 
/* included source files */ 
 
#ifdef INCLUDE_FLASH 
#include "flashMem.c" 
#else /* INCLUDE_FLASH */ 
#include "mem/nullNvRam.c" 
#endif  /* INCLUDE_FLASH */ 
 
#include "vme/nullVme.c" 
#include "sysSerial.c" 
#include "lpc2210Timer.c" 
#include "lpc2210IntrCtl.c" 
 
#ifdef INCLUDE_NETWORK 
#ifdef INCLUDE_END 
#include "sbcCksum.c" 
#include "sysEnd.c" 
#endif /* INCLUDE_END */ 
#endif /* INCLUDE_NETWORK */ 
 
#ifdef INCLUDE_LCD 
#include "sysLcd.c" 
#endif /* INCLUDE_LCD */ 
 
#ifdef INCLUDE_LED 
#include "sysLed.c" 
#endif /* INCLUDE_LCD */ 
 
#ifdef INCLUDE_VWARE_LAUNCH 
#include "sysVware.c" 
#endif /* INCLUDE_VWARE_LAUNCH */ 
 
/*  : added */ 
extern void excEnterUndef(void); 
extern void excEnterSwi(void); 
extern void excEnterPrefetchAbort(void); 
extern void excEnterDataAbort(void); 
extern void intEnt(void); 
 
/****************************************************************************** 
* 
* portInit - 针对硬板,初始化CPU各端口 
*  
*/ 
static void portInit(void) 
{ 
    /* 蜂鸣器*/ 
    IO0DIR = BEEPCON; 
    IO0SET = BEEPCON; 
    IO2DIR = LEDCON; 
    IO2SET = LEDCON; 
 
    PINSEL0 = 0x05;                 /* P0.0 and P0.1 are set to UART0 */ 
    PINSEL1 = 3<<8;                 /* ExtInt3连到P0.20 */ 
    EXTMODE = 0x08;                /* ExtInt3沿触发*/ 
    EXTPOLAR = 0;               /* 下降沿触发*/ 
    EXTINT = 0xf;                  /* 清除ExtInt的中断标志*/ 
} 
 
#if 0 
/****************************************************************************** 
* 
* rtl8019Init - RTL8019网络芯片初始化(与NE2000不兼容) 
* loopDelay - 循环延时函数,每个时间单位为100us 
*/ 
static int delayLoopCount = 400; 
static void loopDelay(int time) 
{ 
  int i; 
  for(;time>0;time--) 
    for(i=0;i 
* 
* This function returns a pointer to a bsp version with the revision. 
* for eg. 1.1/. BSP_REV is concatenated to BSP_VERSION to form the 
* BSP identification string. 
* 
* RETURNS: A pointer to the BSP version/revision string. 
*/ 
 
char * sysBspRev (void) 
    { 
    return (BSP_VERSION BSP_REV); 
    } 
 
/****************************************************************************** 
* 
* sysHwInit - initialize the CPU board hardware 
* 
* This routine initializes various features of the hardware. 
* Normally, it is called from usrInit() in usrConfig.c. 
* 
* NOTE: This routine should not be called directly by the user. 
* 
* RETURNS: N/A 
*/ 
 
void sysHwInit (void) 
{ 
    /*  : added */ 
    portInit(); 
/*    rtl8019Init();    */ 
	 
    /* install the IRQ/SVC interrupt stack splitting routine */ 
 
    _func_armIntStackSplit = sysIntStackSplit; 
#ifdef INCLUDE_LCD	/*  : added */ 
    sysLcdInit(); /* initialize the LCD panel */ 
 
    sysLcdWriteString("   WindRiver    ", 1, 1); 
#if (_BYTE_ORDER == _LITTLE_ENDIAN) 
#if   (CPU == ARMARCH4) 
    sysLcdWriteString("   SBC ARM7     ", 2, 1); 
#else  /* ARMARCH4 */ 
    sysLcdWriteString("   SBC ARM7 (t) ", 2, 1); 
#endif  /* ARMARCH4 */ 
#else /* (_BYTE_ORDER == _LITTLE_ENDIAN) */ 
 
#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */ 
#endif /*INCLUDE_LCD*/ 
#ifdef INCLUDE_LED	/*  : added */ 
    sysLedInit(); /* initialize the LED */ 
#endif /*INCLUDE_LED*/ 
    /* Set the MAC address based on DIP setting 
     * The least significant byte of the address is changed to 
     * the value of the user DIP switch setting. SW4-D0 is the 
     * least significant bit of this byte.  We invert the bits 
     * so Open=0. 
     */ 
 
    /*sysSngks32cMacAddr[5] = ~READ_USERDIP();*/	/*  : deleted */ 
 
#ifdef  FORCE_DEFAULT_BOOT_LINE 
    strncpy(sysBootLine,DEFAULT_BOOT_LINE,strlen(DEFAULT_BOOT_LINE)+1); 
#elif defined INCLUDE_VWARE_LAUNCH 
    sysVwareBuildBootLine((char*)&sysSngks32cMacAddr); 
#endif /* FORCE_DEFAULT_BOOT_LINE */ 
 
    sysSerialHwInit ();      /* initialize serial data structure */ 
} 
 
/****************************************************************************** 
* 
* sysHwInit2 - additional system configuration and initialization 
* 
* This routine connects system interrupts and does any additional 
* configuration necessary. 
* 
* RETURNS: N/A 
* 
* NOMANUAL 
* 
* Note: this is called from sysClkConnect() in the timer driver. 
*/ 
 
void sysHwInit2 (void) 
{ 
    /* initialize the interrupt library and interrupt driver */ 
    intLibInit (LPC2210_INTNUMLEVELS, LPC2210_INTNUMLEVELS, INT_MODE); 
    lpc2210IntDevInit(); 
 
    /* connect sys clock interrupt and auxiliary clock interrupt */ 
    (void)intConnect(INT_VEC_TIMER0, sysClkInt, 0); 
    /*(void)intConnect(INT_VEC_TIMER1, sysAuxClkInt, 0);*/ 
    (void)intConnect(INT_VEC_EXTINT3, (VOIDFUNCPTR)IRQ_Eint3, 0); 
     
    /* connect serial interrupt */ 
    sysSerialHwInit2(); 
} 
 
/****************************************************************************** 
* 
* sysPhysMemTop - get the address of the top of physical memory 
* 
* This routine returns the address of the first missing byte of memory, 
* which indicates the top of memory. 
* 
* Normally, the user specifies the amount of physical memory with the 
* macro LOCAL_MEM_SIZE in config.h.  BSPs that support run-time 
* memory sizing do so only if the macro LOCAL_MEM_AUTOSIZE is defined. 
* If not defined, then LOCAL_MEM_SIZE is assumed to be, and must be, the 
* true size of physical memory. 
* 
* NOTE: Do no 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) 
        { 
#ifdef LOCAL_MEM_AUTOSIZE 
 
        /* If auto-sizing is possible, this would be the spot.  */ 
 
#    error   "Dynamic memory sizing not supported" 
 
#else 
        /* Don't do autosizing, if size is given */ 
 
        physTop = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE); 
 
#endif /* LOCAL_MEM_AUTOSIZE */ 
        } 
 
    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.  It is usually called 
* only by reboot() -- which services ^X -- and bus errors at interrupt 
* level.  However, in some circumstances, the user may wish to introduce a 
* new  to enable special boot ROM facilities. 
* 
* RETURNS: Does not return. 
*/ 
 
STATUS sysToMonitor 
    ( 
    int startType    /* passed to ROM to tell it how to boot */ 
    ) 
    { 
    FUNCPTR     pRom; 
    UINT32 *    p = (UINT32 *)ROM_TEXT_ADRS; 
#ifdef INCLUDE_SNGKS32C_END 
    END_OBJ *   pEnd; 
#endif 
 
    /* 
     * Examine ROM - if it's a VxWorks boot ROM, jump to the warm boot entry 
     * point; otherwise jump to the start of the ROM. 
     * A VxWorks boot ROM begins 
     *    MOV    R0,#BOOT_COLD 
     *    B    ... 
     *    DCB    "Copyright" 
     * We check the first and third words only. This could be tightened up 
     * if required (see romInit.s). 
     */ 
 
#if (_BYTE_ORDER == _LITTLE_ENDIAN) 
    if (p[0] == 0xE3A00002 && p[2] == 0x79706F43) 
        pRom = (FUNCPTR)(ROM_TEXT_ADRS + 4);    /* warm boot address */ 
    else 
        pRom = (FUNCPTR)ROM_TEXT_ADRS;        /* start of ROM */ 
#else /* (_BYTE_ORDER == _LITTLE_ENDIAN) */ 
    if (p[0] == 0xE3A00002 && p[2] == 0x436F7079) 
        pRom = (FUNCPTR)(ROM_TEXT_ADRS + 4);    /* warm boot address */ 
    else 
        pRom = (FUNCPTR)ROM_TEXT_ADRS;        /* start of ROM */ 
#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */ 
 
#ifdef INCLUDE_SNGKS32C_END 
    /* 
     * Reset Ethernet controller to prevent it doing anything 
     * before jumping to the bootrom. 
     */ 
 
    pEnd = endFindByName ("sng", 0); 
 
    if (pEnd != NULL) 
        pEnd->pFuncTable->stop(pEnd->devObject.pDevice); 
#endif /* INCLUDE_SNGKS32C_END */ 
 
    (*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. 
* 
* SEE ALSO: sysProcNumSet() 
*/ 
 
int sysProcNumGet (void) 
    { 
    return 0; 
    } 
 
/**************************************************************************** 
* 
* sysProcNumSet - set the processor number 
* 
* Set the processor number for the CPU board.  Processor numbers should be 
* unique on a single backplane. 
* 
* NOTE 
* By convention, only processor 0 should dual-port its memory. 
* 
* RETURNS: N/A 
* 
* SEE ALSO: sysProcNumGet() 
*/ 
 
void sysProcNumSet 
    ( 
    int procNum        /* processor number */ 
    ) 
    { 
    sysProcNum = procNum; 
    } 
 
#ifdef INCLUDE_FLASH 
 
/* default procedures assume static ram with no special r/w routines */ 
#ifndef NV_RAM_WR_ENBL 
#   define NV_RAM_WR_ENBL    /* no write enable procedure */ 
#endif /*NV_RAM_WR_ENBL*/ 
 
#ifndef NV_RAM_WR_DSBL 
#   define NV_RAM_WR_DSBL    /* no write disable procedure */ 
#endif /*NV_RAM_WR_DSBL*/ 
 
#ifndef NV_RAM_READ 
#   define NV_RAM_READ(x) \ 
    (*(UCHAR *)((int)NV_RAM_ADRS + ((x) * NV_RAM_INTRVL))) 
#endif /*NV_RAM_READ*/ 
 
#ifndef NV_RAM_WRITE 
#   define NV_RAM_WRITE(x,y) \ 
    (*(UCHAR *)((int)NV_RAM_ADRS + ((x) * NV_RAM_INTRVL)) = (y)) 
#endif /*NV_RAM_WRITE*/ 
     
/****************************************************************************** 
* 
* sysNvRamGet - get the contents of non-volatile RAM 
* 
* This routine copies the contents of non-volatile memory into a specified 
* string.  The string is terminated with an EOS. 
* 
* RETURNS: OK, or ERROR if access is outside the non-volatile RAM range. 
* 
* SEE ALSO: sysNvRamSet() 
*/ 
 
STATUS sysNvRamGet 
    ( 
    char *string,    /* where to copy non-volatile RAM    */ 
    int   strLen,      /* maximum number of bytes to copy   */ 
    int   offset       /* byte offset into non-volatile RAM */ 
    ) 
 
    { 
    STATUS retVal; 
 
    offset += NV_BOOT_OFFSET;   /* boot line begins at  = 0 */ 
 
    if ((offset < 0) 
     || (strLen < 0) 
     || ((offset + strLen) > NV_RAM_SIZE)) 
        return (ERROR); 
 
    retVal = sysFlashGet (string, strLen, offset); 
    string [strLen] = EOS; 
 
    return (OK); 
    } 
 
/****************************************************************************** 
* 
* sysNvRamSet - write to non-volatile RAM 
* 
* This routine copies a specified string into non-volatile RAM. 
* 
* RETURNS: OK, or ERROR if access is outside the non-volatile RAM range. 
* 
* SEE ALSO: sysNvRamGet() 
*/ 
 
STATUS sysNvRamSet 
    ( 
    char *string,     /* string to be copied into non-volatile RAM */ 
    int strLen,       /* maximum number of bytes to copy           */ 
    int offset        /* byte offset into non-volatile RAM         */ 
    ) 
 
    { 
    offset += NV_BOOT_OFFSET;   /* boot line begins at  = 0 */ 
 
    if ((offset < 0) 
     || (strLen < 0) 
     || ((offset + strLen) > NV_RAM_SIZE)) 
        return ERROR; 
 
    NV_RAM_WR_ENBL; 
 
    return (sysFlashSet (string, strLen, offset)); 
 
    } 
 
/****************************************************************************** 
* 
* sysFlashBoardDelay - create a delay 
* 
* This routine is used by flashMem.c to produce specified delays. It 
* appears that the Flash driver cannot use taskDelay() at certain 
* points. 
* 
* RETURNS: N/A 
*/ 
 
void sysFlashBoardDelay (void) 
    { 
    return; 
    } 
#endif /* INCLUDE_FLASH */ 
 
#ifdef DEBUG 
/****************************************************************************** 
* 
* sysDebug - print message using polled serial driver 
* 
* Use the polled driver to print debug messages.  Useful before the full 
* hardware initialization is complete (but only after sysHwInit). 
* 
* RETURNS: N/A. 
* 
* NOMANUAL 
*/ 
 
void sysDebug 
    ( 
    char *str 
    ) 
    { 
    int msgSize; 
    int msgIx; 
    LOCAL SIO_CHAN * pSioChan;        /* serial I/O channel */ 
    LOCAL BOOL beenHere = FALSE; 
 
    msgSize = strlen (str); 
 
    if (!beenHere) 
        { 
        sysSerialHwInit (); 
 
        pSioChan = sysSerialChanGet (0); 
 
        sioIoctl (pSioChan, SIO_BAUD_SET, (void *)CONSOLE_BAUD_RATE); 
 
        sioIoctl (pSioChan, SIO_MODE_SET, (void *) SIO_MODE_POLL); 
 
        beenHere = TRUE; 
	} 
 
    for (msgIx = 0; msgIx < msgSize; msgIx++) 
        { 
        while (sioPollOutput (pSioChan, str[msgIx]) == EAGAIN) 
            /* do nothing */; 
        } 
    } 
#endif /* DEBUG */