📄 sysalib.s
字号:
/* sysALib.s - Intel ixm1200 system-dependent routines *//* Copyright 1997-2002 Wind River Systems, Inc.; Copyright 1999 Intel Corp. *//*modification history--------------------01i,24jan02,scm go over veloce mods...01h,21jan02,j_b Removing pre-pended underscores for new compilers (Diab/Gnu elf)01g,12sep01,scm Never reinit PCI unit...01f,30aug01,scm adjust to reflect ixm1200...01e,01Mar01,drj Forced the inclusion of ___ashldi301d,06Oct00,jdg Added Big-Endian support01c,07Mar00,jdg Added support for B0 revision ixp120001b,13aug99,jdg changed name from vbsa1200 to ixp1200eb01a,19Apr99,jdg created from 01c of brutus.*//*DESCRIPTIONThis module contains system-dependent routines written in assemblylanguage. It contains the entry code, sysInit(), for VxWorks imagesthat start running from RAM, such as 'vxWorks'. These images are loadedinto memory by some external program (e.g., a boot ROM) and thenstarted. The routine sysInit() must come first in the text segment.Its job is to perform the minimal setup needed to call the generic Croutine usrInit().sysInit() masks interrupts in the processor, initialises the MMU, setsthe initial stack pointer and intialises system hardware. Otherhardware and device initialisation is performed later in the sysHwInitroutine in sysLib.cNOTEMany routines in this module don't use the "C" frame pointer %r11@ ! orestablish a stack frame. This is either for efficiency, or because no stackhas yet been established.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 "sysLib.h"#include "config.h" .data .globl VAR(copyright_wind_river) .long VAR(copyright_wind_river)/* Exported internal functions */ .globl FUNC(sysInit) /* start of system code */ .globl FUNC(sysIntStackSplit) /* routine to split interrupt stack */ .globl FUNC(sysMmuTtbrGet) /* Read MMU TTBR */ .globl FUNC(sysToRomInit) /* Turn off MMU and branch to romInit */ .globl FUNC(sysWrite16) /* routine to do STRH */ .globl FUNC(sysRead16) /* routine to do LDRH */ .globl FUNC(swap32) /* routine to swap bytes in 32 bit int */ .globl FUNC(swap16) /* routine to swap bytes in 16 bit int */ .globl FUNC(pciCsrWr) /* routine to write PCI CSR safely */ .globl FUNC(sysCpuVerGet) /* Get CPU version revision *//* 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 */ .extern FUNC(__ashldi3) /* 64-bit shift left *//* absolutes */ /* absolute address of cache and mini-cache flush areas */ .globl VAR(sysCacheFlushReadArea) .equ VAR(sysCacheFlushReadArea), CACHE_FLUSH_BASE .globl VAR(sysMinicacheFlushReadArea) .equ VAR(sysMinicacheFlushReadArea), MINICACHE_FLUSH_BASE .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 (never returns)* sysInit () /@ THIS IS NOT A CALLABLE ROUTINE @/*/_ARM_FUNCTION(sysInit) /* disable interrupts and force SVC32 mode, just like reset */ MRS r1, cpsr BIC r1, r1, #MASK_MODE ORR r1, r1, #MODE_SVC32 | I_BIT | F_BIT MSR cpsr, r1#ifdef USE_LEDS_FOR_DEBUG /* Initialize LED's */ LDR r1, L$_IXM1200_LED_ADDR#ifndef LED_MEM_MAPPED /* Set GPIO's to core ownership, outputs, and output a zero */ /* IXM1200_LED_ADDR is GPIO_DATA */ MOV r2, #(GPIO_OWN_CCCC | GPIO_OUTPUT(0xF)) STR r2, [r1,#-(IXM1200_LED_ADDR-IXM1200_GPIO_EN)]#endif /* LED_MEM_MAPPED */ MOV r2, #2 STR r2, [r1]#endif /* USE_LEDS_FOR_DEBUG */ /* * Check for Chip revision: read chip ID into r8 * 0: A rev * 1: B rev */ MRC CP_MMU, 0, r8, c0, c0, 0 AND r8,r8,#0xF /* * CPU INTERRUPTS DISABLED * * In order to remap RAM down to zero upwards, we must have * been entered by some process that has switched the MMU on * and remapped the machine. So leave the MMU switched on, and * pointing to its set of page tables, but otherwise initialise * MMU. */ MOV r1, #MMU_INIT_VALUE /* normal init value */ ORR r1, r1, #MMUCR_M_ENABLE /* leave MMU switched on */ ORR r1, r1, #MMUCR_ROM /* and set protection bit */ MCR CP_MMU, 0, r1, c1, c0, 0 /* Write to MMU CR */ /* * Set Process ID Register to zero, this effectively disables * the process ID remapping feature. */ MOV r1, #0 MCR CP_MMU, 0, r1, c13, c0, 0#if 0 /* * Set core clock speed in Power Manager PLL Configuration Register. * This must be done before enabling clock switching - there are * strong suspicions that it will have no effect otherwise. */ MOV r2, #CCCR_INIT_VALUE /* coded core clock speed value */ LDR r1, L$_IXM1200_PPL_CFG /* PLL Configuration Reg*/ STR r2, [r1]#endif /* * Put the CPU in its normal (fast) clock switching mode * Note that this may prevent any kernel that a bootrom loads from * changing the core clock. */ MCR CP_MMU, 0, r14, c15, c1, 2 /* Clear Debug Support features: VxWorks makes no use of these */ MOV r1, #0 MCR CP_MMU, 0, r1, c14, c3, 0 /* Clear DBCR */ MCR CP_MMU, 0, r1, c14, c8, 0 /* Clear IBCR */ /* * We would like to discard the contents of the Write-Buffer * altogether, but there is no facility to do this. Failing that, * we do not want any pending writes to happen at a later stage, * so drain the Write-Buffer, i.e. force any pending writes to * happen now. */ MCR CP_MMU, 0, r1, c7, c10, 4 /* Drain write-buffer */ /* Flush, (i.e. invalidate) all entries in all caches */ MCR CP_MMU, 0, r1, c7, c6, 0 /* Flush D-cache & mini-cache */ MCR CP_MMU, 0, r1, c7, c5, 0 /* Flush (inval.) all I-cache */ /* * On StrongARM, the next four instructions could still come * from (what was in) the Instruction cache. * * The BSP makes no explicit use of Read Buffer, but make sure * that nothing already in it affects us. */ MCR CP_MMU, 0, r1, c9, c0, 0 /* Flush Read Buffer */ /* Bring other functional units out of reset */ LDR r1, L$_IXM1200_RESET MOV r2, #RESET_MICROENGINE /* Keep external reset applied so that sysHwInit can read GPIOs */ ORR r2, r2, #RESET_EXTERNAL STR r2, [r1] /* * We don't want to reprogram the SDRAM controller, but * we should make sure that the interrupt is not set */ LDR r1, L$_IXM1200_SDRAM_CSR LDR r2, [r1] BIC r2, r2, #(1<<SDRAM_EN_INT_BIT) STR r2, [r1]#ifndef USE_LEDS_FOR_DEBUG /* Initialize LED's */ LDR r1, L$_IXM1200_LED_ADDR#ifndef LED_MEM_MAPPED /* * Set GPIO's to core ownership, outputs, and output a zero * IXM1200_LED_ADDR is GPIO_DATA */ MOV r2, #(GPIO_OWN_CCCC | GPIO_OUTPUT(0xF)) STR r2, [r1,#-(IXM1200_LED_ADDR-IXM1200_GPIO_EN)]#endif /* LED_MEM_MAPPED */ MOV r2, #2 STR r2, [r1]#endif /* USE_LEDS_FOR_DEBUG */#ifdef USE_LEDS_FOR_DEBUG LDR r1, L$_IXM1200_LED_ADDR MOV r2, #3 STR r2, [r1]#endif /* USE_LEDS_FOR_DEBUG */ /* * We don't reload the MMU page tables here. Since we are executing * out of SDRAM (which has been remapped), we have to assume that * we have valid page tables. If we don't and we try to remap them * here, then we will suddenly change the virtual to physical * mapping where we are executing. */ /* set initial stack pointer so stack grows down from start of code */ ADR sp, FUNC(sysInit) /* initialise stack pointer */ /* now call usrInit */ MOV fp, #0 /* initialise frame pointer */ /* pass startType */ MOV r0, #(BOOT_WARM_AUTOBOOT | BOOT_DONT_INIT_HPC | BOOT_DONT_INIT_PCI) 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.** 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -