📄 sysalib.s
字号:
/* sysALib.s - MagicARM2410 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 */ /* 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 /* 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] /* Set bus width for each bank, 0x22111112 */ ldr r2, =rBWSCON_ADR ldr r1, =rBWSCON_INIT_VALUE str r1, [r2] /* Set bank0 for flash 0x00000700 */ ldr r2, =rBANKCON0_ADR ldr r1, =rBANKCON0_INIT_VALUE str r1, [r2] ldr r2, =rBANKCON1_ADR ldr r1, =rBANKCON1_INIT_VALUE str r1, [r2] ldr r2, =rBANKCON3_ADR ldr r1, =rBANKCON3_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) /* 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 4L$_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 + -