]>
Commit | Line | Data |
---|---|---|
80421fcc XL |
1 | /* |
2 | * Startup Code for MIPS32 XBURST CPU-core | |
3 | * | |
4 | * Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc> | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
80421fcc XL |
7 | */ |
8 | ||
9 | #include <config.h> | |
10 | #include <version.h> | |
11 | #include <asm/regdef.h> | |
12 | #include <asm/mipsregs.h> | |
13 | #include <asm/addrspace.h> | |
14 | #include <asm/cacheops.h> | |
15 | ||
16 | .set noreorder | |
17 | ||
18 | .globl _start | |
19 | .text | |
20 | _start: | |
21 | /* Initialize $gp */ | |
22 | bal 1f | |
23 | nop | |
24 | .word _gp | |
25 | 1: | |
26 | lw gp, 0(ra) | |
27 | ||
28 | /* Set up temporary stack */ | |
29 | li sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET | |
30 | ||
31 | la t9, board_init_f | |
32 | jr t9 | |
33 | nop | |
34 | ||
35 | /* | |
36 | * void relocate_code (addr_sp, gd, addr_moni) | |
37 | * | |
38 | * This "function" does not return, instead it continues in RAM | |
39 | * after relocating the monitor code. | |
40 | * | |
41 | * a0 = addr_sp | |
42 | * a1 = gd | |
43 | * a2 = destination address | |
44 | */ | |
45 | .globl relocate_code | |
46 | .ent relocate_code | |
47 | relocate_code: | |
48 | move sp, a0 # set new stack pointer | |
49 | ||
f01d6935 | 50 | move s0, a1 # save gd in s0 |
9a28e0d1 GJ |
51 | move s2, a2 # save destination address in s2 |
52 | ||
80421fcc | 53 | li t0, CONFIG_SYS_MONITOR_BASE |
ba9cf071 | 54 | sub s1, s2, t0 # s1 <-- relocation offset |
6d862278 | 55 | |
80421fcc | 56 | la t3, in_ram |
28875e2c | 57 | lw t2, -12(t3) # t2 <-- __image_copy_end |
80421fcc XL |
58 | move t1, a2 |
59 | ||
ba9cf071 | 60 | add gp, s1 # adjust gp |
80421fcc XL |
61 | |
62 | /* | |
63 | * t0 = source address | |
64 | * t1 = target address | |
65 | * t2 = source end address | |
66 | */ | |
67 | 1: | |
68 | lw t3, 0(t0) | |
69 | sw t3, 0(t1) | |
70 | addu t0, 4 | |
5b7dd816 | 71 | blt t0, t2, 1b |
80421fcc XL |
72 | addu t1, 4 |
73 | ||
74 | /* If caches were enabled, we would have to flush them here. */ | |
75 | ||
76 | /* flush d-cache */ | |
77 | li t0, KSEG0 | |
78 | addi t1, t0, CONFIG_SYS_DCACHE_SIZE | |
79 | 2: | |
cb0a6a1e | 80 | cache INDEX_WRITEBACK_INV_D, 0(t0) |
80421fcc XL |
81 | bne t0, t1, 2b |
82 | addi t0, CONFIG_SYS_CACHELINE_SIZE | |
83 | ||
84 | sync | |
85 | ||
86 | /* flush i-cache */ | |
87 | li t0, KSEG0 | |
88 | addi t1, t0, CONFIG_SYS_ICACHE_SIZE | |
89 | 3: | |
cb0a6a1e | 90 | cache INDEX_INVALIDATE_I, 0(t0) |
80421fcc XL |
91 | bne t0, t1, 3b |
92 | addi t0, CONFIG_SYS_CACHELINE_SIZE | |
93 | ||
94 | /* Invalidate BTB */ | |
95 | mfc0 t0, CP0_CONFIG, 7 | |
96 | nop | |
97 | ori t0, 2 | |
98 | mtc0 t0, CP0_CONFIG, 7 | |
99 | nop | |
100 | ||
101 | /* Jump to where we've relocated ourselves */ | |
9a28e0d1 | 102 | addi t0, s2, in_ram - _start |
80421fcc XL |
103 | jr t0 |
104 | nop | |
105 | ||
04380c65 GJ |
106 | .word __rel_dyn_end |
107 | .word __rel_dyn_start | |
28875e2c | 108 | .word __image_copy_end |
80421fcc | 109 | .word _GLOBAL_OFFSET_TABLE_ |
80421fcc XL |
110 | .word num_got_entries |
111 | ||
112 | in_ram: | |
113 | /* | |
114 | * Now we want to update GOT. | |
115 | * | |
116 | * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object | |
117 | * generated by GNU ld. Skip these reserved entries from relocation. | |
118 | */ | |
119 | lw t3, -4(t0) # t3 <-- num_got_entries | |
e5c868a2 GJ |
120 | lw t8, -8(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ |
121 | add t8, s1 # t8 now holds relocated _G_O_T_ | |
122 | addi t8, t8, 8 # skipping first two entries | |
80421fcc XL |
123 | li t2, 2 |
124 | 1: | |
e5c868a2 | 125 | lw t1, 0(t8) |
80421fcc | 126 | beqz t1, 2f |
ba9cf071 | 127 | add t1, s1 |
e5c868a2 | 128 | sw t1, 0(t8) |
80421fcc XL |
129 | 2: |
130 | addi t2, 1 | |
131 | blt t2, t3, 1b | |
e5c868a2 | 132 | addi t8, 4 |
80421fcc | 133 | |
04380c65 GJ |
134 | /* Update dynamic relocations */ |
135 | lw t1, -16(t0) # t1 <-- __rel_dyn_start | |
136 | lw t2, -20(t0) # t2 <-- __rel_dyn_end | |
137 | ||
138 | b 2f # skip first reserved entry | |
139 | addi t1, 8 | |
140 | ||
141 | 1: | |
d707e5b7 | 142 | lw t8, -4(t1) # t8 <-- relocation info |
04380c65 | 143 | |
d707e5b7 GJ |
144 | li t3, 3 |
145 | bne t8, t3, 2f # skip non R_MIPS_REL32 entries | |
04380c65 GJ |
146 | nop |
147 | ||
148 | lw t3, -8(t1) # t3 <-- location to fix up in FLASH | |
149 | ||
e5c868a2 GJ |
150 | lw t8, 0(t3) # t8 <-- original pointer |
151 | add t8, s1 # t8 <-- adjusted pointer | |
04380c65 | 152 | |
ba9cf071 | 153 | add t3, s1 # t3 <-- location to fix up in RAM |
e5c868a2 | 154 | sw t8, 0(t3) |
04380c65 GJ |
155 | |
156 | 2: | |
157 | blt t1, t2, 1b | |
158 | addi t1, 8 # each rel.dyn entry is 8 bytes | |
159 | ||
696a3b2a DS |
160 | /* |
161 | * Clear BSS | |
162 | * | |
163 | * GOT is now relocated. Thus __bss_start and __bss_end can be | |
164 | * accessed directly via $gp. | |
165 | */ | |
166 | la t1, __bss_start # t1 <-- __bss_start | |
167 | la t2, __bss_end # t2 <-- __bss_end | |
168 | ||
169 | 1: | |
170 | sw zero, 0(t1) | |
171 | blt t1, t2, 1b | |
172 | addi t1, 4 | |
80421fcc | 173 | |
f01d6935 | 174 | move a0, s0 # a0 <-- gd |
80421fcc XL |
175 | la t9, board_init_r |
176 | jr t9 | |
9a28e0d1 | 177 | move a1, s2 |
80421fcc XL |
178 | |
179 | .end relocate_code |