📄 sysalib.s
字号:
/* sysALib.s - HITSAT omu system-dependent routines */
/*
DESCRIPTION
This module contains:
system-dependent routines written in assembly language;
It contains the entry code:
sysInit()
for VxWorks images that start running from RAM, such as 'vxWorks'.
These images are loaded into memory by some external program (e.g., a boot ROM) and then started.
The routine sysInit() must come first in the text segment.
Its job is to perform the minimal setup needed to call the generic C routine usrInit().
sysInit()
masks interrupts in:
the processor
the interrupt controller
sets the initial stack pointer.
Other hardware and device initialisation is performed later in the sysHwInit routine in sysLib.c.
*/
#define _ASMLANGUAGE
#include "vxWorks.h"
#include "asm.h"
#include "regs.h"
#include "sysLib.h"
#include "config.h"
#include "arch/arm/mmuArmLib.h"
.data
.globl VAR(copyright_wind_river)
.long VAR(copyright_wind_river)
/* internals */
.globl FUNC(sysInit) /* start of system code */
.globl FUNC(sysIntStackSplit) /* routine to split interrupt stack */
/* externals */
.extern FUNC(usrInit) /* system initialization routine */
.extern FUNC(vxSvcIntStackBase) /* base of SVC-mode interrupt stack */
.extern FUNC(vxSvcIntStackEnd) /* end of SVC-mode interrupt stack */
.extern FUNC(vxIrqIntStackBase) /* base of IRQ-mode interrupt stack */
.extern FUNC(vxIrqIntStackEnd) /* end of IRQ-mode interrupt stack */
.text
.balign 4
/*******************************************************************************
*
* sysInit - start after boot
*
* This routine is the system start-up entry point for VxWorks in RAM, the
* first code executed after booting. It disables interrupts, sets up
* the stack, and jumps to the C routine usrInit() in usrConfig.c.
*
* The initial stack is set to grow down from the address of sysInit(). This
* stack is used only by usrInit() and is never used again. Memory for the
* stack must be accounted for when determining the system load address.
*
* NOTE: This routine should not be called by the user.
*
* RETURNS: N/A
* sysInit () /@ THIS IS NOT A CALLABLE ROUTINE @/
*/
_ARM_FUNCTION(sysInit)
/* Turn off the watchdog. */
ldr r0, =rWTCON_ADR /* r0->WTCON */
ldr r1, =rWTCON_INIT_VALUE /* r1 = WTCON's initValue */
str r1, [r0] /* Turn off the watch-dog */
#if 1/*donleo debug 2005-10-23 21:10*/
/* led on */
ldr r2,=0x56000058
ldr r1,=0xff
str r1,[r2]
ldr r2,=0x56000050
ldr r1,=(0x400 | 0x100 | 0x4000 | 0x1000)
str r1,[r2]
ldr r2,=0x56000054
ldr r1,=(~0xf0)
str r1,[r2]
/* end led in */
#endif
/* Setup MMU Control Register */
mov r1, #MMU_INIT_VALUE /* Defined in mmuArmLib.h */
#if defined(INTEGRATOR_EARLY_I_CACHE_ENABLE)
orr r1, r1, #MMUCR_I_ENABLE /* conditionally enable Icache*/
#endif
mcr p15, 0, r1, c1, c0, 0 /* Write to MMU CR */
/* drain write-buffer */
mov r1, #0 /* data SBZ */
mcr p15, 0, r1, c7, c10, 4
/* Flush (invalidate) both I and D caches */
mcr p15, 0, r1, c7, c7, 0 /* R1 = 0 from above, data SBZ*/
/*
Set Process ID Register to zero,
this effectively disables the process ID remapping feature.
*/
mov r1, #0
mcr p15, 0, r1, c13, c0, 0
/* Disable interrupts in processor and switch to SVC32 mode */
mrs r1, cpsr
bic r1, r1, #MASK_MODE
orr r1, r1, #MODE_SVC32 | I_BIT | F_BIT
msr cpsr, r1
/* Disable individual interrupts in the interrupt controller */
ldr r1, =0xffffffff
ldr r2, =rINTMSK_ADR /* R2->interrupt mask registor of controller */
str r1, [r2] /* disable all sources */
ldr r2, =rINTSUBMSK_ADR /* R2->sub-interrupt mask registor of controller */
str r1, [r2] /* disable all sub-sources */
/* Set asynchronous mode via MMU. */
mrc p15, 0, r2, c1, c0, 0
orr r2, r2, #MMUCR_ASYNC
mcr p15, 0, r2, c1, c0, 0
#if 0/*donleo debug 2005-10-23 21:10*/
/* led on */
ldr r2,=0x56000058
ldr r1,=0xff
str r1,[r2]
ldr r2,=0x56000050
ldr r1,=(0x400 | 0x100 | 0x4000 | 0x1000)
str r1,[r2]
ldr r2,=0x56000054
ldr r1,=(~0x50)
str r1,[r2]
/* end led in */
cold:
b cold
#endif
/* Set PLL lock time. */
ldr r2, =rLOCKTIME_ADR
ldr r1, =rLOCKTIME_INIT_VALUE
str r1, [r2]
/* Set FCLK:HCLK:PCLK = 1:2:4 */
ldr r2, =rCLKDIVN_ADR
ldr r1, =rCLKDIVN_INIT_VALUE
str r1, [r2]
/* Set FCLK = 200MHz by Fosc = 12MHz */
ldr r2, =rMPLLCON_ADR
ldr r1, =rMPLLCON_INIT_VALUE
str r1, [r2]
/* Set clock control register */
ldr r2, =rCLKCON_ADR
ldr r1, =rCLKCON_INIT_VALUE
str r1, [r2]
/* Set clock slow register */
ldr r2, =rCLKSLOW_ADR
ldr r1, =rCLKSLOW_INIT_VALUE
str r1, [r2]
#if 0/*donleo debug 2005-10-23 21:10*/
/* led on */
ldr r2,=0x56000058
ldr r1,=0xff
str r1,[r2]
ldr r2,=0x56000050
ldr r1,=(0x400 | 0x100 | 0x4000 | 0x1000)
str r1,[r2]
ldr r2,=0x56000054
ldr r1,=(~0xb0)
str r1,[r2]
/* end led in */
cold:
b cold
#endif
/* Set bus width for each bank, 0x22111112 */
ldr r2, =rBWSCON_ADR
ldr r1, =rBWSCON_INIT_VALUE
str r1, [r2]
/* Set bank0 and bank5 for flash and cs8900, 0x00000700 */
ldr r2, =rBANKCON0_ADR
ldr r1, =rBANKCON0_INIT_VALUE
str r1, [r2]
#if 1/*donleo 2005-10-21 3:34*/
ldr r2, =rBANKCON3_ADR
ldr r1, =rBANKCON3_INIT_VALUE
str r1, [r2]
#endif
ldr r2, =rBANKCON5_ADR
ldr r1, =rBANKCON5_INIT_VALUE
str r1, [r2]
/* Set bank6 for SDRAM, 0x00018000 */
ldr r2, =rBANKCON6_ADR
ldr r1, =rBANKCON6_INIT_VALUE
str r1, [r2]
/* Set refresh for SDRAM, 0x00860459 */
ldr r2, =rREFRESH_ADR
ldr r1, =rREFRESH_INIT_VALUE
str r1, [r2]
/* Set bank size for SDRAM, 0x000000b7 */
ldr r2, =rBANKSIZE_ADR
ldr r1, =rBANKSIZE_INIT_VALUE
str r1, [r2]
/* Set bank mode, 0x00000030 */
ldr r2, =rMRSRB6_ADR
ldr r1, =rMRSRB6_INIT_VALUE
str r1, [r2]
/* initialise stack pointer */
/*adr sp, FUNC(sysInit)*/
ldr sp, =0x30001000
/* now call usrInit */
mov fp, #0 /* initialise frame pointer */
mov r0, #BOOT_WARM_AUTOBOOT /* pass startType */
#if (ARM_THUMB)
ldr r12, L$_usrInit
bx r12
#else
b FUNC(usrInit)
#endif /* (ARM_THUMB) */
/*******************************************************************************
*
* sysIntStackSplit - split interrupt stack and set interrupt stack pointers
*
* This routine is called, via a function pointer, during kernel
* initialisation. It splits the allocated interrupt stack into IRQ and
* SVC-mode stacks and sets the processor's IRQ stack pointer. Note that
* the pointer passed points to the bottom of the stack allocated i.e.
* highest address+1.
*
* IRQ stack needs 6 words per nested interrupt;
* SVC-mode will need a good deal more for the C interrupt handlers.
* For now, use ratio 1:7 with any excess allocated to the SVC-mode stack
* at the lowest address.
*
* Note that FIQ is not handled by VxWorks so no stack is allocated for it.
*
* The stacks and the variables that describe them look like this.
* .CS
*
* - HIGH MEMORY -
* ------------------------ <--- vxIrqIntStackBase (r0 on entry)
* | |
* | IRQ-mode |
* | interrupt stack |
* | |
* ------------------------ <--{ vxIrqIntStackEnd
* | | { vxSvcIntStackBase
* | SVC-mode |
* | interrupt stack |
* | |
* ------------------------ <--- vxSvcIntStackEnd
* - LOW MEMORY -
* .CE
*
* NOTE: This routine should not be called by the user.
* void sysIntStackSplit
* (
* char *pBotStack /@ pointer to bottom of interrupt stack @/
* long size /@ size of stack @/
* )
*/
_ARM_FUNCTION_CALLED_FROM_C(sysIntStackSplit)
/*
* r0 = base of space allocated for stacks (i.e. highest address)
* r1 = size of space
*/
sub r2, r0, r1 /* r2->lowest usable address */
ldr r3, L$_vxSvcIntStackEnd
str r2, [r3] /* == end of SVC-mode stack */
sub r2, r0, r1, ASR #3 /* leave 1/8 for IRQ */
ldr r3, L$_vxSvcIntStackBase
str r2, [r3]
/* now allocate IRQ stack, setting irq_sp */
ldr r3, L$_vxIrqIntStackEnd
str r2, [r3]
ldr r3, L$_vxIrqIntStackBase
str r0, [r3]
mrs r2, cpsr
bic r3, r2, #MASK_MODE
orr r3, r3, #MODE_IRQ32 | I_BIT /* set irq_sp */
msr cpsr, r3
mov sp, r0
/* switch back to original mode and return */
msr cpsr, r2
#if (ARM_THUMB)
bx lr
#else
mov pc, lr
#endif /* (ARM_THUMB) */
/******************************************************************************/
/*
* PC-relative-addressable pointers - LDR Rn,=sym is broken
* note "_" after "$" to stop preprocessor preforming substitution
*/
.balign 4
L$_vxSvcIntStackBase:
.long VAR(vxSvcIntStackBase)
L$_vxSvcIntStackEnd:
.long VAR(vxSvcIntStackEnd)
L$_vxIrqIntStackBase:
.long VAR(vxIrqIntStackBase)
L$_vxIrqIntStackEnd:
.long VAR(vxIrqIntStackEnd)
#if (ARM_THUMB)
L$_usrInit:
.long FUNC(usrInit)
#endif /* (ARM_THUMB) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -