www.pudn.com > S3c2410bsp.zip > 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 */