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


/* sysLib.c - Samsung SBC ARM7 system-dependent routines */ 
 
 
/* Copyright 1984-2002 Wind River Systems, Inc. */ 
#include "copyright_wrs.h" 
 
/* 
modification history 
-------------------- 
01o,29jul04,a_m  BSP定制 for 多刃剑开发板 
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 
    sngks32cTimer.c   -     SNGKS32CARM7 timer driver 
    sngks32cIntrCtl.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" 
 
/* 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 */ 
 
/*  : 21->26 */ 
#if S3C44B0X_INTNUMLEVELS != 26 
#   error sbcIntLvlMask is wrong size for number of levels 
#endif 
 
 
/* defines */ 
 
     
/* externals */ 
 
IMPORT void   sngks32cIntDevInit (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); 
 
#ifdef INCLUDE_CACHE_SUPPORT 
STATUS sngks32cCacheLibInit(CACHE_MODE instMode, CACHE_MODE dataMode); 
FUNCPTR sysCacheLibInit = sngks32cCacheLibInit; 
 
void   sysDebug (char *str); 
void   sngks32cCacheFlush    (void);   
void * sngks32cCacheDmaMalloc(size_t bytes); 
STATUS sngks32cCacheDmaFree  (void *pBuf); 
void   sngks32cCacheEnable   (void); 
void   sngks32cCacheDisable  (void); 
void * sngks32cPhysToVirtRtn (void *adrs); 
void * sngks32cVirtToPhysRtn (void *adrs); 
#endif /*INCLUDE_CACHE_SUPPORT*/ 
 
/* 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 "sngks32cTimer.c" 
#include "sngks32cIntrCtl.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) 
{ 
  /*  BIT   9   8   7   6   5   4   3   2   1   0 */ 
  /*  A24   A23 A22 A21 A20 A19 A18 A17 A16 A0  */         
  /*  0   1 1 1 1 1 1 1 1 1 */ 
  rPCONA = 0x3ff;  
  rPDATA = 0x3ff; 
  /*  BIT 10  9   8   7   6   5   4   3   2   1   0   */ 
  /*  /CS5  /CS4  /CS3  /CS2  /CS1  nWBE3 nWBE2 /SRAS /SCAS SCLK  SCKE  */ 
  /*  EXT   NIC   USB   IDE   SMC   NC    NC    Sdram Sdram Sdram Sdram */ 
  /*      0,        0,   0,   0,    1,    0,       0,     1,    1,    1,   1          */ 
  rPDATB = 0x7ff; 
  rPCONB = 0x7ff; 
  /*  PC15    14    13    12    11    10    9   8 */ 
  /*  o   o   RXD1  TXD1  o   o   o   o */ 
  /*  NC    NC    Uart1 Uart1 NC    NC    NC    NC  */ 
  /*   11   11    11    11    11    11    01    00  */ 
 
  /*  PC7   6   5   4   3   2   1   0 */ 
  /*   o    o   o   o   o   o   o   o */ 
  /*   NC   NC    NC    NC    SMCALE  SMCCLE  SMCCE SMCRB*/ 
  /*   01   01    01    01    01    01    01    01  */ 
  rPDATC = 0x0000;   
  rPCONC = 0xFFF5FFFF;   
  rPUPC  = 0xFC00;   
  /*  PORT D GROUP(I/O OR LCD)                    */ 
  /*  BIT7    6   5   4   3   2   1   0 */ 
  /*      VF    VM    VLINE VCLK  VD3   VD2   VD1   VD0 */ 
  /*     01   01    01    01    01    01    01    01  */ 
  rPDATD= 0x55; 
  rPCOND= 0xaaaa;  
  rPUPD = 0x00; 
  /*  Bit 8   7   6   5   4   3   2   1   0   */ 
  /*    ENDLAN  LED3  LED2  LED1  LED0  BEEP  RXD0  TXD0  CLKOUT  */  
  /*      00    01    01    01    01    01    10    10    00    */ 
  rPDATE  = 0x157; 
  rPCONE  = 0x25569;  
  rPUPE = 0xff; 
  /*  Bit8    7   6   5    4    3   2   1   0   */    
  /*  IISCLK  IISDI IISDO IISLRCK Input Input Input IICSDA  IICSCL  */ 
  /*  100   100   100   100   00    01    01    10    10    */ 
  rPDATF = 0x0; 
  rPCONF = 0x1B6D5A; 
  rPUPF  = 0x1E3; 
  /*  BIT7    6   5   4   3   2   1   0  */ 
  /*  INT7    INT6    INT5    INT4    INT3    INT2    INT1    INT0  */ 
  /*    S3    S4    S5    S6    NIC   EXT   IDE   USB */ 
  /*      11      11      11      11      11      11      11      11       */ 
  rPDATG = 0xFF; 
  rPCONG = 0xFFFF; 
  rPUPG  = 0x00;   
 
  rSPUCR=0x7;   
 
  /*定义非Cache区*/ 
  /*rNCACHBE0 = 0xc0002000; */ 
 
  rEXTINT=0x0444;	/*网卡使用EXTINT1,上升沿触发*/ 
} 
 
