aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/boot/simple/relocate.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/boot/simple/relocate.S')
-rw-r--r--arch/ppc/boot/simple/relocate.S213
1 files changed, 0 insertions, 213 deletions
diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S
deleted file mode 100644
index 1bbbcd2f2bcb..000000000000
--- a/arch/ppc/boot/simple/relocate.S
+++ /dev/null
@@ -1,213 +0,0 @@
1/*
2 * This is the common part of the loader relocation and initialization
3 * process. All of the board/processor specific initialization is
4 * done before we get here.
5 *
6 * Author: Tom Rini
7 * trini@mvista.com
8 * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
9 *
10 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15
16#include <asm/cache.h>
17#include <asm/ppc_asm.h>
18
19#define GETSYM(reg, sym) \
20 lis reg, sym@h; ori reg, reg, sym@l
21
22 .text
23 /* We get called from the early initialization code.
24 * Register 3 has the address where we were loaded,
25 * Register 4 contains any residual data passed from the
26 * boot rom.
27 */
28 .globl relocate
29relocate:
30 /* Save r3, r4 for later.
31 * The r8/r11 are legacy registers so I don't have to
32 * rewrite the code below :-).
33 */
34 mr r8, r3
35 mr r11, r4
36
37 /* compute the size of the whole image in words. */
38 GETSYM(r4,start)
39 GETSYM(r5,end)
40
41 addi r5,r5,3 /* round up */
42 sub r5,r5,r4 /* end - start */
43 srwi r5,r5,2
44 mr r7,r5 /* Save for later use. */
45
46 /*
47 * Check if we need to relocate ourselves to the link addr or were
48 * we loaded there to begin with.
49 */
50 cmpw cr0,r3,r4
51 beq start_ldr /* If 0, we don't need to relocate */
52
53 /* Move this code somewhere safe. This is max(load + size, end)
54 * r8 == load address
55 */
56 GETSYM(r4, start)
57 GETSYM(r5, end)
58
59 sub r6,r5,r4
60 add r6,r8,r6 /* r6 == phys(load + size) */
61
62 cmpw r5,r6
63 bgt 1f
64 b 2f
651:
66 mr r6, r5
672:
68 /* dest is in r6 */
69 /* Ensure alignment --- this code is precautionary */
70 addi r6,r6,4
71 li r5,0x0003
72 andc r6,r6,r5
73
74 /* Find physical address and size of do_relocate */
75 GETSYM(r5, __relocate_start)
76 GETSYM(r4, __relocate_end)
77 GETSYM(r3, start)
78
79 /* Size to copy */
80 sub r4,r4,r5
81 srwi r4,r4,2
82
83 /* Src addr to copy (= __relocate_start - start + where_loaded) */
84 sub r3,r5,r3
85 add r5,r8,r3
86
87 /* Save dest */
88 mr r3, r6
89
90 /* Do the copy */
91 mtctr r4
923: lwz r4,0(r5)
93 stw r4,0(r3)
94 addi r3,r3,4
95 addi r5,r5,4
96 bdnz 3b
97
98 GETSYM(r4, __relocate_start)
99 GETSYM(r5, do_relocate)
100
101 sub r4,r5,r4 /* Get entry point for do_relocate in */
102 add r6,r6,r4 /* relocated section */
103
104 /* This will return to the relocated do_relocate */
105 mtlr r6
106 b flush_instruction_cache
107
108 .section ".relocate_code","xa"
109
110do_relocate:
111 /* We have 2 cases --- start < load, or start > load
112 * This determines whether we copy from the end, or the start.
113 * Its easier to have 2 loops than to have paramaterised
114 * loops. Sigh.
115 */
116 li r6,0 /* Clear checksum */
117 mtctr r7 /* Setup for a loop */
118
119 GETSYM(r4, start)
120 mr r3,r8 /* Get the load addr */
121
122 cmpw cr0,r4,r3 /* If we need to copy from the end, do so */
123 bgt do_relocate_from_end
124
125do_relocate_from_start:
1261: lwz r5,0(r3) /* Load and decrement */
127 stw r5,0(r4) /* Store and decrement */
128 addi r3,r3,4
129 addi r4,r4,4
130 xor r6,r6,r5 /* Update checksum */
131 bdnz 1b /* Are we done? */
132 b do_relocate_out /* Finished */
133
134do_relocate_from_end:
135 GETSYM(r3, end)
136 slwi r4,r7,2
137 add r4,r8,r4 /* Get the physical end */
1381: lwzu r5,-4(r4)
139 stwu r5, -4(r3)
140 xor r6,r6,r5
141 bdnz 1b
142
143do_relocate_out:
144 GETSYM(r3,start_ldr)
145 mtlr r3 /* Easiest way to do an absolute jump */
146/* Some boards don't boot up with the I-cache enabled. Do that
147 * now because the decompress runs much faster that way.
148 * As a side effect, we have to ensure the data cache is not enabled
149 * so we can access the serial I/O without trouble.
150 */
151 b flush_instruction_cache
152
153 .previous
154
155start_ldr:
156/* Clear all of BSS and set up stack for C calls */
157 lis r3,__bss_start@h
158 ori r3,r3,__bss_start@l
159 lis r4,end@h
160 ori r4,r4,end@l
161 subi r3,r3,4
162 subi r4,r4,4
163 li r0,0
16450: stwu r0,4(r3)
165 cmpw cr0,r3,r4
166 blt 50b
16790: mr r9,r1 /* Save old stack pointer (in case it matters) */
168 lis r1,.stack@h
169 ori r1,r1,.stack@l
170 addi r1,r1,4096*2
171 subi r1,r1,256
172 li r2,0x000F /* Mask pointer to 16-byte boundary */
173 andc r1,r1,r2
174
175 /*
176 * Exec kernel loader
177 */
178 mr r3,r8 /* Load point */
179 mr r4,r7 /* Program length */
180 mr r5,r6 /* Checksum */
181 mr r6,r11 /* Residual data */
182 mr r7,r25 /* Validated OFW interface */
183 bl load_kernel
184
185 /*
186 * Make sure the kernel knows we don't have things set in
187 * registers. -- Tom
188 */
189 li r4,0
190 li r5,0
191 li r6,0
192
193 /*
194 * Start at the begining.
195 */
196#ifdef CONFIG_PPC_PREP
197 li r9,0xc
198 mtlr r9
199 /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD,
200 * and tell the kernel to start on the 4th instruction since we
201 * overwrite the first 3 sometimes (which are 'nop').
202 */
203 lis r10,0xdeadc0de@h
204 ori r10,r10,0xdeadc0de@l
205 li r9,0
206 stw r10,0(r9)
207#else
208 li r9,0
209 mtlr r9
210#endif
211 blr
212
213 .comm .stack,4096*2,4