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


/* sysLib.c - Samsung SBC ARM9 system-dependent routines */

/* Copyright 2004-2005  */

/* Copyright 1984-2002 Wind River Systems, Inc. */
#include "copyright_wrs.h"



#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 "wrSbcArm9.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   s3c2410xCacheFuncs;
/* : sysSngks32cMacAddr->ne2000EnetAddr */
unsigned char ne2000EnetAddr[] = ETHERNET_MAC_ADRS;

/* locals */

/* : 21->26 */
#if S3C2410X_INTLEVEL_NUM != 32
#   error sbcIntLvlMask is wrong size for number of levels
#endif


/* defines */

#define _WR(ulADDR,usDATA)	*((volatile unsigned short *)(ulADDR<<1))=(unsigned short)usDATA

    
/* externals */

IMPORT void   s3c2410xIntDevInit (void);
IMPORT void   sysIntStackSplit (char *, long);

/*local defines*/
#ifndef SBCARM9_CTRL_REG_READ
#   define SBCARM9_CTRL_REG_READ(x,result) \
        ((result) = *(volatile UINT32 *)(x))
#endif    /*SBCARM9_READ*/

#ifndef SBCARM9_CTRL_REG_WRITE
#   define SBCARM9_CTRL_REG_WRITE(x,data) \
        (*((volatile UINT32 *)(x)) = (data))
#endif /*SBCARM9_WRITE*/



/* globals */


unsigned char Verify(unsigned long ulRomAddr,unsigned long ulRamAddr,unsigned long ulRomSize);
unsigned char _WAIT(unsigned long ulAddr) ;
unsigned char SST39VF160_WordProg_Test(unsigned long ulAddr,unsigned short usData);
unsigned char SST39VF160_ChipProg(unsigned long ulRomAddr,unsigned long ulRamAddr,unsigned long ulRomSize);
unsigned char SST39VF160_SectorErase(unsigned long ulAddr);

char *    sysPhysMemTop (void);

#ifdef INCLUDE_CACHE_SUPPORT
STATUS s3c2410xCacheLibInit(CACHE_MODE instMode, CACHE_MODE dataMode);
FUNCPTR sysCacheLibInit = s3c2410xCacheLibInit;

