📄 sysalib.s
字号:
/* sysALib.s - HITSAT omu system-dependent routines *//*DESCRIPTIONThis 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 and bank5 for flash and cs8900, 0x00000700 */ ldr r2, =rBANKCON0_ADR ldr r1, =rBANKCON0_INIT_VALUE str r1, [r2] 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) /* 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 + -