crt0.S
193 lines
| 6.9 KiB
| text/S-plus
|
SLexer
jeandet@pc-de-jeandet3.LAB-LPP.LOCAL
|
r18 | .global main // int main(void) | ||
.global _etext // -> .data initial values in ROM | ||||
.global _data // -> .data area in RAM | ||||
.global _edata // end of .data area | ||||
.global __bss_start // -> .bss area in RAM | ||||
.global __bss_end__ // end of .bss area | ||||
.global _stack // top of stack | ||||
// Stack Sizes | ||||
.set UND_STACK_SIZE, 0x00000004 | ||||
.set ABT_STACK_SIZE, 0x00000004 | ||||
.set FIQ_STACK_SIZE, 0x00000004 | ||||
.set IRQ_STACK_SIZE, 0X00000080 | ||||
.set SVC_STACK_SIZE, 0x00000004 | ||||
// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs | ||||
.set MODE_USR, 0x10 // User Mode | ||||
.set MODE_FIQ, 0x11 // FIQ Mode | ||||
.set MODE_IRQ, 0x12 // IRQ Mode | ||||
.set MODE_SVC, 0x13 // Supervisor Mode | ||||
.set MODE_ABT, 0x17 // Abort Mode | ||||
.set MODE_UND, 0x1B // Undefined Mode | ||||
.set MODE_SYS, 0x1F // System Mode | ||||
.equ I_BIT, 0x80 // when I bit is set, IRQ is disabled | ||||
.equ F_BIT, 0x40 // when F bit is set, FIQ is disabled | ||||
.text | ||||
.code 32 | ||||
.align 2 | ||||
.global _boot | ||||
.func _boot | ||||
_boot: | ||||
// Runtime Interrupt Vectors | ||||
// ------------------------- | ||||
Vectors: | ||||
b _start // reset - _start | ||||
ldr pc,_undf // undefined - _undf | ||||
ldr pc,_swi // SWI - _swi | ||||
ldr pc,_pabt // program abort - _pabt | ||||
ldr pc,_dabt // data abort - _dabt | ||||
nop // reserved | ||||
ldr pc,[pc,#-0xFF0] // IRQ - read the VIC | ||||
ldr pc,_fiq // FIQ - _fiq | ||||
#if 0 | ||||
// Use this group for production | ||||
_undf: .word _reset // undefined - _reset | ||||
_swi: .word _reset // SWI - _reset | ||||
_pabt: .word _reset // program abort - _reset | ||||
_dabt: .word _reset // data abort - _reset | ||||
_irq: .word _reset // IRQ - _reset | ||||
_fiq: .word _reset // FIQ - _reset | ||||
#else | ||||
// Use this group for development | ||||
_undf: .word __undf // undefined | ||||
_swi: .word __swi // SWI | ||||
_pabt: .word __pabt // program abort | ||||
_dabt: .word __dabt // data abort | ||||
_irq: .word __irq // IRQ | ||||
_fiq: .word __fiq // FIQ | ||||
__undf: b . // undefined | ||||
__swi: b . // SWI | ||||
__pabt: b . // program abort | ||||
__dabt: b . // data abort | ||||
__irq: b . // IRQ | ||||
__fiq: b . // FIQ | ||||
#endif | ||||
.size _boot, . - _boot | ||||
.endfunc | ||||
// Setup the operating mode & stack. | ||||
// --------------------------------- | ||||
.global _start, start, _mainCRTStartup | ||||
.func _start | ||||
_start: | ||||
start: | ||||
_mainCRTStartup: | ||||
// Initialize Interrupt System | ||||
// - Set stack location for each mode | ||||
// - Leave in System Mode with Interrupts Disabled | ||||
// ----------------------------------------------- | ||||
ldr r0,=_stack | ||||
msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode | ||||
mov sp,r0 | ||||
sub r0,r0,#UND_STACK_SIZE | ||||
msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode | ||||
mov sp,r0 | ||||
sub r0,r0,#ABT_STACK_SIZE | ||||
msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode | ||||
mov sp,r0 | ||||
sub r0,r0,#FIQ_STACK_SIZE | ||||
msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode | ||||
mov sp,r0 | ||||
sub r0,r0,#IRQ_STACK_SIZE | ||||
msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode | ||||
mov sp,r0 | ||||
sub r0,r0,#SVC_STACK_SIZE | ||||
msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode | ||||
mov sp,r0 | ||||
// Copy initialized data to its execution address in RAM | ||||
// ----------------------------------------------------- | ||||
#ifdef ROM_RUN | ||||
ldr r1,=_etext // -> ROM data start | ||||
ldr r2,=_data // -> data start | ||||
ldr r3,=_edata // -> end of data | ||||
1: cmp r2,r3 // check if data to move | ||||
ldrlo r0,[r1],#4 // copy it | ||||
strlo r0,[r2],#4 | ||||
blo 1b // loop until done | ||||
#endif | ||||
// Clear .bss | ||||
// ---------- | ||||
mov r0,#0 // get a zero | ||||
ldr r1,=__bss_start // -> bss start | ||||
ldr r2,=__bss_end__ // -> bss end | ||||
2: cmp r1,r2 // check if data to clear | ||||
strlo r0,[r1],#4 // clear 4 bytes | ||||
blo 2b // loop until done | ||||
/* | ||||
Call C++ constructors (for objects in "global scope") | ||||
ctor loop added by Martin Thomas 4/2005 | ||||
based on a Anglia Design example-application for ST ARM | ||||
*/ | ||||
LDR r0, =__ctors_start__ | ||||
LDR r1, =__ctors_end__ | ||||
ctor_loop: | ||||
CMP r0, r1 | ||||
BEQ ctor_end | ||||
LDR r2, [r0], #4 | ||||
STMFD sp!, {r0-r1} | ||||
MOV lr, pc | ||||
MOV pc, r2 | ||||
LDMFD sp!, {r0-r1} | ||||
B ctor_loop | ||||
ctor_end: | ||||
// Call main program: main(0) | ||||
// -------------------------- | ||||
mov r0,#0 // no arguments (argc = 0) | ||||
mov r1,r0 | ||||
mov r2,r0 | ||||
mov fp,r0 // null frame pointer | ||||
mov r7,r0 // null frame pointer for thumb | ||||
ldr r10,=main | ||||
mov lr,pc | ||||
bx r10 // enter main() | ||||
/* "global object"-dtors are never called and it should not be | ||||
needed since there is no OS to exit to. */ | ||||
.size _start, . - _start | ||||
.endfunc | ||||
.global _reset, reset, exit, abort | ||||
.func _reset | ||||
_reset: | ||||
reset: | ||||
exit: | ||||
abort: | ||||
#if 0 | ||||
// Disable interrupts, then force a hardware reset by driving P23 low | ||||
// ------------------------------------------------------------------- | ||||
mrs r0,cpsr // get PSR | ||||
orr r0,r0,#I_BIT|F_BIT // disable IRQ and FIQ | ||||
msr cpsr,r0 // set up status register | ||||
ldr r1,=(PS_BASE) // PS Base Address | ||||
ldr r0,=(PS_PIO) // PIO Module | ||||
str r0,[r1,#PS_PCER_OFF] // enable its clock | ||||
ldr r1,=(PIO_BASE) // PIO Base Address | ||||
ldr r0,=(1<<23) // P23 | ||||
str r0,[r1,#PIO_PER_OFF] // make sure pin is contolled by PIO | ||||
str r0,[r1,#PIO_CODR_OFF] // set the pin low | ||||
str r0,[r1,#PIO_OER_OFF] // make it an output | ||||
#endif | ||||
b . // loop until reset | ||||
.size _reset, . - _reset | ||||
.endfunc | ||||
.end | ||||