void   sysDebug (char *str);
void   s3c2410xCacheFlush    (void);  
void * s3c2410xCacheDmaMalloc(size_t bytes);
STATUS s3c2410xCacheDmaFree  (void *pBuf);
void   s3c2410xCacheEnable   (void);
void   s3c2410xCacheDisable  (void);
void * s3c2410xPhysToVirtRtn (void *adrs);
void * s3c2410xVirtToPhysRtn (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 "s3c2410xTimer.c"
#include "s3c2410xIntrCtl.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 */

extern void excEnterUndef(void);
extern void excEnterSwi(void);
extern void excEnterPrefetchAbort(void);
extern void excEnterDataAbort(void);
extern void intEnt(void);

/******************************************************************************
*
* 
*/
static void portInit(void)
{

  
  rPCONA = 0x01ffff; 
  rPDATA = 0x000000;
  

  
  rPCONB = 0x2aa955;
  rPDATB = 0x000;
  rPUPB  = 0xfff;
  
  
  rPCONC = 0x00005555;     
  rPDATC = 0x0001; 
  rPUPC  = 0x4100;     


  rPCOND= 0x55555555;
  rPDATD= 0x0000; 
  rPUPD = 0xc040;

 
  rPCONE  = 0xaa8002aa;
  rPDATE  = 0x0000; 
  rPUPE =   0xf81f;

  
  rPCONF = 0xaa8a;
  rPDATF = 0x00;  
  rPUPF  = 0xff;

  rPCONG = 0x00b000f0;
  rPDATG = 0x0000;
  rPUPG  = 0x08fb;  


  
  rPCONH= 0x15faaa;
  rPDATH= 0xFFDF;
  rPUPH= 0x7bf; 

  rMISCCR=0x43550;  

  rDCLKCON = 0x7f007f0;

 
  rEXTINT1 = 0x00000444;

  rEXTINT2 = 0x00000000;

  rEXINTFLT2 = 0x00000000;

  rEXINTFLT3 = 0x00000000;

  rEXINTMASK = 0x00fffff0;

  rEXINTPND = 0x00fffff0;

  

}

/******************************************************************************
*
*/
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
* NOTE: This routine should not be called directly by the user.
*
* RETURNS: N/A
*/

void sysHwInit (void)
    {
    
    portInit();	
    
    rtl8019Init();
    s3cExcVecSet();
	
    _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 ARM9     ", 2, 1);
#else  /* ARMARCH4 */
    sysLcdWriteString("   SBC ARM9 (t) ", 2, 1);
#endif  /* ARMARCH4 */
#else /* (_BYTE_ORDER == _LITTLE_ENDIAN) */
#if   (CPU == ARMARCH4)
    sysLcdWriteString("  SBC ARM9 (BE) ", 2, 1);
#else  /* ARMARCH4 */
    sysLcdWriteString("  SBC ARM9 (tBE)", 2, 1);
#endif  /* ARMARCH4 */
#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */
#endif /*INCLUDE_LCD*/
#ifdef INCLUDE_LED	/* : added */
    sysLedInit(); /* initialize the LED */
#endif /*INCLUDE_LED*/

#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)
    {


    intLibInit (S3C2410X_INTLEVEL_NUM, S3C2410X_INTLEVEL_NUM, INT_MODE);
    s3c2410xIntDevInit();


    (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
*
*
* 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


#    error   "Dynamic memory sizing not supported"

#else

        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
*
*
* 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
*
*
* 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_S3C2410X_END
    END_OBJ *   pEnd;
#endif

#ifdef INCLUDE_CACHE_SUPPORT
    s3c2410xCacheDisable();
#endif /* INCLUDE_CACHE_SUPPORT */


#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_S3C2410X_END

    pEnd = endFindByName ("sng", 0);

    if (pEnd != NULL)
        pEnd->pFuncTable->stop(pEnd->devObject.pDevice);
#endif /* INCLUDE_S3C2410X_END */

    (*pRom)(startType);    /* jump to bootrom */

    return OK;        /* in case we ever continue from ROM monitor */
    }

/****************************************************************************
*
* sysProcNumGet - get the processor number
*
*
* RETURNS: The processor number for the CPU board.
*
* SEE ALSO: sysProcNumSet()
*/

int sysProcNumGet (void)
    {
    return 0;
    }

/****************************************************************************
*
* sysProcNumSet - set the processor number
*
* 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
*
*
* 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
*
*
* 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
*
*
* RETURNS: N/A
*/

void sysFlashBoardDelay (void)
    {
    return;
    }
#endif /* INCLUDE_FLASH */


STATUS sysRomGet(char *string, int   strLen,   int   offset )

    {
    /*STATUS retVal;*/

    if ((offset < 0)
     || (strLen < 0))
        return (ERROR);

    /*retVal = copyLongs (offset, string, strLen);*/
    /*copyString (offset, string, strLen);*/
    bcopyBytes ((char *) (offset), string, strLen);
    string [strLen] = EOS;

    return (OK);
    }


unsigned char SST39VF160_ChipProg(unsigned long ulRomAddr,unsigned long ulRamAddr,unsigned long ulRomSize)
{
	unsigned long i,j,ulRomAddrOri,ulRamAddrOri,ulRomSizeOri;
	/*static int LedCount=0;*/
	unsigned short usData;
	ulRomAddrOri	=ulRomAddr;
	ulRamAddrOri	=ulRamAddr;
	ulRomSizeOri	=ulRomSize;
	SST39VF160_SectorErase(ulRomAddr);
		
	
	for(i=0;i<6553600/3;i++);
	for(i=0;i<(ulRomSize/2);i++)	
	{
		for(j=0;j<200;j++);
		usData=*(unsigned short *)ulRamAddr;
		SST39VF160_WordProg_Test(ulRomAddr,usData);
		ulRomAddr++;
		ulRamAddr+=2;
	} 
	return (Verify(ulRomAddrOri,ulRamAddrOri,ulRomSizeOri));	
}

unsigned char SST39VF160_WordProg_Test(unsigned long ulAddr,unsigned short usData)
{       int level;
	_WR(0x5555,0xaa);
	_WR(0x2aaa,0x55);
	level = intLock();
	_WR(0x5555,0xa0);
	_WR(ulAddr,usData);
	_WAIT(ulAddr);
	intUnlock(level);
	return 1;
}
unsigned char _WAIT(unsigned long ulAddr) 
{
	volatile unsigned short flashStatus,old;
	old=*((volatile unsigned short *)(ulAddr<<1));
	
	while(1)
	{
		flashStatus=*((volatile unsigned short *)(ulAddr<<1));
		
		if( (old&0x40) == (flashStatus&0x40) )
			break;
		else
		   old=flashStatus;
	}
	return 1;
}

unsigned char SST39VF160_SectorErase(unsigned long ulAddr)
{
	int level;
	int i;
	_WR(0x5555,0xaa);
	_WR(0x2aaa,0x55);
	_WR(0x5555,0x80);
	_WR(0x5555,0xaa);
	_WR(0x2aaa,0x55);
	level = intLock();
	_WR(ulAddr,0x30);
	_WAIT(ulAddr);
	for(i=0; i<0x800; i++,ulAddr++){
		   if(*((volatile unsigned short *)(ulAddr<<1)) != 0xffff)  break;
		   
	}	
	_WR(ulAddr,0xf0);
	intUnlock(level);	
	if(i < 0x800)	{
			printf("Debug: sst39vf160_SectorErase fail.\n");
			return 0;
	}
  return 1;
}
unsigned char Verify(unsigned long ulRomAddr,unsigned long ulRamAddr,unsigned long ulRomSize)
{
	unsigned long i;
	for (i=0x0;iSBCARM9_CACHE_MODE */
    SBCARM9_CTRL_REG_WRITE(S3C2410X_SYSCFG,
                           (result & ~(SBCARM9_CACHE_MODE)));
    }

/******************************************************************************
*
* s3c2410xCacheFlush - flush the cache
*
* This routine flushes the cache
*
* RETURNS: void
*
* SEE ALSO: s3c2410xCacheEnable(), s3c2410xCacheDisable()
*
* NOMANUAL
*/
void s3c2410xCacheFlush(void)
{
    int i, num;
    UINT32 *tagram;
	UINT32 addr;

	addr = SBCARM9_TAGRAM_BEG;
	num = (SBCARM9_TAGRAM_END - SBCARM9_TAGRAM_BEG)/16;
    s3c2410xCacheDisable();
    for(i=0; i < num; i++)
    {
        tagram = (UINT32 *)addr;
        *tagram = 0x00000000; 
        addr += 16;
    }
	SBCARM9_CTRL_REG_WRITE (S3C2410X_SYSCFG, (SBCARM9_WRITE_BUFF | SBCARM9_CACHE_8K));
}

/******************************************************************************
*
* s3c2410xPhysToVirtRtn - 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: s3c2410xCacheEnable(), s3c2410xCacheDisable()
*
* NOMANUAL
*/

void * s3c2410xPhysToVirtRtn 
    (
    void *adrs
    )

    {
    UINT32 foo;

    foo = (UINT32)adrs;
    foo &= ~NON_CACHE_REGION;
    adrs = (void *) foo;
    return adrs;
    }

/******************************************************************************
*
* s3c2410xVirtToPhysRtn - 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: s3c2410xCacheEnable(), s3c2410xCacheDisable()
*
* NOMANUAL
*/

void * s3c2410xVirtToPhysRtn 
    (
    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 */