]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/mips/cpu/xburst/start.S
MIPS: always keep all sections in u-boot ELF binary.
[people/ms/u-boot.git] / arch / mips / cpu / xburst / start.S
CommitLineData
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
251:
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
47relocate_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 */
671:
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
792:
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
893:
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
112in_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
1241:
e5c868a2 125 lw t1, 0(t8)
80421fcc 126 beqz t1, 2f
ba9cf071 127 add t1, s1
e5c868a2 128 sw t1, 0(t8)
80421fcc
XL
1292:
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
1411:
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
1562:
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
1691:
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