Marcin Bukat | 7552542 | 2014-02-09 22:25:25 +0100 | [diff] [blame] | 1 | #include "mips.h" |
| 2 | |
| 3 | .extern main |
| 4 | .global start |
| 5 | |
| 6 | .set mips32r2 |
| 7 | .set noreorder |
| 8 | .set noat |
| 9 | |
| 10 | .section .init.text,"ax",%progbits |
| 11 | |
| 12 | start: |
| 13 | di # disable interrupts |
| 14 | bltzal zero, load_addr # ra = PC + 8, branch not taken |
| 15 | nop |
| 16 | |
| 17 | load_addr: |
| 18 | addiu v0, ra, -12 # calc real load address |
| 19 | # account for branch delay slot |
| 20 | # and very first 'di' instruction |
Marcin Bukat | 101d10f | 2014-02-14 08:37:01 +0100 | [diff] [blame] | 21 | lui t3, 0xa000 # use KSEG1 uncached unmapped |
| 22 | la t0, relocstart # addresses as we don't know |
| 23 | or t0, t0, t3 # the state of caches |
Marcin Bukat | 7552542 | 2014-02-09 22:25:25 +0100 | [diff] [blame] | 24 | la t1, relocend |
Marcin Bukat | 101d10f | 2014-02-14 08:37:01 +0100 | [diff] [blame] | 25 | or t1, t1, t3 |
| 26 | beq t0, v0, cache_init # no relocation needed |
Marcin Bukat | 7552542 | 2014-02-09 22:25:25 +0100 | [diff] [blame] | 27 | nop |
| 28 | |
| 29 | reloc_loop: |
| 30 | lw t2, 0(v0) # src |
| 31 | addiu v0, 4 # inc src addr |
| 32 | sw t2, 0(t0) # dst |
| 33 | bne t0, t1, reloc_loop |
| 34 | addiu t0, 4 # inc dst addr |
| 35 | |
Marcin Bukat | 101d10f | 2014-02-14 08:37:01 +0100 | [diff] [blame] | 36 | cache_init: |
Marcin Bukat | 7552542 | 2014-02-09 22:25:25 +0100 | [diff] [blame] | 37 | # setup caches |
| 38 | # 4-way, 256 sets, 16 bytes cacheline I/D |
| 39 | li t0, 3 # enable cache for kseg0 accesses |
| 40 | mtc0 t0, C0_CONFIG |
| 41 | |
| 42 | la t0, 0x80000000 # an idx op should use an unmappable address |
| 43 | ori t1, t0, 0x4000 # 16kB cache |
| 44 | mtc0 zero, C0_TAGLO |
| 45 | mtc0 zero, C0_TAGHI |
| 46 | |
| 47 | cache_init_loop: |
| 48 | cache 8, 0(t0) # index store icache tag |
| 49 | cache 9, 0(t0) # index store dcache tag |
| 50 | bne t0, t1, cache_init_loop |
| 51 | addiu t0, t0, 0x10 |
| 52 | |
| 53 | intc_setup: |
| 54 | li t0, 0xb0020000 # INTC base |
| 55 | lw zero, 4(t0) # INTC_MSK mask all interrupt sources |
| 56 | |
| 57 | core_irq_setup: |
| 58 | li t0, 0x00404000 # BEV=1 for C0_EBASE setup, IM6=1, IE=0 |
| 59 | mtc0 t0, C0_STATUS |
| 60 | |
| 61 | la t0, _irqbase # vectors base address must be 4k aligned |
| 62 | mtc0 t0, C0_EBASE |
| 63 | |
| 64 | li t0, 0x00004000 |
| 65 | mtc0 t0, C0_STATUS # BEV=0, IM6=1, IE=0 |
| 66 | |
| 67 | li t1, 0x08800000 |
| 68 | mtc0 t1, C0_CAUSE # DC=1, IV=1 |
| 69 | mtc0 zero,C0_INTCTL # VS = 0 |
| 70 | |
| 71 | # clear bss |
| 72 | la t0, bssbegin |
| 73 | la t1, bssend |
| 74 | |
| 75 | clear_bss_loop: |
| 76 | sw zero, 0(t0) |
| 77 | bne t0, t1, clear_bss_loop |
| 78 | addiu t0, 4 |
| 79 | |
| 80 | # setup stack |
| 81 | la k0, irqstackend |
| 82 | la sp, stackend |
| 83 | la t0, stackbegin |
| 84 | li t1, 0xdeadbeef |
| 85 | |
| 86 | stack_munge_loop: |
| 87 | sw t1, 0(t0) |
| 88 | bne t0, sp, stack_munge_loop |
| 89 | addiu t0, 4 |
| 90 | |
| 91 | # jump to C code with enabled interrupts |
Marcin Bukat | 101d10f | 2014-02-14 08:37:01 +0100 | [diff] [blame] | 92 | la t0, main |
| 93 | jr t0 |
Marcin Bukat | 7552542 | 2014-02-09 22:25:25 +0100 | [diff] [blame] | 94 | ei |
| 95 | |
| 96 | .set at |
| 97 | .set reorder |