📄 sysalib.s
字号:
/* sysALib.s - ixp425 IXDP425 system-dependent routines *//* Copyright 2002 Wind River Systems, Inc. *//*modification history--------------------01g,20aug03,m_h warmboot problems01f,11aug03,scm mods for diab compilation...01e,02jul03,m_h little endian01d,24sep02,jb3 Going for Csr_Gold01c,05sep02,jb3 Merge in changes from w/ t2.1 ongiong development01c,20aug02,jb Adding visionClick download support01b,13jun02,jb Fixing sysToMonitor support01a,05jun02,jb initial version...*//*DESCRIPTIONThis module contains system-dependent routines written in assemblylanguage.This module must be the first specified in the \f3ld\f1 command used tobuild the system. The sysInit() routine is the system start-up code.INTERNALMany routines in this module doesn't use the "c" frame pointer %r11@ !This is only for the benefit of the stacktrace facility to allow it to properly trace tasks executing within these routines.SEE ALSO: .I "ARM Architecture Reference Manual"*/#define _ASMLANGUAGE #include "vxWorks.h"#include "regs.h"#include "arch/arm/arm.h"#include "arch/arm/mmuArmLib.h"#include "arch/arm/excArmLib.h"#include "sysLib.h"#include "ixdp425.h" #include "ixp425IntrCtl.h"#include "config.h" .data .globl FUNC(copyright_wind_river) .long FUNC(copyright_wind_river)#define SYS_A_LIB_DEBUG /* internals */ .globl FUNC(sysInit) /* start of system code */ .globl FUNC(sysIntStackSplit) .globl FUNC(sysEnableIRQMasks) .globl FUNC(sysPhysMemSize) .globl FUNC(sysByteSwap) .globl FUNC(sysToMonSwitchFlashRam) .globl FUNC(sysReadTTB) .globl FUNC(sysWriteTTB) .globl FUNC(sysInvalidateTLB) .globl FUNC(sysTurnMmuOn) .globl FUNC(sysTurnMmuOff) .globl FUNC(sysEnablePBitForMmuTableWalk) .globl FUNC(sysDisablePBitForMmuTableWalk) .globl FUNC(sysReadProgramCounter) .globl FUNC(prepWarmReboot) .globl FUNC(prepWarmRebootEnd) .globl sysBootromTTableInRam /* 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 */ /* Allocate space in the data section where the ROM translation table * will be copied into. This will be on a 16K boundary */ .p2align 14sysBootromTTableInRam: .skip 0x4000 .text .align 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 @/ */FUNC_LABEL(sysInit)/* Disable Interrupts */ MRS r1, cpsr /* get current status */ ORR r1, r1, #I_BIT | F_BIT /* disable IRQ and FIQ */ MSR cpsr, r1/* Interrupts Disabled */ ldr r1, =IXP425_ICMR /* Zero-out Interrupt Mask */ mov r2, #0x0 str r2, [r1] adr sp, FUNC(sysInit) /* initialise stack pointer */ mov fp, #0 /* initialise frame pointer */ /* Make sure Boot type is set correctly. visionClick doesn't */ mov r1,#BOOT_NORMAL cmp r1,r0 beq L$_Good_Boot mov r1,#BOOT_NO_AUTOBOOT cmp r1,r0 beq L$_Good_Boot mov r1,#BOOT_CLEAR cmp r1,r0 beq L$_Good_Boot mov r1,#BOOT_QUICK_AUTOBOOT cmp r1,r0 beq L$_Good_Boot mov r0, #BOOT_NORMAL /* pass startType *//* Pass r0 through */L$_Good_Boot:/* now call usrInit */ b FUNC(usrInit) /********************************************************************************* 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.** NOMANUAL* void sysIntStackSplit* (* char *pBotStack /@ pointer to bottom of interrupt stack @/* long size /@ size of stack @/* )*/FUNC_LABEL(sysIntStackSplit)/* * Split stack into 2 - IRQ and SVC-mode interrupt stacks. * 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. * * - HIGH MEMORY - * ------------------------ <--- vxIrqIntStackBase (r0 on entry) * | | * | IRQ-mode | * | interrupt stack | * | | * ------------------------ <--{ vxIrqIntStackEnd * | | { vxSvcIntStackBase * | SVC-mode | * | interrupt stack | * | | * ------------------------ <--- vxSvcIntStackEnd * - LOW MEMORY - * * * 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 MOV pc,lrFUNC_LABEL(sysEnableIRQMasks)/**************************************************INTCTL : Nothing to do. Just return. *****************************************************/ mov pc, lr/* Retrieve auto-sized memory. *//* UINT32 sysPhysMemSize(void) */FUNC_LABEL(sysPhysMemSize) /* No support for dynamic memory sizeing, return Configured size. */ mov r0, #LOCAL_MEM_SIZE /* return Configured size*/ ALL_DONE_NOW: mov pc, lrFUNC_LABEL(sysByteSwap) EOR r1,r0,r0,ROR #16 BIC r1,r1,#0xff0000 MOV r0,r0,ROR #8 EOR r0,r0,r1,LSR #8 mov pc, lr/* * This is called from sysToMonitor, it jumps to an aliased version of code currently running. * Then it puts flash down at 0x0 so that sysToMonitor may perform a reboot. * There is an implicit asumption that physical=locgical memory if the MMU is enabled. * Note: distroys r0,r1 */FUNC_LABEL(sysToMonSwitchFlashRam) /* Jump back to relocated ram */ ldr r0, =IXP425_SDRAM_BASE_ALT orr r0,r0,pc mov pc,r0 nop /* Adjust the link register, frame pointer, and stack pointer * to reference the first aliased memory area (+ 0x10000000) */ add lr,lr,#IXP425_SDRAM_BASE_ALT add fp,fp,#IXP425_SDRAM_BASE_ALT add sp,sp,#IXP425_SDRAM_BASE_ALT /* Write to Expansion Bus controller to swap Flash & Ram Now running from low down */ ldr r0,=IXP425_EXP_CNFG0 ldr r1,[r0] orr r1,r1,#0x80000000 str r1,[r0] mov pc,lr FUNC_LABEL(sysReadTTB) mrc p15, 0, r0, c2, c0, 0 /* Get Translation Table Base Register */ CPWAIT(r0) mov pc,lrFUNC_LABEL(sysWriteTTB) /* Assumes r0 contains TTB */ mcr p15, 0, r0, c2, c0, 0 /* Set Translation Table Base Register */ CPWAIT(r0) mov pc,lrFUNC_LABEL(sysInvalidateTLB) /* Assumes r0 contains TTB */ /* Invalidate Instruction, Data TLBs */ ldr r0, =0x0 mcr p15, 0, r0, c8, c7, 0 /* Flush I & D TLBs*/ CPWAIT(r0) mov pc,lrFUNC_LABEL(sysTurnMmuOff) /* disable Instruction Cache */ mrc p15, 0, r0, c1, c0, 0 /* Read Control Register*/ bic r0, r0, #0x1000 /* Clear I-Cache bit */ mcr p15, 0, r0, c1, c0, 0 /* Write Back Control Register */ CPWAIT(r0) /* Invalidata Entire Instr Cache */ mov r0,#0x0 /* Clear R0 */ mcr p15, 0, r0, c7, c5, 0 CPWAIT(r0) /* disable Data Cache */ mrc p15, 0, r0, c1, c0, 0 /* Read Control Register*/ bic r0, r0, #0x0002 /* Clear D-Cache bit */ mcr p15, 0, r0, c1, c0, 0 /* Write Back Control Register */ CPWAIT(r0) /* Invalidate Entire Data Cache */ mov r0,#0x0 /* Clear R0 */ mcr p15, 0, r0, c7, c6, 0 CPWAIT(r0) /* Drain Write/Fill Buffers */ mov r0, #0x0 /* Clear R0 */ mcr p15, 0, r0, c7, c10, 4 /* Drain */ CPWAIT(r0) /* Turn off MMU */ mrc p15, 0, r0, c1, c0, 0 /* Get Control Processor reg 15 value into r1 */ bic r0, r0, #0x1 /* Clear Bit 0 of CP15 register 1 */ mcr p15, 0, r0, c1, c0, 0 /* Save new CP15 Reg 1 value */ andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 /* Wait to be sure the MMU gets switched off.*/ CPWAIT(r0) mov pc, lr FUNC_LABEL(sysTurnMmuOn) mrc p15, 0, r1, c1, c0, 0 /* Get Control Processor reg 15 value into r1 */ orr r1, r1, #0x1 /* Set Bit 0 of CP15 register 1 */ mcr p15, 0, r1, c1, c0, 0 /* Save new CP15 Reg 1 value */ CPWAIT(r0) mov pc, lrFUNC_LABEL(sysEnablePBitForMmuTableWalk) mrc p15, 0, r1, c1, c0, 1 /* Get Control Processor reg 15 value into r1 */ orr r1, r1, #0x2 /* Set Bit 1 of CP15 register 1 */ mcr p15, 0, r1, c1, c0, 1 /* Save new CP15 Reg 1 value */ CPWAIT(r0) mov pc, lrFUNC_LABEL(sysDisablePBitForMmuTableWalk) mrc p15, 0, r1, c1, c0, 1 /* Get Control Processor reg 15 value into r1 */ bic r1, r1, #0x2 /* Set Bit 1 of CP15 register 1 */ mcr p15, 0, r1, c1, c0, 1 /* Save new CP15 Reg 1 value */ CPWAIT(r0) mov pc, lrFUNC_LABEL(sysReadProgramCounter) mov r0, pc mov pc, lr /* * void prepWarmReboot (volatile UINT32 arg1, volatile UINT32 arg2) */FUNC_LABEL(prepWarmReboot) /* Disable Instruction Cache */ mrc p15, 0, r4, c1, c0, 0 bic r4, r4, #0x1000 mcr p15, 0, r4, c1, c0, 0 /* Wait (Similar code to the CPWAIT macro in sysALib.s) */ mrc p15, 0, r4, c2, c0, 0 mov r4, r4 /* Invalidata Entire Instr Cache */ mov r4,#0x0 mcr p15, 0, r4, c7, c5, 0 /* Wait (Similar code to the CPWAIT macro in sysALib.s) */ mrc p15, 0, r4, c2, c0, 0 mov r4, r4 /* disable Data Cache */ mrc p15, 0, r4, c1, c0, 0 bic r4, r4, #0x0002 mcr p15, 0, r4, c1, c0, 0 /* Wait (Similar code to the CPWAIT macro in sysALib.s) */ mrc p15, 0, r4, c2, c0, 0 mov r4, r4 /* Invalidate Entire Data Cache */ mov r4,#0x0 mcr p15, 0, r4, c7, c6, 0 /* Wait (Similar code to the CPWAIT macro in sysALib.s) */ mrc p15, 0, r4, c2, c0, 0 mov r4, r4 /* Drain Write/Fill Buffers */ mcr p15, 0, r4, c7, c10, 4 /* Wait (Similar code to the CPWAIT macro in sysALib.s) */ mrc p15, 0, r4, c2, c0, 0 mov r4, r4 /* Turn off MMU */ mrc p15, 0, r5, c1, c0, 0 bic r5, r5, #0x1 mcr p15, 0, r5, c1, c0, 0 /* Wait to be sure the MMU gets switched off. * (Similar code to the CPWAIT macro in sysALib.s) */ mrc p15, 0, r4, c2, c0, 0 mov r4, r4 /* Turn off the P-Bit in the MMU Table Walk */ mrc p15, 0, r5, c1, c0, 1 bic r5, r5, #0x2 mcr p15, 0, r5, c1, c0, 1 /* Write to Expansion Bus controller to swap Flash & Ram. * Now running from low down */ mov r4, r0 mov r5, r1 add r4, r4, r5 ldr r5, [r4] orr r5, r5, #0x80000000 str r5, [r4] mov pc, lr/* This function gets swapped in memory. Mark the end */FUNC_LABEL(prepWarmRebootEnd)L$_vxSvcIntStackBase: .long FUNC(vxSvcIntStackBase) L$_vxSvcIntStackEnd: .long FUNC(vxSvcIntStackEnd) L$_vxIrqIntStackBase: .long FUNC(vxIrqIntStackBase) L$_vxIrqIntStackEnd: .long FUNC(vxIrqIntStackEnd) /***EOF***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -