📄 rominit.s
字号:
/* romInit.s - ARM Integrator ROM initialization module *//* Copyright 2002 Wind River Systems, Inc. *//*TODO - Remove the template modification history and begin a new history starting with version 01a and growing the history upward with each revision.modification history--------------------01b,17jul02,dat remove obsolete information01a,23may02,scm written*//*TODO - Update documentation as necessary.NOTICEPlease substitute the appropriate file for this file, as needed.DESCRIPTIONThis module contains the entry code for VxWorks images that startrunning from ROM, such as 'bootrom' and 'vxWorks_rom'.The entry point, romInit(), is the first code executed on power-up.It performs the minimal setup needed to callthe generic C routine romStart() with parameter BOOT_COLD.RomInit() typically masks interrupts in the processor, sets the initialstack pointer (to STACK_ADRS which is defined in configAll.h), andreadies system memory by configuring the DRAM controller if necessary.Other hardware and device initialization is performed later in theBSP's sysHwInit() routine.A second entry point in romInit.s is called romInitWarm(). It is calledby sysToMonitor() in sysLib.c to perform a warm boot.The warm-start entry point must be written to allow a parameter onthe stack to be passed to romStart().WARNING:This code must be Position Independent Code (PIC). This means that itshould not contain any absolute address references. If an absolute addressmust be used, it must be relocated by the macro ROM_ADRS(x). This macrowill convert the absolute reference to the appropriate address withinROM space no matter how the boot code was linked. (For PPC, ROM_ADRS doesnot work. You must subtract _romInit and add ROM_TEXT_ADRS to eachabsolute address). (NOTE: ROM_ADRS(x) macro does not work for currentPPC compiler).This code should not call out to subroutines declared in other modules,specifically sysLib.o, and sysALib.o. If an outside module is absolutelynecessary, it can be linked into the system by adding the moduleto the makefile variable BOOT_EXTRA. If the same module is referenced byother BSP code, then that module must be added to MACH_EXTRA as well.Note that some C compilers can generate code with absolute addresses.Such code should not be called from this module. If absolute addressescannot be avoided, then only ROM resident code can be generated from thismodule. Compressed and uncompressed bootroms or VxWorks images will notwork if absolute addresses are not processed by the macro ROM_ADRS.WARNING:The most common mistake in BSP development is to attempt to do too muchin romInit.s. This is not the main hardware initialization routine.Only do enough device initialization to get memory functioning. All otherdevice setup should be done in sysLib.c, as part of sysHwInit().Unlike other RTOS systems, VxWorks does not use a single linear deviceinitialization phase. It is common for inexperienced BSP writers to takea BSP from another RTOS, extract the assembly language hardware setupcode and try to paste it into this file. Because VxWorks provides 3different memory configurations, compressed, uncompressed, and rom-resident,this strategy will usually not work successfully.WARNING:The second most common mistake made by BSP writers is to assume thathardware or CPU setup functions done by romInit.o do not need to berepeated in sysALib.s or sysLib.c. A vxWorks image needs only the followingfrom a boot program: The startType code, and the boot parameters stringin memory. Each VxWorks image will completely reset the CPU and allhardware upon startup. The image should not rely on the boot program toinitialize any part of the system (it may assume that the memory controlleris initialized).This means that all initialization done by romInit.s must be repeated ineither sysALib.s or sysLib.c. The only exception here could be thememory controller. However, in most cases even that can bereinitialized without harm.Failure to follow this rule may require users to rebuild bootrom's forminor changes in configuration. It is WRS policy that bootroms and vxWorksimages should not be linked in this manner.This module contains the entry code for VxWorks images that startrunning from ROM, such as 'bootrom' and 'vxWorks_rom'. The entrypoint, romInit(), is the first code executed on power-up. It performsthe minimal setup needed to call the generic C routine romStart() withparameter BOOT_COLD.romInit() masks interrupts in the processor and the interruptcontroller and sets the initial stack pointer (to STACK_ADRS which isdefined in configAll.h). Other hardware and device initialisation isperformed later in the sysHwInit routine in sysLib.c.The routine sysToMonitor() jumps to a location after the beginning ofromInit, (defined by ROM_WARM_ADRS) to perform a "warm boot". Thisentry point allows a parameter to be passed to romStart().The routines in this module don't use the "C" frame pointer %r11@ ! orestablish a stack frame.SEE ALSO:.I "ARM Architecture Reference Manual,".I "ARM 7TDMI Data Sheet,". "ARM 720T Data Sheet,".I "ARM 740T Data Sheet,".I "ARM 920T Technical Reference Manual",.I "ARM 940T Technical Reference Manual",.I "ARM 946E-S Technical Reference Manual",.I "ARM 966E-S Technical Reference Manual",.I "ARM Reference Peripherals Specification,".I "ARM Integrator/AP User Guide",.I "ARM Integrator/CM7TDMI User Guide",.I "ARM Integrator/CM720T User Guide",.I "ARM Integrator/CM740T User Guide",.I "ARM Integrator/CM920T User Guide",.I "ARM Integrator/CM940T User Guide",.I "ARM Integrator/CM946E User Guide",.I "ARM Integrator/CM9x6ES Datasheet".*//* TODO -Modify as needed... */#define _ASMLANGUAGE#include "vxWorks.h"#include "sysLib.h"#include "asm.h"#include "regs.h" #include "config.h"#include "arch/arm/mmuArmLib.h" .data .globl VAR(copyright_wind_river) .long VAR(copyright_wind_river)/* internals */ .globl FUNC(romInit) /* start of system code */ .globl VAR(sdata) /* start of data */ .globl _sdata/* externals */ .extern FUNC(romStart) /* system initialization routine */_sdata:VAR_LABEL(sdata) .asciz "start of data" .balign 4/* variables */ .data .text .balign 4/********************************************************************************* romInit - entry point for VxWorks in ROM** romInit* (* int startType /@ only used by 2nd entry point @/* )* INTERNAL* sysToMonitor examines the ROM for the first instruction and the string* "Copy" in the third word so if this changes, sysToMonitor must be updated.*/_ARM_FUNCTION(romInit)_romInit:cold: MOV r0, #BOOT_COLD /* fall through to warm boot entry */warm: B start /* copyright notice appears at beginning of ROM (in TEXT segment) */ .ascii "\nCopyright 1999-2002 Wind River Systems, Inc." .balign 4start: /* * There have been reports of problems with certain boards and * certain power supplies not coming up after a power-on reset, * and adding a delay at the start of romInit appears to help * with this. */ TEQS r0, #BOOT_COLD MOVEQ r1, #ARMBSP_DELAY_VALUE MOVNE r1, #1delay_loop: SUBS r1, r1, #1 BNE delay_loop#if defined(CPU_720T) || defined(CPU_720T_T) || \ defined(CPU_740T) || defined(CPU_740T_T) || \ defined(CPU_920T) || defined(CPU_920T_T) || \ defined(CPU_940T) || defined(CPU_940T_T) || \ defined(CPU_946ES) || defined(CPU_946ES_T) /* * Set processor and MMU to known state as follows (we may have not * been entered from a reset). We must do this before setting the CPU * mode as we must set PROG32/DATA32. * * MMU Control Register layout. * * bit * 0 M 0 MMU disabled * 1 A 0 Address alignment fault disabled, initially * 2 C 0 Data cache disabled * 3 W 0 Write Buffer disabled * 4 P 1 PROG32 * 5 D 1 DATA32 * 6 L 1 Should Be One (Late abort on earlier CPUs) * 7 B ? Endianness (1 => big) * 8 S 0 System bit to zero } Modifies MMU protections, not really * 9 R 1 ROM bit to one } relevant until MMU switched on later. * 10 F 0 Should Be Zero * 11 Z 0 Should Be Zero (Branch prediction control on 810) * 12 I 0 Instruction cache control */ /* Setup MMU Control Register */ MOV r1, #MMU_INIT_VALUE /* Defined in mmuArmLib.h */#if defined(CPU_920T) || defined(CPU_920T_T)#if defined(ARMBSP_EARLY_I_CACHE_ENABLE) ORR r1, r1, #MMUCR_I_ENABLE /* conditionally enable Icache*/#endif#endif MCR CP_MMU, 0, r1, c1, c0, 0 /* Write to MMU CR */ /* * If MMU was on before this, then we'd better hope it was set * up for flat translation or there will be problems. The next * 2/3 instructions will be fetched "translated" (number depends * on CPU). * * 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. */#if defined(CPU_720T) || defined(CPU_720T_T) || \ defined(CPU_740T) || defined(CPU_740T_T) MOV r2, #ARMBSP_RESET_RAM_BASE /* RAM base at reset */ SWPB r1, r1, [r2] /* Drain write-buffer */ /* Flush, (i.e. invalidate) all entries in the ID-cache */ MCR CP_MMU, 0, r1, c7, c0, 0 /* Flush (inval) all ID-cache */#endif /* defined(CPU_720T,740T) */#if defined(CPU_920T) || defined(CPU_920T_T) || \ defined(CPU_946ES) || defined(CPU_946ES_T) MOV r1, #0 /* data SBZ */ MCR CP_MMU, 0, r1, c7, c10, 4 /* drain write-buffer */ /* Flush (invalidate) both I and D caches */ MCR CP_MMU, 0, r1, c7, c7, 0 /* R1 = 0 from above, data SBZ*/#endif /* defined(CPU_920T,946ES) */#if defined(CPU_940T) || defined(CPU_940T_T) LDR r1, L$_sysCacheUncachedAdrs /* R1 -> uncached area */ LDR r1, [r1] /* drain write-buffer */ /* Flush (invalidate) both caches */ MOV r1, #0 /* data SBZ */ MCR CP_MMU, 0, r1, c7, c5, 0 /* Flush (inval) all I-cache */ MCR CP_MMU, 0, r1, c7, c6, 0 /* Flush (inval) all D-cache */#endif /* defined(CPU_940T,940T_T) */#if defined(CPU_720T) || defined(CPU_720T_T) || \ defined(CPU_920T) || defined(CPU_920T_T) /* * 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#endif /* defined(CPU_720T,920T) */#endif /* defined(CPU_720T,740T,920T,940T,946ES) */ /* disable interrupts in CPU 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 /* * CPU INTERRUPTS DISABLED * * disable individual interrupts in the interrupt controller */ MOV r2, #IC_BASE /* R2->interrupt controller */ MVN r1, #0 /* &FFFFFFFF */ STR r1, [r2, #FIQ_DISABLE-IC_BASE] /* disable all FIQ sources */ STR r1, [r2, #IRQ_DISABLE-IC_BASE] /* disable all IRQ sources */ /* * Jump to the normal (higher) ROM Position. After a reset, the * ROM is mapped into memory from* location zero upwards as well * as in its normal position at This code could be executing in * the lower position. We wish to be executing the code, still * in ROM, but in its normal (higher) position before we remap * the machine so that the ROM is no longer dual-mapped from zero * upwards, but so that RAM appears from 0 upwards. */ LDR pc, L$_HiPosnHiPosn: /* TODO - Do any special memory controller setups here */ /* TODO - setup any special onboard oscillators/hardware */ /* TODO - Initialize chip select lines */ /* * End of DRAM initialisation. * * Initialize the stack pointer to just before where the * uncompress code, copied from ROM to RAM, will run. */ LDR sp, L$_STACK_ADDR MOV fp, #0 /* zero frame pointer */ /* jump to C entry point in ROM: routine - entry point + ROM base */#if (ARM_THUMB) LDR r12, L$_rStrtInRom ORR r12, r12, #1 /* force Thumb state */ BX r12#else LDR pc, L$_rStrtInRom#endif /* (ARM_THUMB) *//******************************************************************************//* * PC-relative-addressable pointers - LDR Rn,=sym is broken * note "_" after "$" to stop preprocessor performing substitution */ .balign 4L$_HiPosn: .long ROM_TEXT_ADRS + HiPosn - FUNC(romInit)L$_rStrtInRom: .long ROM_TEXT_ADRS + FUNC(romStart) - FUNC(romInit)L$_STACK_ADDR: .long STACK_ADRS#if defined(CPU_940T) || defined (CPU_940T_T)L$_sysCacheUncachedAdrs: .long SYS_CACHE_UNCACHED_ADRS#endif /* defined(CPU_940T, CPU_940T_T) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -