diff options
Diffstat (limited to 'Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S')
| -rw-r--r-- | Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S new file mode 100644 index 0000000..3786ac7 --- /dev/null +++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S @@ -0,0 +1,164 @@ +;
+; The AREA must have the attribute READONLY, otherwise the linker will not
+; place it in ROM.
+;
+; The AREA must have the attribute CODE, otherwise the assembler will not
+; let us put any code in this AREA
+;
+; Note the '|' character is used to surround any symbols which contain
+; non standard characters like '!'.
+
+ AREA Init, CODE, READONLY
+
+; Now some standard definitions...
+
+Mode_IRQ EQU 0x12
+Mode_SVC EQU 0x13
+
+I_Bit EQU 0x80
+F_Bit EQU 0x40
+
+SWI_Exit EQU 0x11
+
+; Locations of various things in our memory system
+
+RAM_Base EQU 0x10000000 ; 64k RAM at this base
+RAM_Limit EQU 0x10010000
+
+IRQ_Stack EQU RAM_Limit ; 1K IRQ stack at top of memory
+SVC_Stack EQU RAM_Limit-1024 ; followed by SVC stack
+
+; --- Define __main & set entry point
+ ENTRY
+
+; --- Setup interrupt / exception vectors
+ IF :DEF: ROM_AT_ADDRESS_ZERO
+; If the ROM is at address 0 this is just a sequence of branches
+ B Reset_Handler
+ B Undefined_Handler
+ B SWI_Handler
+ B Prefetch_Handler
+ B Abort_Handler
+ NOP ; Reserved vector
+ B IRQ_Handler
+ B FIQ_Handler
+ ELSE
+; Otherwise we copy a sequence of LDR PC instructions over the vectors
+; (Note: We copy LDR PC instructions because branch instructions
+; could not simply be copied, the offset in the branch instruction
+; would have to be modified so that it branched into ROM. Also, a
+; branch instructions might not reach if the ROM is at an address
+; > 32M).
+ MOV R8, #0
+ ADR R9, Vector_Init_Block
+ LDMIA R9!, {R0-R7}
+ STMIA R8!, {R0-R7}
+ LDMIA R9!, {R0-R7}
+ STMIA R8!, {R0-R7}
+
+; Now fall into the LDR PC, Reset_Addr instruction which will continue
+; execution at 'Reset_Handler'
+
+Vector_Init_Block
+ LDR PC, Reset_Addr
+ LDR PC, Undefined_Addr
+ LDR PC, SWI_Addr
+ LDR PC, Prefetch_Addr
+ LDR PC, Abort_Addr
+ NOP
+ LDR PC, IRQ_Addr
+ LDR PC, FIQ_Addr
+
+Reset_Addr DCD Reset_Handler
+Undefined_Addr DCD Undefined_Handler
+SWI_Addr DCD SWI_Handler
+Prefetch_Addr DCD Prefetch_Handler
+Abort_Addr DCD Abort_Handler
+ DCD 0 ; Reserved vector
+IRQ_Addr DCD IRQ_Handler
+FIQ_Addr DCD FIQ_Handler
+ ENDIF
+
+; The following handlers do not do anything useful in this example.
+;
+Undefined_Handler
+ B Undefined_Handler
+SWI_Handler
+ B SWI_Handler
+Prefetch_Handler
+ B Prefetch_Handler
+Abort_Handler
+ B Abort_Handler
+IRQ_Handler
+ B IRQ_Handler
+FIQ_Handler
+ B FIQ_Handler
+
+; The RESET entry point
+Reset_Handler
+
+; --- Initialise stack pointer registers
+; Enter IRQ mode and set up the IRQ stack pointer
+ MOV R0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
+ MSR CPSR, R0
+ LDR R13, =IRQ_Stack
+
+; Set up other stack pointers if necessary
+ ; ...
+
+; Set up the SVC stack pointer last and return to SVC mode
+ MOV R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
+ MSR CPSR, R0
+ LDR R13, =SVC_Stack
+
+; --- Initialise memory system
+ ; ...
+
+; --- Initialise critical IO devices
+ ; ...
+
+; --- Initialise interrupt system variables here
+ ; ...
+
+; --- Enable interrupts
+; Now safe to enable interrupts, so do this and remain in SVC mode
+ MOV R0, #Mode_SVC:OR:F_Bit ; Only IRQ enabled
+ MSR CPSR, R0
+
+; --- Initialise memory required by C code
+
+ IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
+ IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
+ IMPORT |Image$$ZI$$Base| ; Base and limit of area
+ IMPORT |Image$$ZI$$Limit| ; to zero initialise
+
+ LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
+ LDR r1, =|Image$$RW$$Base| ; and RAM copy
+ LDR r3, =|Image$$ZI$$Base| ; Zero init base => top of initialised data
+ CMP r0, r1 ; Check that they are different
+ BEQ %1
+0 CMP r1, r3 ; Copy init data
+ LDRCC r2, [r0], #4
+ STRCC r2, [r1], #4
+ BCC %0
+1 LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment
+ MOV r2, #0
+2 CMP r3, r1 ; Zero init
+ STRCC r2, [r3], #4
+ BCC %2
+
+; --- Now we enter the C code
+
+ IMPORT C_Entry
+ [ :DEF:THUMB
+ ORR lr, pc, #1
+ BX lr
+ CODE16 ; Next instruction will be Thumb
+ ]
+ BL C_Entry
+; In a real application we wouldn't normally expect to return, however
+; this example does so the debug monitor swi SWI_Exit is used to halt the
+; application.
+ SWI SWI_Exit
+
+ END
|