/****************************************************************************** 
* 
* 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(); 
    s3cExcVecSet(); 
	 
    /* 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) */ 
#if   (CPU == ARMARCH4) 
    sysLcdWriteString("  SBC ARM7 (BE) ", 2, 1); 
#else  /* ARMARCH4 */ 
    sysLcdWriteString("  SBC ARM7 (tBE)", 2, 1); 
#endif  /* ARMARCH4 */ 
#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 (S3C44B0X_INTNUMLEVELS, S3C44B0X_INTNUMLEVELS, INT_MODE); 
    sngks32cIntDevInit(); 
 
    /* connect sys clock interrupt and auxiliary clock interrupt */ 
 
    (void)intConnect (INUM_TO_IVEC (INT_VEC_TIMER0), sysClkInt, 0); 
    (void)intConnect (INUM_TO_IVEC (INT_VEC_TIMER1), sysAuxClkInt, 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 
 
#ifdef INCLUDE_CACHE_SUPPORT 
    sngks32cCacheDisable(); 
#endif /* INCLUDE_CACHE_SUPPORT */ 
 
    /* 
     * 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 INCLUDE_CACHE_SUPPORT 
 
/****************************************************************************** 
* 
* sngks32cCacheLibInit - initialize ARM cache library function pointers 
* 
* This routine initializes the cache library for SNG32C processor.  It 
* initializes the function pointers and configures the caches to the 
* specified cache modes.  Modes should be set before caching is 
* enabled.  If two complementary flags are set (enable/disable), no 
* action is taken for any of the input flags. 
* 
* INTERNAL 
* This routine is called (from cacheLibInit()), before sysHwInit has 
* been called, and before BSS has been cleared. 
* 
* RETURNS: OK always 
* 
*/ 
 
STATUS sngks32cCacheLibInit 
    ( 
    CACHE_MODE    instMode,    /* instruction cache mode */ 
    CACHE_MODE    dataMode    /* data cache mode */ 
    ) 
    { 
 
#if ((ARMCACHE == ARMCACHE_KS32C)) 
    cacheLib.enableRtn               = (FUNCPTR) sngks32cCacheEnable; 
    cacheLib.disableRtn              = (FUNCPTR) sngks32cCacheDisable; 
    cacheLib.flushRtn                = (FUNCPTR) sngks32cCacheFlush; 
    cacheLib.invalidateRtn           = (FUNCPTR) NULL; 
    cacheLib.clearRtn                = (FUNCPTR) NULL; 
    cacheLib.textUpdateRtn           = (FUNCPTR) NULL; 
    cacheLib.pipeFlushRtn            = (FUNCPTR) NULL; 
    cacheLib.dmaMallocRtn            = (FUNCPTR) sngks32cCacheDmaMalloc; 
    cacheLib.dmaFreeRtn              = (FUNCPTR) sngks32cCacheDmaFree; 
    sngks32cCacheFuncs.virtToPhysRtn = (FUNCPTR) sngks32cVirtToPhysRtn; 
    sngks32cCacheFuncs.physToVirtRtn = (FUNCPTR) sngks32cPhysToVirtRtn; 
 
    if ( 
    (instMode & CACHE_WRITEALLOCATE)    || 
    (dataMode & CACHE_WRITEALLOCATE)    || 
    (instMode & CACHE_NO_WRITEALLOCATE)    || 
    (dataMode & CACHE_NO_WRITEALLOCATE)    || 
    (instMode & CACHE_SNOOP_ENABLE)        || 
    (dataMode & CACHE_SNOOP_ENABLE)        || 
    (instMode & CACHE_SNOOP_DISABLE)    || 
    (dataMode & CACHE_SNOOP_DISABLE)    || 
    (instMode & CACHE_BURST_ENABLE)        || 
    (dataMode & CACHE_BURST_ENABLE)        || 
    (instMode & CACHE_BURST_DISABLE)    || 
    (dataMode & CACHE_BURST_DISABLE)) 
        return ERROR; 
 
    /* This has combined Instruction and Data caches */ 
    if (instMode != dataMode) 
        return ERROR; 
 
#else 
#error ARMCACHE type not supported here 
#endif 
 
 
    return OK; 
    } 
 
/****************************************************************************** 
* 
* sngks32cCacheDmaMalloc - allocate a cache-safe buffer 
* 
* This routine attempts to return a pointer to a section of memory 
* that will not experience cache coherency problems.  This routine 
* is only called when MMU support is available for cache control. 
* 
* RETURNS: A pointer to a cache-safe buffer, or NULL. 
* 
* SEE ALSO: sngks32cCacheDmaFree(), cacheDmaMalloc() 
* 
* NOMANUAL 
*/ 
 
void * sngks32cCacheDmaMalloc 
    ( 
    size_t    bytes    /* size of cache-safe buffer */ 
    ) 
    { 
    void   *ptr; 
    UINT32  foo; 
 
    ptr = malloc (bytes); 
    foo = (UINT32)ptr; 
    foo |= NON_CACHE_REGION; 
    ptr = (void *)foo; 
 
    return (ptr); 
 
    } /* cacheArchDmaMalloc() */ 
 
/****************************************************************************** 
* 
* sngks32cCacheDmaFree - free the buffer acquired by cacheArchDmaMalloc() 
* 
* This routine returns to the free memory pool a block of memory previously 
* allocated with cacheArchDmaMalloc().  The buffer is marked cacheable. 
* 
* RETURNS: OK, or ERROR if cacheArchDmaMalloc() cannot be undone. 
* 
* SEE ALSO: sngks32cCacheDmaMalloc(), cacheDmaFree() 
* 
* NOMANUAL 
*/ 
 
STATUS sngks32cCacheDmaFree 
    ( 
    void *    pBuf        /* ptr returned by cacheArchDmaMalloc() */ 
    ) 
    { 
 
    UINT32 foo; 
 
    foo = (UINT32) pBuf; 
    foo &= ~NON_CACHE_REGION; 
    pBuf = (void *)foo; 
	 
    free (pBuf);    /* free buffer after modified */ 
 
    return OK; 
 
    } /* cacheArchDmaFree() */ 
 
/****************************************************************************** 
* 
* sngks32cCacheEnable - enable cache 
* 
* This routine enables cache 
* 
* RETURNS: void 
* 
* SEE ALSO: sngks32cCacheDisable(), sngks32cCacheFlush() 
* 
* NOMANUAL 
*/ 
 
void sngks32cCacheEnable 
    (  
    void 
    ) 
    { 
 
    UINT32    result; 
 
    /* Clear cache-related bits */ 
    SBCARM7_CTRL_REG_READ (S3C44B0X_SYSCFG, result); 
    /*-SBCARM7_CTRL_REG_WRITE (SNGKS32C_SYSCFG, (result & 0xffffffC0));*/ 
	/*  : deleted and added */ 
    SBCARM7_CTRL_REG_WRITE (S3C44B0X_SYSCFG, (result & (~SBCARM7_CACHE_MODE))); 
    SBCARM7_CTRL_REG_READ (S3C44B0X_SYSCFG, result); 
 
	/*  : added */ 
	SBCARM7_CTRL_REG_WRITE (S3C44B0X_NCACHBE0, 0xC0000000); 
	/*SBCARM7_CTRL_REG_WRITE (S3C44B0X_NCACHBE0, 0xC0002000);*/ 
	/*SBCARM7_CTRL_REG_WRITE (S3C44B0X_NCACHBE1, 0xFFFFC800);*/ 
 
#if (SBCARM7_CACHE_SIZE == SBCARM7_CACHE_4K) 
    result &= ~SBCARM7_CACHE_MODE;        /* For 4K Cache */ 
    /*-SBCARM7_CTRL_REG_WRITE (SNGKS32C_SYSCFG, (result | SBCARM7_WRITE_BUFF));*/ 
    sngks32cCacheFlush(); 
	/*  : added */ 
	SBCARM7_CTRL_REG_WRITE (S3C44B0X_SYSCFG, (result | SBCARM7_WRITE_BUFF | SBCARM7_CACHE_4K)); 
 
    /*-SBCARM7_CTRL_REG_READ (S3C44B0X_SYSCFG, result); 
    SBCARM7_CTRL_REG_WRITE (S3C44B0X_SYSCFG, (result | SBCARM7_CACHE_ENABLE));*/ 
#endif /* (SBCARM7_CACHE_SIZE == SBCARM7_CACHE_4K) */ 
 
#if (SBCARM7_CACHE_SIZE == SBCARM7_CACHE_8K)	 
    result &= ~SBCARM7_CACHE_MODE;        /* Clear mode bits */ 
    /*-SBCARM7_CTRL_REG_WRITE (SNGKS32C_SYSCFG, 
                            (result | SBCARM7_WRITE_BUFF | SBCARM7_CACHE_8K));*/ 
    sngks32cCacheFlush(); 
	/*  : added */	 
	SBCARM7_CTRL_REG_WRITE (S3C44B0X_SYSCFG, (result | SBCARM7_WRITE_BUFF | SBCARM7_CACHE_8K)); 
 
    /*-SBCARM7_CTRL_REG_READ (S3C44B0X_SYSCFG, result); 
    SBCARM7_CTRL_REG_WRITE(S3C44B0X_SYSCFG, (result | SBCARM7_CACHE_ENABLE));*/ 
#endif /* (SBCARM7_CACHE_SIZE == SBCARM7_CACHE_8K) */ 
    } 
 
 
/****************************************************************************** 
* 
* sngks32cCacheDisable - disable cache 
* 
* This routine disables cache 
* 
* RETURNS: void 
* 
* SEE ALSO: sngks32cCacheEnable(), sngks32cCacheFlush() 
* 
* NOMANUAL 
*/ 
 
void sngks32cCacheDisable 
    ( 
    void 
    ) 
    { 
    UINT32 result; 
 
    SBCARM7_CTRL_REG_READ(S3C44B0X_SYSCFG, result); 
    /*  : SBCARM7_CACHE_ENABLE->SBCARM7_CACHE_MODE */ 
    SBCARM7_CTRL_REG_WRITE(S3C44B0X_SYSCFG, 
                           (result & ~(SBCARM7_CACHE_MODE))); 
    } 
 
/****************************************************************************** 
* 
* sngks32cCacheFlush - flush the cache 
* 
* This routine flushes the cache 
* 
* RETURNS: void 
* 
* SEE ALSO: sngks32cCacheEnable(), sngks32cCacheDisable() 
* 
* NOMANUAL 
*/ 
/*  : 修改较多,如循环次数,地址进位,重新使能等 */ 
void sngks32cCacheFlush(void) 
{ 
    int i, num; 
    UINT32 *tagram; 
	UINT32 addr; 
 
	addr = SBCARM7_TAGRAM_BEG; 
	num = (SBCARM7_TAGRAM_END - SBCARM7_TAGRAM_BEG)/16; 
    sngks32cCacheDisable(); 
    for(i=0; i < num; i++) 
    { 
        tagram = (UINT32 *)addr; 
        *tagram = 0x00000000;  
        addr += 16; 
    } 
	SBCARM7_CTRL_REG_WRITE (S3C44B0X_SYSCFG, (SBCARM7_WRITE_BUFF | SBCARM7_CACHE_8K)); 
} 
 
/****************************************************************************** 
* 
* sngks32cPhysToVirtRtn - force memory to cacheable region 
* 
* This routine clears the "non-cache" bit on an address to force it to use 
* the cacheable region of memory 
* 
* RETURNS: void 
* 
* SEE ALSO: sngks32cCacheEnable(), sngks32cCacheDisable() 
* 
* NOMANUAL 
*/ 
 
void * sngks32cPhysToVirtRtn  
    ( 
    void *adrs 
    ) 
 
    { 
    UINT32 foo; 
 
    foo = (UINT32)adrs; 
    foo &= ~NON_CACHE_REGION; 
    adrs = (void *) foo; 
    return adrs; 
    } 
 
/****************************************************************************** 
* 
* sngks32cVirtToPhysRtn - force memory to non-cacheable region 
* 
* This routine sets the "non-cache" bit on an address to force it to use 
* the non-cacheable region of memory 
* 
* RETURNS: void 
* 
* SEE ALSO: sngks32cCacheEnable(), sngks32cCacheDisable() 
* 
* NOMANUAL 
*/ 
 
void * sngks32cVirtToPhysRtn  
    ( 
    void *adrs 
    ) 
     
    { 
    UINT32 foo; 
 
    foo = (UINT32)adrs; 
    foo |= NON_CACHE_REGION; 
    adrs = (void *) foo; 
    return adrs; 
    } 
 
#endif    /* INCLUDE_CACHE_SUPPORT */ 
 
#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 */