nkeynes@812 | 1 | .section .text
|
nkeynes@812 | 2 | .code 32
|
nkeynes@812 | 3 | .align 0
|
nkeynes@812 | 4 | .global start
|
nkeynes@812 | 5 | .global ___exit
|
nkeynes@812 | 6 | .global _atexit
|
nkeynes@812 | 7 | start:
|
nkeynes@821 | 8 | b real_entry
|
nkeynes@821 | 9 | b exception_entry
|
nkeynes@821 | 10 | b exception_entry /* SWI - not used so jump to general exception */
|
nkeynes@821 | 11 | b exception_entry
|
nkeynes@821 | 12 | b exception_entry
|
nkeynes@821 | 13 | b exception_entry /* Not a vector, but if we ever get here... */
|
nkeynes@821 | 14 | b irq_entry
|
nkeynes@821 | 15 | b fiq_entry
|
nkeynes@812 | 16 |
|
nkeynes@812 | 17 | /* Start by setting up a stack */
|
nkeynes@821 | 18 | real_entry:
|
nkeynes@812 | 19 | /* Set up the stack pointer to a fixed value */
|
nkeynes@812 | 20 | ldr r3, .LC0
|
nkeynes@812 | 21 | mov sp, r3
|
nkeynes@812 | 22 | /* Setup a default stack-limit in-case the code has been
|
nkeynes@812 | 23 | compiled with "-mapcs-stack-check". Hard-wiring this value
|
nkeynes@812 | 24 | is not ideal, since there is currently no support for
|
nkeynes@812 | 25 | checking that the heap and stack have not collided, or that
|
nkeynes@812 | 26 | this default 64k is enough for the program being executed.
|
nkeynes@812 | 27 | However, it ensures that this simple crt0 world will not
|
nkeynes@812 | 28 | immediately cause an overflow event: */
|
nkeynes@812 | 29 | sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
|
nkeynes@821 | 30 | b .LB0
|
nkeynes@812 | 31 |
|
nkeynes@821 | 32 | .syscall:
|
nkeynes@821 | 33 | .word -1 /* Syscall # */
|
nkeynes@821 | 34 | .word 0 /* Arguments */
|
nkeynes@821 | 35 | .word 0
|
nkeynes@821 | 36 | .word 0
|
nkeynes@821 | 37 |
|
nkeynes@821 | 38 | irq_counter:
|
nkeynes@821 | 39 | .word 0
|
nkeynes@821 | 40 | fiq_counter:
|
nkeynes@821 | 41 | .word 0
|
nkeynes@821 | 42 |
|
nkeynes@821 | 43 | .LB0:
|
nkeynes@812 | 44 | /* Zero-out the BSS segment */
|
nkeynes@812 | 45 | mov a2, #0 /* Second arg: fill value */
|
nkeynes@812 | 46 | mov fp, a2 /* Null frame pointer */
|
nkeynes@812 | 47 | mov r7, a2 /* Null frame pointer for Thumb */
|
nkeynes@812 | 48 |
|
nkeynes@812 | 49 | ldr a1, .LC1 /* First arg: start of memory block */
|
nkeynes@812 | 50 | ldr a3, .LC2
|
nkeynes@812 | 51 | sub a3, a3, a1 /* Third arg: length of block */
|
nkeynes@812 | 52 | bl memset
|
nkeynes@812 | 53 |
|
nkeynes@812 | 54 | /* Enter main with no arguments for now */
|
nkeynes@812 | 55 | mov r0, #0 /* no arguments */
|
nkeynes@812 | 56 | mov r1, #0 /* no argv either */
|
nkeynes@812 | 57 | bl main
|
nkeynes@812 | 58 |
|
nkeynes@812 | 59 | bl exit /* Should not return */
|
nkeynes@812 | 60 |
|
nkeynes@812 | 61 | /* For Thumb, constants must be after the code since only
|
nkeynes@812 | 62 | positive offsets are supported for PC relative addresses. */
|
nkeynes@821 | 63 |
|
nkeynes@821 | 64 | exception_entry:
|
nkeynes@821 | 65 | mov r13, #-2
|
nkeynes@821 | 66 | str r13, .syscall
|
nkeynes@821 | 67 | .die:
|
nkeynes@821 | 68 | b .die
|
nkeynes@812 | 69 |
|
nkeynes@821 | 70 | irq_entry:
|
nkeynes@821 | 71 | /* Increment IRQ counter and return */
|
nkeynes@821 | 72 | ldr r13, irq_counter
|
nkeynes@821 | 73 | add r13, r13, #1
|
nkeynes@821 | 74 | str r13, irq_counter
|
nkeynes@821 | 75 | subs r15, r14, #4
|
nkeynes@821 | 76 | fiq_entry:
|
nkeynes@821 | 77 | /* Increment FIQ counter and return */
|
nkeynes@821 | 78 | ldr r13, fiq_counter
|
nkeynes@821 | 79 | add r13, r13, #1
|
nkeynes@821 | 80 | str r13, fiq_counter
|
nkeynes@821 | 81 | subs r15, r14, #4
|
nkeynes@821 | 82 |
|
nkeynes@812 | 83 | .align 0
|
nkeynes@812 | 84 | .LC0:
|
nkeynes@812 | 85 | .word _stack
|
nkeynes@812 | 86 | .LC1:
|
nkeynes@812 | 87 | .word __bss_start
|
nkeynes@812 | 88 | .LC2:
|
nkeynes@812 | 89 | .word __bss_end
|
nkeynes@812 | 90 |
|
nkeynes@812 | 91 |
|