1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/linkage.h>
15#include <linux/init.h>
16
17#include <asm/assembler.h>
18#include <asm/domain.h>
19#include <asm/ptrace.h>
20#include <asm/asm-offsets.h>
21#include <asm/memory.h>
22#include <asm/thread_info.h>
23#include <asm/system.h>
24
25
26
27#endif
28
29#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
30#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
31
32
33
34
35
36
37
38
39
40
41
42#endif
43
44 .globl swapper_pg_dir
45 .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
46
47 .macro pgtbl, rd
48 ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
49 .endm
50
51#ifdef CONFIG_XIP_KERNEL
52#define KERNEL_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
53#define KERNEL_END _edata_loc
54#else
55#define KERNEL_START KERNEL_RAM_VADDR
56#define KERNEL_END _end
57#endif
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 .section ".text.head", "ax"
78ENTRY(stext)
79 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
80 @ and irqs disabled
81 mrc p15, 0, r9, c0, c0 @ get processor id
82 bl __lookup_processor_type @ r5=procinfo r9=cpuid
83 movs r10, r5 @ invalid processor (r5=0)?
84 beq __error_p @ yes, error 'p'
85 bl __lookup_machine_type @ r5=machinfo
86 movs r8, r5 @ invalid machine (r5=0)?
87 beq __error_a @ yes, error 'a'
88 bl __vet_atags
89 bl __create_page_tables
90
91
92
93
94
95
96
97
98 ldr r13, __switch_data @ address to jump to after
99 @ mmu has been enabled
100 adr lr, BSYM(__enable_mmu) @ return (PIC) address
101 ARM( add pc, r10,
102 THUMB( add r12, r10,
103 THUMB( mov pc, r12 )
104ENDPROC(stext)
105
106
107ENTRY(secondary_startup)
108
109
110
111
112
113
114
115 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
116 mrc p15, 0, r9, c0, c0 @ get processor id
117 bl __lookup_processor_type
118 movs r10, r5 @ invalid processor?
119 moveq r0,
120 beq __error
121
122
123
124
125 adr r4, __secondary_data
126 ldmia r4, {r5, r7, r12} @ address to jump to after
127 sub r4, r4, r5 @ mmu has been enabled
128 ldr r4, [r7, r4] @ get secondary_data.pgdir
129 adr lr, BSYM(__enable_mmu) @ return address
130 mov r13, r12 @ __secondary_switched address
131 ARM( add pc, r10,
132 @ (return control reg)
133 THUMB( add r12, r10,
134 THUMB( mov pc, r12 )
135ENDPROC(secondary_startup)
136
137
138
139
140ENTRY(__secondary_switched)
141 ldr sp, [r7,
142 mov fp,
143 b secondary_start_kernel
144ENDPROC(__secondary_switched)
145
146 .type __secondary_data, %object
147__secondary_data:
148 .long .
149 .long secondary_data
150 .long __secondary_switched
151#endif
152
153
154
155
156
157
158
159
160__enable_mmu:
161#ifdef CONFIG_ALIGNMENT_TRAP
162 orr r0, r0,
163#else
164 bic r0, r0,
165#endif
166#ifdef CONFIG_CPU_DCACHE_DISABLE
167 bic r0, r0,
168#endif
169#ifdef CONFIG_CPU_BPREDICT_DISABLE
170 bic r0, r0,
171#endif
172#ifdef CONFIG_CPU_ICACHE_DISABLE
173 bic r0, r0,
174#endif
175 mov r5,
176 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
177 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
178 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
179 mcr p15, 0, r5, c3, c0, 0 @ load domain access register
180 mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
181 b __turn_mmu_on
182ENDPROC(__enable_mmu)
183
184
185
186
187
188
189
190
191
192
193
194
195 .align 5
196__turn_mmu_on:
197 mov r0, r0
198 mcr p15, 0, r0, c1, c0, 0 @ write control reg
199 mrc p15, 0, r3, c0, c0, 0 @ read id reg
200 mov r3, r3
201 mov r3, r13
202 mov pc, r3
203ENDPROC(__turn_mmu_on)
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219__create_page_tables:
220 pgtbl r4 @ page table address
221
222
223
224
225 mov r0, r4
226 mov r3,
227 add r6, r0,
2281: str r3, [r0],
229 str r3, [r0],
230 str r3, [r0],
231 str r3, [r0],
232 teq r0, r6
233 bne 1b
234
235 ldr r7, [r10,
236
237
238
239
240
241
242
243 mov r6, pc
244 mov r6, r6, lsr
245 orr r3, r7, r6, lsl
246 str r3, [r4, r6, lsl
247
248
249
250
251
252 add r0, r4,
253 str r3, [r0,
254 ldr r6, =(KERNEL_END - 1)
255 add r0, r0,
256 add r6, r4, r6, lsr
2571: cmp r0, r6
258 add r3, r3,
259 strls r3, [r0],
260 bls 1b
261
262#ifdef CONFIG_XIP_KERNEL
263
264
265
266 orr r3, r7,
267 .if (KERNEL_RAM_PADDR & 0x00f00000)
268 orr r3, r3,
269 .endif
270 add r0, r4,
271 str r3, [r0,
272 ldr r6, =(_end - 1)
273 add r0, r0,
274 add r6, r4, r6, lsr
2751: cmp r0, r6
276 add r3, r3,
277 strls r3, [r0],
278 bls 1b
279#endif
280
281
282
283
284 add r0, r4,
285 orr r6, r7,
286 .if (PHYS_OFFSET & 0x00f00000)
287 orr r6, r6,
288 .endif
289 str r6, [r0]
290
291#ifdef CONFIG_DEBUG_LL
292 ldr r7, [r10,
293
294
295
296
297
298 ldr r3, [r8,
299 add r0, r4, r3
300 rsb r3, r3,
301 cmp r3,
302 movhi r3,
303 add r6, r0, r3
304 ldr r3, [r8,
305 orr r3, r3, r7
3061: str r3, [r0],
307 add r3, r3,
308 teq r0, r6
309 bne 1b
310
311
312
313
314
315 add r0, r4,
316 orr r3, r7,
317 str r3, [r0]
318#endif
319#ifdef CONFIG_ARCH_RPC
320
321
322
323
324
325 add r0, r4,
326 orr r3, r7,
327 str r3, [r0]
328 add r0, r4,
329 str r3, [r0]
330#endif
331#endif
332 mov pc, lr
333ENDPROC(__create_page_tables)
334 .ltorg
335
336#include "head-common.S"
337