📄 startrom.s
字号:
TTL Generic ARM start-of-day (initialisation) code > startrom.s ; --------------------------------------------------------------------- ; This file provides the Angel initialisation and startup code ; for ROM systems. After performing all the necessary ARM and ; target initialisation the "__main" function is called to ; start the Angel library and application code present. ; ; $Revision: 1.6 $ ; $Author: mwelsh $ ; $Date: 1999/06/25 15:25:49 $ ; ; Copyright Advanced RISC Machines Limited, 1995. ; All Rights Reserved ; ; Notes: ; To make it simpler for the developer to understand, the ROM ; specific and generic Angel workspace are provided as ; standard RW data AREAs. ; ; However, this means that care must be taken when ; constructing ROM based versions of Angel. In fact there are ; two types of ROM based Angel: boot ROMs and application ; ROMs. For application ROMs we do not need to worry about the ; size of RW data, since *NO* programs will be downloaded, and ; the application can use as much RAM as required. However, ; for boot ROMs we need to ensure that the RAM usage of the ; ROM system does not exceed 0x8000. This will ensure that ; default AIF applications can be downloaded. ; ; For non-ROM based applications the linker can be left to ; place data AREAs as it sees fit. For ROM based code we force ; the linker to reference the data at a fixed address. The ; only problem then becomes finding the initialised data in ; the ROM image, and ensuring that it is copied to the correct ; RAM address. This can be achieved as follows: ; ; 1) We know that the linker places identical area types ; contiguously. ; ; 2) We explicitly force the RO (code areas) to be at the ; start of the ROM image. ; ; 3) We can use Image$$RO$$Base and Limit to find the end of ; the RO section in the ROM image. This will give us the start ; location in the ROM of the RW data. ; ; 4) We can use the corresponding RW and ZI Base and Limit ; values to find out how big the areas are, and initialise the ; RAM accordingly. ; ; 5) Since we now know how large the RW data is, we can find ; the end of the ROM image and any post-armlink information ; that has been appended to the binary image (e.g. CRCs, MMU ; tables, etc.). ; ; 6) We know that the linker places R/W code areas before R/W ; data areas, which in turn appear before the BSS areas. ; ; We cannot use the "-last" feature of the ARM linker to place ; a RO area at the end, since this will break point 1) where ; the linker wants to make AREAs of the same type contiguous. ; ; --------------------------------------------------------------------- GET listopts.s ; standard listing control GET lolevel.s ; generic ARM definitions GET macros.s ; standard assembler support GET taskmacs.s ; exception handling etc. GET target.s ; target specific definitions ; --------------------------------------------------------------------- IMPORT |__main| ; Hi-level Angel init entry point IF :DEF: MINIMAL_ANGEL :LAND: MINIMAL_ANGEL<>0 IMPORT |__entry| ; Application entry point ELSE IMPORT |__entry|,WEAK ; main need not exist (no application) ENDIF IMPORT __rt_asm_fatalerror ; error reporting via suppasm.s IMPORT angel_StartupStatus ; Variable describing type of reset. IMPORT angel_MMUtype ; Variable holding ARM MMU type. IMPORT Angel_GlobalRegBlock KEEP ; Keep local symbols in the object. ; --------------------------------------------------------------------- ; ; This AREA is marked as NOINIT, to ensure that it appears as BSS: AREA |AngelROM$$Data|,DATA,NOINIT EXPORT angel_ROMEnd EXPORT angel_GhostCount IF DEBUG <> 0 EXPORT angel_InterruptCount EXPORT angel_SysCallCount ENDIF EXPORT angel_ComplexSWILock EXPORT angel_Needschedule IF DEBUG <> 0 EXPORT angel_DebugTaskBase EXPORT angel_DebugTaskArea EXPORT angel_DebugStartTaskCount EXPORT angel_DebugQueueTaskCount ENDIFangel_ROMWorkspaceStart % 0 ; start of this workspace section IF DEBUG <> 0angel_DebugTaskBase % 4angel_DebugTaskArea % 4angel_DebugStartTaskCount % 4angel_DebugQueueTaskCount % 4angel_InterruptCount % 4 ; count of interrupts angel_SysCallCount % 4 ; count of Angel system calls ENDIF ;angel_ROMEnd % 4 ; true ROM end address ; When constructing the ROM, it may be necessary to append ; information to the image produced by the linker. This ; variable is initialised to the address after all of the ; linker placed AREAs. This allows the run-time code to find ; such private, appended, information. e.g. hard-wired MMU ; tables, ROM CRC values, etc. ;angel_GhostCount % 4 ; count of ghost interruptsangel_ComplexSWILock % 4angel_Needschedule % 4 ; if non-zero, schedule on ISR exitangel_ROMWorkspaceEnd % 0 ; allows size of area to be calculated ; --------------------------------------------------------------------- ; -- ROM Startup code ------------------------------------------------- ; --------------------------------------------------------------------- IF :DEF: ADS_BUILD :LAND: ADS_BUILD = 1 AREA |ROMStartup|,CODE,READONLY ELSE AREA |ROMStartup|,CODE,PIC,READONLY ENDIF|__romBase| ; Symbol for the first location in the ROM. EXPORT |__rom| ; NOTE: This is not an APCS function|__rom| ; This is the only symbol exported from this area. It is the ; main ENTRY point into a ROM Angel world from an ARM hardware ; reset. It can also be used as an emergency re-start when ; called directly from software control. ; ; We treat the call to this code as a branch, and will *NOT* ; return to the caller. This code corrupts the r14 value ; present at the instance of the entry to this routine. NOTE: ; At this point we cannot rely on the state of the ARM ; hardware exception vectors, so the code should not generate ; aborts or events until handlers have been put in place. ; First we must get the actual start address IF ROMonly SUB r4, lr, #4 ; 1st instruction is BL __rom ELSE ADR r4, __rom ; We are linked to be the 1st module ENDIF ; ; Ensure the processor is in SVC32 mode, with IRQs and FIQs ; disabled before continuing with the initialisation. IF :DEF: HAS_ARM600_MMU ; On ARM6x0 processors the MMU control register is written as ; zero by reset. This means little-endian, early abort, 26bit ; data, 26bit program, write buffer off, cache off, alignment ; fault off and MMU off. However Angel is a 32bit clean ; system, so we need to ensure the correct processor ; configuration. MRS r14,CPSR ; get the current processor status TST r14,#(1 :SHL: 4) ; 26- or 32-bit mode? ; If bit (1 :SHL: 4) is *NOT* set then we are in a 26-bit ; mode. This code assumes that if we are started in 26-bit ; mode then we *MUST* have an MMU. MOVEQ r14,#DefaultMMUConfig ; desired state MCREQ MMUCP,0,r14,MMUControlReg,c0 ; NOTE: The above has *NOT* enabled the MMU, cache or ; write-buffer. Until the Angel system has been fully ; initialised, we cannot construct any MMU tables. The default ; Angel world defines a straight through logical-to-physical ; mapping for ARM systems with MMUs. However it is up to a ; particular developer whether an Angel ROM system enables the ; cache and write-buffer as part of its startup. This code may ; need to change when dealing with different ARM processors. ENDIF MRS r14,CPSR ; get the processor status BIC r14,r14,#ModeMask ORR r14,r14,#(SVCmode :OR: InterruptMask) MSR cpsr_cf,r14 ; SVC 32 mode with interrupts disabled ; ; state: SVC mode; IRQs disabled; FIQs disabled. ; r14 = current PSR ; r4 = PowerOnStatus [input] (zero - hard; non-zero - soft). ; r5 = RAM size, or 0x00000000 if not yet known. ; r0, r1 used as temporary working space within STARTUPCODE ; ; All other registers undefined. ; If present, MMU initialised to default off state. ; ; The following macro should perform any target specific I/O ; disabling and setup. i.e. disable all interrupt sources, set ; memory access timings, etc. STARTUPCODE r0,r1,r4,r5 IF :DEF: HAS_ARM600_MMU ; Force 32 bit address & data, little endian MOVNE r0,#0x30 ; 32-bit address & data, little-endian MCRNE MMUCP,0,r0,MMUControlReg,c0 ENDIF ; ; The following linker generated symbols are used to control ; the ROM-to-RAM copy loop: ; IMPORT |Image$$RO$$Base| ; start of ROM code IMPORT |Image$$RO$$Limit| ; end of ROM code IMPORT |Image$$RW$$Base| ; destination address of initialised R/W IMPORT |Image$$ZI$$Base| ; start of the zero initialised (BSS) data. IMPORT |Image$$RW$$Limit| ; used to size initialised R/W section ; ; These are used to copy the vector table to zero when necessary ; IMPORT |__VectorStart| IMPORT |__Vectors$$Limit| LDR r0, =|Image$$RO$$Base| ; get linked location of code ; see if we started in ROM mapped at zero or not MOVS r1, r4 LDREQ r1, =ROMBase SUB r8, r1, r0 IF :LNOT: ROMonly ; ; Z is set if we are running in ROM that has been mapped to ; zero - if this is the case, then we need to start executing ; from the real ROM and unmap the ROM from zero ; BNE RealROMAddress LDR r2, =RealROMAddress ADD pc, r2, r8RealROMAddress UNMAPROM r2, r3 ; macro to unmap ROM from 0 ; r2, r3 are passed as working space ENDIF ; :LNOT: ROMonly
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -