Files
vxWorks/bsps/ls2k1000/sysLib.c
2025-08-21 11:21:20 +08:00

960 lines
28 KiB
C

/* sysLib.c - BCM1250 system-dependent routines */
/*
* Copyright (c) 2001-2002, 2004-2008 Wind River Systems, Inc.
*
* The right to copy, distribute or otherwise make use of this software
* may be licensed only pursuant to the terms of an applicable Wind River
* license agreement.
*/
/*
* This file has been developed or significantly modified by the
* MIPS Center of Excellence Dedicated Engineering Staff.
* This notice is as per the MIPS Center of Excellence Master Partner
* Agreement, do not remove this notice without checking first with
* WR/Platforms MIPS Center of Excellence engineering management.
*/
/*
modification history
--------------------
03i,01oct08,pgh Fix clock rate difference between default rate and target
board.
03h,16sep08,slk don't include sysBootSec if INCLUDE_NETWORK not defined
03g,29aug08,kab Change _WRS_VX_SMP to _WRS_CONFIG_SMP
03f,28may08,dlk Use generic vxbDmaBufLib DMA map load routines.
03e,16oct07,pes WIND00108155: vxCpuConfiguredGet returns wrong count (!=1) in
a UP system.
03d,13aug07,slk remove deprecated APIs
03c,27jul07,ami cmdLine.c inclusion removed
03b,28jun07,bwa added DSHM support.
03a,22jun07,slk remove sysCpuNumGet and replace with vxCpuIdGet (from arch)
02z,14jun07,slk shared memory support and move sb1FfsTbl table here from
sysLib.c.
02y,24may07,slk defect 86392 - fix AMP mode support for secondary cpu
02x,03may07,slk remove include of vxbMipsR4KTimer.c and fix cpunum
warning
02w,27apr07,slk hardcode sysClk driver selection
02v,27apr07,slk changes for interrupt controller support
02u,17apr07,rlg fix CACHE_LIB_INIT_FUNC macro
02t,20feb07,ami Made compatible with vxbus timers
02s,04feb07,wap Add support for detecting the system revision
02r,26jan07,pes Arrange for override of assignment of sysCacheLibInit.
02q,18jan07,d_c Correct merge error - remove extra endif
02p,08jan07,pes Add detection of existing bootline in RAM to support warm
boots.
02o,05jan07,rlg update from smp via phil
02n,17nov06,rlg fix mbox names
02m,31oct06,pes Change reference to vxCpuLib.h to vxCpuLibArch.h.
02l,18oct06,jmt Defect 69546 - Add missing code to set boottype
02k,04oct06,pes Set up Mailbox interrupts as highest priority interrupt in
the system.
02j,26sep06,pes Add sysStartType handling from environment variable. Add
sysCpuStart and sysCpuStop functions.
02i,12sep06,pes Use vxCpuLib.h include to get declaration of vxCpuCount.
02h,21aug06,pes Modify strategy of sysToMonitor to assert system_reset bit in
system config register
02g,12aug06,pes Change references to VX_MAX_SMP_CPUS to SB_MAX_SMP_CPUS, as
defined in this BSP.
02f,08aug06,pes Correct usage of VX_MAX_SMP_CPU to VX_MAX_SMP_CPUS.
02e,01aug06,pes Add initialization of vxCpuCount global to cfeInit.
02c,22sep06,pmr add support for DRV_SIO_SB1
02d,19sep06,rlg clean up for romable images and etc.
02c,07sep06,rlg modifications for dual core support
02b,20jul06,wap Update for new vxbDmaBuf API
02a,18jul06,wap Fix project build
01z,07jul06,wap Add VxBus support
01y,23may06,pes Update sysModelStr.
01x,17may06,pes Temporarily add test code.
01w,15may06,pes Adjustments to sysToMonitor() for warm booting.
01v,11may06,pes Add support for starting slave cpu(s).
01u,13apr06,pes Support boot-time detection of CPU_CLOCK_RATE.
01t,10apr06,pes Disable debugging code by default.
01s,14mar06,pes Added INCLUDE_CFE_SUPPORT.
01r,24jan06,rlg SPR 102678 lockout interrupts before jumping to restart
01q,17jan06,pes SPR 109178, 109181, 109182: Use common mipsTlbClear function.
01q,12jan06,jmt Modified sysModel to use SYS_MODEL
01p,23aug05,jmt Componentize BSP for scalability
01o,03aug05,dr Decoupled for scalability.
01n,16nov04,mdo Documentation fixes for apigen
01m,07oct04,agf remove use of LOCAL_MEM_LOCAL_ADRS_RUNT
01l,07oct04,agf addt'l vxWorks 6.0 clean-up
01k,06oct04,pes Change INCLUDE_MMU_BASIC to INCLUDE_MAPPED_KERNEL
01j,18aug04,md PM_RESERVED_MEM is dependent on INCLUDE_EDR_PM
01i,03aug04,agf change MMU include from FULL to BASIC
01h,23jun04,agf remove exc vector init, handled by arch code
01k,17may04,agf AIM AD-MMU support (kernel in KSEG2)
01j,03oct02,agf changes for shared sentosa support
01i,18jul02,pgh Use R4K library timer.
01h,25jun02,pgh Add calls to enable L2 cache.
01g,20jun02,pgh Change path to bcm1250Lib.h.
01f,13mar02,agf remove cond compiles for obj module loader types, SPR 73892
change SM_OBJ conditional compiles to SM_COMMON, SPR 74321
01e,21jan02,tlc Remove specialization of sysBusTas() by removing SYS_BUS_TAS
macro.
01d,04jan02,agf add nvRAM support supplied by Z.Chen
01d,17jan02,agf make sysForceLink vars global so diab will not optimize them
out
01c,20dec01,agf add references to symbols in bcm1250L2Cache.s and
bcm1250DramInit.s to make sure they are in the partial link
objects when building vxWorks_rom et al
01c,20dec01,tlc Remove unecessary include files.
01b,07dec01,agf remove vestigial #if 0 code from sysHwInit2
01a,15nov01,agf written.
*/
/*
DESCRIPTION
This library provides board-specific routines for the Broadcom BCM1250-
swarm evaluation board.
INCLUDE FILES: sysLib.h
*/
/* includes (header file)*/
#include <vxWorks.h>
#include <vsbConfig.h>
#include <stdio.h>
#include <version.h>
#include <ctype.h>
#include <cacheLib.h>
#include <fppLib.h>
#include <ioLib.h>
#include <intLib.h>
#include <sysLib.h>
#include <string.h>
#include <arch/mips/fppMipsLib.h>
#include <arch/mips/vxCpuArchLib.h>
#include "config.h"
extern void printstr(char *s);
extern void printnum(unsigned long long n);
extern int cfe_cpu_stop(int cpu);
extern void MIPS_LS2k_conf_write32(UINT32 address,UINT32 value);
extern UINT32 MIPS_LS2k_conf_read32(UINT32 address);
#ifdef INCLUDE_PCI
#include <drv/pci/pciAutoConfigLib.h>
#include <drv/pci/pciConfigLib.h>
#include <drv/pci/pciIntLib.h>
#endif /* INCLUDE_PCI */
#ifdef INCLUDE_VXBUS
#include <hwif/vxbus/vxBus.h>
# ifdef INCLUDE_SIO_UTILS
IMPORT void sysSerialConnectAll();
# endif /* INCLUDE_SIO_UTILS */
IMPORT void hardWareInterFaceInit();
#ifdef DRV_TIMER_MIPSR4K
UINT32 vxbR4KTimerFrequencyGet (void);
#endif/*DRV_TIMER_MIPSR4K*/
#include "hwconf.c"
#endif
#ifdef INCLUDE_RTC
# include "sysRtc.c"
#endif /* INCLUDE_RTC */ /* Real-time clock support */
#if defined(INCLUDE_MAPPED_KERNEL)
#include "vmLib.h"
#endif
#undef INCLUDE_VXMP_TESTS
#ifdef INCLUDE_VXMP_TESTS
#include "semSmLib.h"
#include "smNameLib.h"
#endif /* INCLUDE_VXMP_TESTS */
/* externals */
#if ((defined INCLUDE_RTC) && (defined INCLUDE_DOSFS))
IMPORT void dosFsDateTimeInstall(FUNCPTR);
#endif /* INCLUDE_RTC, INCLUDE_DOSFS */
IMPORT void fpIntr ();
IMPORT int sysFpaAck ();
IMPORT int taskSRInit();
IMPORT int sysCompareSet ();
IMPORT void sysAltGo ();
IMPORT int palCoreNumGet ();
IMPORT int sysPridGet(void);
#if (INT_PRIO_MSB == TRUE)
IMPORT UINT8 ffsMsbTbl[]; /* Msb high interrupt hash table */
#else /* INT_PRIO_MSB == TRUE */
IMPORT UINT8 ffsLsbTbl[]; /* Lsb high interrupt hash table */
#endif /* INT_PRIO_MSB == TRUE */
IMPORT int sysStartType;
IMPORT char _gp[];
IMPORT UINT32 taskSrDefault;
/* forward declarations */
UINT32 sysCpuAvailableGet(void);
/* globals */
/*
* Since tying interrupt lines to the processor is board dependent sysHashOrder
* is provided to select the prioritization of interrupt lines.
*
* Usually, a sequential prioritization of interrupts from left to right is
* sufficient. However, since we MUST have the IPI (InterProcessor Interrupt)
* at the highest priority for SMP, since the timer interrupt is on the most
* significant interrupt pin (INT5), and finally, since we can't share the
* IPI interrupt with another interrupt, the standard prioritization is not
* acceptable.
*
* Here, we provide an alternate priority table that ensures that the
* IPI interrupt always gets acknowledged whenever it is asserted, and
* also modifies the priorities seen for the other interrupt sources:
*
* Mailbox (for Inter-Processor Interrupts) (INT4, Highest)
* Timer (System clock) (INT5)
* AuxTimer (INT2)
* PCI (INT0)
* UART0,2 (INT1)
* UART1,3 (INT3)
* SWTRAP1 (Software trap 1) (SW1)
* SWTRAP0 (Software trap 0) (SW0, Lowest)
*
*/
UINT8 sb1FfsTbl [256] =
{
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
};
UINT8 * sysHashOrder = sb1FfsTbl;
/*
* This table is critical to interrupt processing. Do not alter
* its contents until you understand the consequences. Refer to the
* MIPS Architecture Supplement for instructions on its use.
*/
typedef struct
{
ULONG intCause; /* cause of interrupt */
ULONG bsrTableOffset; /* index to BSR table */
ULONG statusReg; /* interrupt level */
ULONG pad; /* pad for ease of use */
} PRIO_TABLE;
#define INT_PRIO_ENFORCED
#ifdef INT_PRIO_ENFORCED
/* This prioritization table ensures that the IPI interrupt is
* never disabled by any other interrupt, and disables all other
* interrupts
*
* There is some flexibility in these masks. Specifically, this
* table causes each interrupt to mask not only itself, but
* also all lower-priority interrupts. This is not strictly
* required. But DO NOT allow any interrupt mask to include the
* bit to disable the IPI interrupt (except the IPI interrupt
* itself, of course), or change the IPI mask so that any other
* interrupt is left enabled during IPI processing.
*/
PRIO_TABLE intPrioTable[8] =
{
{CAUSE_SW1,(ULONG) IV_SWTRAP0_VEC, 0x0100, 0}, /* sw trap 0 */
{CAUSE_SW2,(ULONG) IV_SWTRAP1_VEC, 0x0300, 0}, /* sw trap 1 */
{CAUSE_IP3,(ULONG) IV_INT0_VEC, 0x2f00, 0}, /* INT 0, PCI */
{CAUSE_IP4,(ULONG) IV_INT1_VEC, 0x2b00, 0}, /* INT 1, UART0,2 */
{CAUSE_IP5,(ULONG) IV_INT2_VEC, 0x3f00, 0}, /* INT 2 AuxClk */
{CAUSE_IP6,(ULONG) IV_INT3_VEC, 0x2300, 0}, /* INT 3 UART1,3 */
{CAUSE_IP7,(ULONG) IV_INT4_VEC, 0xff00, 0}, /* INT 4, IPI */
{CAUSE_IP8,(ULONG) IV_INT5_VEC, 0xbf00, 0} /* INT 5, Timer */
};
#else /* INT_PRIO_ENFORCED */
/*
* This prioritization table also ensures that the IPI interrupt is
* never disabled by any other interrupt, but it allows all other
* interrupts to only disable themselves, instead of masking lower
* priority interrupts, as done above.
*/
PRIO_TABLE intPrioTable[8] =
{
{CAUSE_SW1,(ULONG) IV_SWTRAP0_VEC, 0x0100, 0}, /* sw trap 0 */
{CAUSE_SW2,(ULONG) IV_SWTRAP1_VEC, 0x0200, 0}, /* sw trap 1 */
{CAUSE_IP3,(ULONG) IV_INT0_VEC, 0x0400, 0}, /* INT 0, PCI */
{CAUSE_IP4,(ULONG) IV_INT1_VEC, 0x0800, 0}, /* INT 1, UART0,2 */
{CAUSE_IP5,(ULONG) IV_INT2_VEC, 0x1000, 0}, /* INT 2 AuxClk */
{CAUSE_IP6,(ULONG) IV_INT3_VEC, 0x2000, 0}, /* INT 3 UART1,3 */
{CAUSE_IP7,(ULONG) IV_INT4_VEC, 0xff00, 0}, /* INT 4, IPI */
{CAUSE_IP8,(ULONG) IV_INT5_VEC, 0x8000, 0} /* INT 5, Timer */
};
#endif /* INT_PRIO_ENFORCED */
/*
* Virtual Memory definitions
*/
#if defined(INCLUDE_MAPPED_KERNEL)
#define VM_STATE_MASK_FOR_ALL \
VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE
#define VM_STATE_FOR_IO \
VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE_NOT
#define VM_STATE_FOR_MEM_OS \
VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE
#define VM_STATE_FOR_MEM_APPLICATION \
VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE
#define VM_STATE_FOR_PCI \
VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE_NOT
/*
* sysPhysMemDesc[] entries:
* defines the memory space on the card
*/
PHYS_MEM_DESC sysPhysMemDesc [] =
{
/* RAM */
{
(VIRT_ADDR) LOCAL_MEM_LOCAL_ADRS, /* virtual Addr */
(PHYS_ADDR)( LOCAL_MEM_LOCAL_ADRS&0x0fffffff), /* Physical Addr */
0x10000000, /* length */
VM_STATE_MASK_FOR_ALL,
VM_STATE_FOR_MEM_OS
},
{
(VIRT_ADDR) 0xd0000000, /* virtual Addr */
(PHYS_ADDR)( (0xd0000000 & 0x1fffffff) | 0x80000000), /* Physical Addr */
0x2ffe0000, /* length */
VM_STATE_MASK_FOR_ALL,
VM_STATE_FOR_MEM_OS
}
};
/* number Mmu entries to be mapped */
int sysPhysMemDescNumEnt = NELEMENTS(sysPhysMemDesc);
#endif /* defined(INCLUDE_MAPPED_KERNEL) */
/* locals */
char sysModelStr[64] = BOARD_NAME;
IMPORT STATUS sysCacheSb1Init(int, int);
#define CACHE_LIB_INIT_FUNC sysCacheSb1Init
/* Included Generic MIPS Support code */
#include "sysMipsLib.c"
/* Additional Components */
#ifdef INCLUDE_NVRAM
#if (NV_RAM_SIZE == NONE)
# include <mem/nullNvRam.c>
#endif
#endif /* INCLUDE_NVRAM */
/*#ifdef INCLUDE_SOUND
#include "sound/ls2k_uda1342.c"
#include "sound/ls2k_sound.c"
#include "sound/sndAu.c"
#include "sound/sndWave.c"
#include "sound/sndPlay.c"
#endif*/
#ifdef LS2K_HDA_AUDIO
#include "hda/sb700Dsp.c"
#include "hda/sb700Mxr.c"
#include "hda/sb700Snd.c"
#include "hda/sndAu.c"
#include "hda/sndPlay.c"
#include "hda/sndWave.c"
#include "hda/sysSB700_Audio.c"
#endif /*LS2K_Audio*/
/*******************************************************************************
*
* sysModel - return the model name of the CPU board
*
* This routine returns the model name of the CPU board.
*
* RETURNS: A pointer to the board name string.
*
* ERRNO
*
* NOMANUAL
*/
char *sysModel (void)
{
return (sysModelStr);
}
/******************************************************************************
*
* sysBspRev - return the bsp version with the revision eg 1.1/<x>
*
* This function returns a pointer to a BSP version with the revision.
* for eg. 1.1/<x>. BSP_REV is concatenated to BSP_VERSION to form the
* BSP identification string.
*
* RETURNS: A pointer to the BSP version/revision string.
*
* ERRNO
*
* NOMANUAL
*/
char * sysBspRev (void)
{
return (BSP_VERSION BSP_REV);
}
/*******************************************************************************
*
* sysHwInit - initialize the CPU board hardware
*
* This routine initializes various features of the SB1/SB1A
* It is called from usrInit() in usrConfig.c.
*
* This routine initializes and turns off the timers.
*
* NOTE:
* This routine should not be called directly by the user.
*
* RETURNS: N/A
*
* ERRNO
*
* NOMANUAL
*/
IMPORT FUNCPTR lwIntr(int a0,ESFMIPS * a1, REG_SET * a2);
void initDc(void)
{
UINT32 tmp;
pciConfigInLong(0x0,0x6,0,0x10,&tmp);
tmp &=~(0xf) ;
memset((UINT32*)0x40000000, 0x0, (sysInLong(tmp | 0x1400) & 0x7FF)*(sysInLong(tmp| 0x1480)& 0x7FF)*2);
sysOutLong((tmp | 0x00001240),0x100103);
sysOutLong((tmp | 0x00001250),0x100103);
sysOutLong((tmp | 0x00001260),0xc0000000);
sysOutLong((tmp | 0x00001270),0xc0000000);
sysOutLong((tmp | 0x00001580),0xc0000000);
sysOutLong((tmp | 0x00001590),0xc0000000);
}
#ifndef INCLUDE_WINDML
void gcIntr()
{
}
#endif
#ifdef E6465
void initE6465(void)
{
UINT32 tmp;
int bus,dev,func;
pciFindDevice(0x1002,0x6766,0, &bus,&dev,&func);
pciConfigInLong(bus,dev,func,0x18,&tmp);
tmp &=(~0xf);
tmp |= 0x1;
pciConfigOutLong(bus,dev,func,0x30,(tmp + 0x20000));/*128k bytes*/
return ;
}
#endif
void coherent(void)
{
MIPS_LS2k_conf_write32(0xbfe10420,(MIPS_LS2k_conf_read32(0xbfe10420) | 0x1));/* gmac*/
MIPS_LS2k_conf_write32(0xbfe10424,(MIPS_LS2k_conf_read32(0xbfe10424) | 0x7));/*pcie, usb, hda*/
MIPS_LS2k_conf_write32(0xbfe10430,(MIPS_LS2k_conf_read32(0xbfe10430) | 0xc));/*dc, gpu*/
MIPS_LS2k_conf_write32(0xbfe10450,(MIPS_LS2k_conf_read32(0xbfe10450) | 0x400));/*sata*/
MIPS_LS2k_conf_write32(0xbfe10c00,(MIPS_LS2k_conf_read32(0xbfe10c00) & (~(0x2))));/*apbdma0*/
MIPS_LS2k_conf_write32(0xbfe10c10,(MIPS_LS2k_conf_read32(0xbfe10c10) & (~(0x2))));/*apbdma1*/
MIPS_LS2k_conf_write32(0xbfe10c20,(MIPS_LS2k_conf_read32(0xbfe10c20) & (~(0x2))));/*apbdma2*/
MIPS_LS2k_conf_write32(0xbfe10c30,(MIPS_LS2k_conf_read32(0xbfe10c30) & (~(0x2))));/*apbdma3*/
MIPS_LS2k_conf_write32(0xbfe10c40,(MIPS_LS2k_conf_read32(0xbfe10c40) & (~(0x2))));/*apbdma4*/
}
void sysHwInit (void)
{
int sr;
sr = SB1_SR;
/* init status register but leave interrupts disabled */
taskSRInit (sr);
intSRSet (sr & ~SR_IE);
/* set the Processor number based on the CPU ID */
sysProcNumSet (palCoreNumGet());
coherent();
/* make sure there is a valid boot string if running a secondary cpu */
strcpy (sysBootLine, DEFAULT_BOOT_LINE);
#ifdef INCLUDE_HW_FP
/* initialize floating pt unit */
if (fppProbe () == OK)
{
fppInitialize ();
intVecSet ((FUNCPTR *)INUM_TO_IVEC (IV_FPE_VEC), (FUNCPTR) fpIntr);
}
/*add by hb 2011_1_25*/
#define IV_ADEL_VEC 4 /* address load vector */
#define IV_ADES_VEC 5 /* address store vector */
intVecSet ((FUNCPTR *) INUM_TO_IVEC (IV_ADEL_VEC), (FUNCPTR)lwIntr);
intVecSet ((FUNCPTR *) INUM_TO_IVEC (IV_ADES_VEC), (FUNCPTR)lwIntr);
#endif /* INCLUDE_HW_FP */
#ifdef INCLUDE_VXBUS
hardWareInterFaceInit();
#endif /* INCLUDE_VXBUS */
initDc();
}
/******************************************************************************
*
* sysHwInit2 - additional system configuration and initialization
*
* This routine connects system interrupts and does any additional
* configuration necessary.
*
* RETURNS: N/A
*
* ERRNO
*
* NOMANUAL
*/
void sysHwInit2 (void)
{
#ifdef INCLUDE_VXBUS
vxbDevInit ();
#ifdef INCLUDE_SIO_UTILS
sysSerialConnectAll();
#endif /* INCLUDE_SIO_UTILS */
#ifdef INCLUDE_RTC
ds1339RtcInit();
#endif /* INCLUDE_RTC */
#if (( defined INCLUDE_RTC ) && ( defined INCLUDE_DOSFS_MAIN ))
dosFsDateTimeInstall((FUNCPTR)sysRtcDateTimeHook);
setAnsiSysTime();
#endif /* INCLUDE_RTC, INCLUDE_DOSFS_MAIN */
taskSpawn("tDevConn", 11, 0, 10000,
vxbDevConnect, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
#endif
#ifdef E6465
initE6465();
#endif
#ifdef LS2K_HDA_AUDIO
intConnect((void *)(4), sysAudioInt, 0); /*Connect the audio ISR*/
#endif /*LS2H_Audio*/
}
/*******************************************************************************
*
* sysPhysMemTop - get the address of the top of memory
*
* This routine returns the address of the first missing byte of memory, which
* indicates the top of 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 memory.
*
* ERRNO
*
* NOMANUAL
*/
char *sysPhysMemTop (void)
{
static char * memTop = NULL;
if (memTop == NULL)
{
memTop = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE);
}
return memTop;
}
/*******************************************************************************
*
* sysMemTop - get the address of the top of logical memory
*
* This routine returns the address of the first unusable byte of memory.
* VxWorks will not use any memory at or above this address.
*
* The user can reserve local memory from the board by declaring the
* macro USER_RESERVED_MEM with the amount of memory to reserve. This
* routine will return a pointer to the first byte of the reserved memory
* area.
*
* RETURNS: The address of the top of usable memory.
*
* ERRNO
*
* NOMANUAL
*/
char *sysMemTop (void)
{
static char * memTop = NULL;
if (memTop == NULL)
{
memTop = sysPhysMemTop () - USER_RESERVED_MEM;
#ifdef INCLUDE_EDR_PM
/* account for ED&R persistent memory */
memTop = memTop - PM_RESERVED_MEM;
#endif
}
return memTop;
}
/*******************************************************************************
*
* sysAutoAck - acknowledge the R4000 interrupt condition
*
* This routine acknowledges an R4000 interrupt for a specified interrupt
* vector.
*
* NOTE:
* This routine must be provided on all R4000 board support packages.
* Most interrupts are automatically acknowledged in the interrupt service
* routine.
*
* RETURNS: The result of the interrupt acknowledge cycle.
*
* ERRNO
*
* NOMANUAL
*/
int sysAutoAck
(
int vecNum /* vector num of interrupt that bugs us */
)
{
int result;
result = 0;
switch (vecNum)
{
case IV_INT5_VEC:
sysCompareSet (0); /* reset count/compare interrupt */
break;
case IV_SWTRAP0_VEC: /* software trap 0 */
return(result = sysSw0Ack ());
break;
case IV_SWTRAP1_VEC: /* software trap 1 */
return(result = sysSw1Ack ());
break;
case IV_FPA_UNIMP_VEC: /* unimplemented FPA oper*/
case IV_FPA_INV_VEC: /* invalid FPA operation*/
case IV_FPA_DIV0_VEC: /* FPA div by zero */
case IV_FPA_OVF_VEC: /* FPA overflow exception */
case IV_FPA_UFL_VEC: /* FPA underflow exception */
case IV_FPA_PREC_VEC: /* FPA inexact operation */
return(result = sysFpaAck ());
break;
default:
return(-1);
break;
}
return(result);
}
#ifdef DRV_TIMER_MIPSR4K
/******************************************************************************
* vxbR4KTimerFrequencyGet - to get the frequency
*
* The CPU frequency is determined by the function cfeInit() in sysLib.c.
*
* RETURNS: the frequncy of the CPU
*
* RETURNS: N/A
*
* NOMANUAL
*/
UINT32 vxbR4KTimerFrequencyGet(void)
{
UINT32 loopc, refc, div, div_l2;
UINT32 pll_ddr0,pll_ddr1,pll_ddr2,hw_freq;
pll_ddr0 = MIPS_LS2k_conf_read32(0xbfe10480);
pll_ddr1 = MIPS_LS2k_conf_read32(0xbfe10484);
pll_ddr2 = MIPS_LS2k_conf_read32(0xbfe10488);
loopc = pll_ddr1 & 0x3ff;
refc = (pll_ddr0 >> 26) & 0x3f;
div = (pll_ddr1 >> 10) & 0x3f;
div_l2 = pll_ddr2 & 0x3f;
hw_freq = 100/refc*loopc/div/div_l2;
return (hw_freq *1000000/2);
}
#endif
/*******************************************************************************
*
* 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 bus errors at interrupt level.
* However, in some circumstances, the user may wish to introduce a
* <startType> to enable special boot ROM facilities.
*
* RETURNS: Does not return.
*
* ERRNO
* NOMANUAL
*/
STATUS sysToMonitor
(
int startType /* parameter passed to ROM to tell it how to boot */
)
{
UINT32 apciRegbase;
/* lock out interrupts while jumping to reboot code */
#if 0
UINT32 epc,srValue;
epc = *(volatile UINT32*)EXCPAGE_EXCSTUB_PC;
printstr("epc:0x");
printnum(epc);
printstr("\n\r");
printstr("status:0x");
printnum(intSRGet());
printstr("\n\r");
printstr("cause:0x");
printnum(intCRGet());
printstr("\n\r");
srValue = MIPS_LS2k_conf_read32(0xbfe11420);
printstr("LSCtlr0 intisr:0x");
printnum(srValue);
printstr("\n\r");
srValue = MIPS_LS2k_conf_read32(0xbfe11460);
printstr("LSCtlr1 intisr:0x");
printnum(srValue);
printstr("\n\r");
printstr("LSCtlr0 inten:0x");
printnum(MIPS_LS2k_conf_read32(0xbfe11424));
printstr("\n\r");
printstr("LSCtlr1 inten:0x");
printnum(MIPS_LS2k_conf_read32(0xbfe11464));
printstr("\n\r");
#endif
intCpuLock();
/*APCI 0x30 register OS_RST*/
pciConfigInLong(0,2,0,0x10,&apciRegbase);
apciRegbase = (apciRegbase & 0xfffffff0) | 0xb0007000;
sysOutLong((apciRegbase + 0x30), 0x1);
return (OK); /* in case we ever continue from rom monitor */
}
#if defined(_WRS_CONFIG_SMP)
/* forward declarations */
void sysCpuInit (int, WIND_CPU_STATE *);
/* globals */
int sysCpuLoopCount[SB_MAX_SMP_CPUS] = {0};
/* statics */
FUNCPTR sysCpuInitTable[SB_MAX_SMP_CPUS] = {NULL};
/***************************************************************************
*
* sysCpuStart - start a SB1 core
*
* This function acts as a wrapper around the cfe_cpu_start function to
* provide the vxWorks SMP equivalent API, sysCpuStart().
*
* N.B.: This function currently assumes that CFE is available.
*
* The cfe_cpu_start() function requires 5 parameters:
*
* int cpu; /@ core number to start @/
* void (*fn)(void); /@ pointer to initial PC @/
* long sp; /@ value of initial stack pointer @/
* long gp; /@ value of initial global pointer @/
* long a1; /@ value to be passed to a1 at startup @/
*
* The sysCpuStart() function takes two parameters:
* int cpu; /@ core number to start @/
* REG_SET *pRegs; /@ pointer to a REG_SET structure @/
*
* The intent is to implement a function with the basic features of
* vxTaskRegsInit() that sets up the regs structure, then passes the
* cpu number and pRegs pointer to this function, which in turn extracts
* the needed values from the regs structure and calls cfe_cpu_start.
*
* RETURNS: OK
*
* NOMANUAL
*/
IMPORT void godson3_cpu_start(int ,void *,long ,long ,long);
#if defined (INCLUDE_MAPPED_KERNEL)
#define SYS_CPU_INIT KM_TO_K0(sysCpuInit)
#else /* INCLUDE_MAPPED_KERNEL */
#define SYS_CPU_INIT sysCpuInit
#endif /* INCLUDE_MAPPED_KERNEL */
STATUS sysCpuStart(int cpu, WIND_CPU_STATE *cpuState)
{
godson3_cpu_start(cpu,
(void (*)(void))SYS_CPU_INIT,
(long)cpuState->regs.spReg,
(long)cpuState->regs.gpReg,
(long)cpuState->regs.a1Reg);
return OK;
}
/***************************************************************************
*
* sysCpuStop - stop a SB1 core
*
* This function acts as a wrapper around the cfe_cpu_stop function to
* provide the vxWorks SMP equivalent API, sysCpuStop().
*
* N.B.: This function currently assumes that CFE is available.
*
* The cfe_cpu_start() function requires 1 parameter:
*
* int cpu; /@ core number to stop @/
*
* The sysCpuStop() function takes one parameter:
* int cpu; /@ core number to stop @/
*
* RETURNS: OK
*
* NOMANUAL
*/
STATUS sysCpuStop(int cpu)
{
return (cfe_cpu_stop(cpu));
}
/******************************************************************************
*
* sysCpuEnable - enable a multi core CPU
*
* This routine brings a CPU out of reset
*
* RETURNS: 0 - Success
* -1 - Fail
*
*/
STATUS sysCpuEnable(unsigned int cpuNum, WIND_CPU_STATE *cpuState)
{
if ((cpuNum < 1) || (cpuNum > (sysCpuAvailableGet ()-1)))
{
return -1;
}
sysCpuInitTable[cpuNum] = (FUNCPTR) cpuState->regs.pc;
return sysCpuStart(cpuNum, cpuState);
}
/******************************************************************************
*
* sysCpuDisable - disable a multi core CPU
*
* This routine shuts down the specified core.
*
* RETURNS: 0 - Success
* -1 - Fail
*
*/
STATUS sysCpuDisable(int cpuNum)
{
return sysCpuStop(cpuNum);
}
#endif /* if defined(_WRS_CONFIG_SMP) */
/******************************************************************************
*
* sysCpuAvailableGet - Determine the number of cores present
*
* this routine returns the number of cores
*
* RETURNS: CPU number (0-7)
*
* NOMANUAL
*/
UINT32 sysCpuAvailableGet(void)
{
return VX_SMP_NUM_CPUS;
}
#ifdef DRV_SIO_NS16550 /*zxj*/
SIO_CHAN * bspSerialChanGet
(
int channel /* serial channel */
)
{
return ((SIO_CHAN *) ERROR);
}
#endif /* DRV_SIO_SB1 */