source: mainline/boot/arch/ppc32/src/asm.S

Last change on this file was cfdeedc, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Keep kernel in ELF format

By keeping kernel in an ELF file (instead of converting it to
a flat binary), we can use the information it contains, like
symbol table and debug info.

We can also later implement more advanced functionality, like
loading kernel at multiple discontiguous blocks, or loading
a position-independent kernel at a randomized address.

Currently the functionality is quite restricted, to keep changes
to a minimum. Code in boot/generic/src/kernel.c validates that
the kernel image was built with the same addresses as the boot
loader uses, giving an extra level of sanity checking compared
to a flat binary.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1#
2# Copyright (c) 2006 Martin Decky
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8#
9# - Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# - Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14# - The name of the author may not be used to endorse or promote products
15# derived from this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28
29#include <abi/asmtool.h>
30#include <arch/arch.h>
31#include <arch/regname.h>
32
33.macro SMC_COHERENCY addr
34 dcbst 0, \addr
35 sync
36 icbi 0, \addr
37 sync
38 isync
39.endm
40
41.macro FLUSH_DCACHE addr
42 dcbst 0, \addr
43 sync
44 isync
45.endm
46
47.macro TLB_FLUSH reg
48 li \reg, 0
49 sync
50
51 .rept 64
52 tlbie \reg
53 addi \reg, \reg, 0x1000
54 .endr
55
56 eieio
57 tlbsync
58 sync
59.endm
60
61.macro BAT_COMPUTE base size mask lower upper
62 # less than 128 KB -> no BAT
63
64 lis \upper, 0x0002
65 cmpw \size, \upper
66 blt no_bat
67
68 # mask = total >> 18
69
70 li \upper, 18
71 srw \mask, \size, \upper
72
73 # create Block Length mask by replicating
74 # the leading logical one 14 times
75
76 li \upper, 14
77 mtctr \mask
78 li \upper, 1
79
80 0:
81 # mask = (mask >> 1) | mask
82
83 srw \lower, \mask, \upper
84 or \mask, \mask, \lower
85
86 bdnz 0b
87
88 # mask = mask & 0x07ff
89 # (BAT can map up to 256 MB)
90
91 andi. \mask, \mask, 0x07ff
92
93 # mask = (mask << 2) | 0x0002
94 # (priviledged access only)
95
96 li \upper, 2
97 slw \mask, \mask, \upper
98 ori \mask, \mask, 0x0002
99
100 lis \upper, (0x8000 + \base)
101 or \upper, \upper, \mask
102
103 lis \lower, \base
104 ori \lower, \lower, 0x0002
105.endm
106
107.section BOOTSTRAP, "ax"
108
109SYMBOL(start)
110 lis r4, ofw_cif@ha
111 addi r4, r4, ofw_cif@l
112 stw r5, 0(r4)
113
114 bl ofw_init
115 b bootstrap
116
117.text
118
119FUNCTION_BEGIN(halt)
120 b halt
121FUNCTION_END(halt)
122
123FUNCTION_BEGIN(jump_to_kernel)
124 # arguments:
125 # r3 = bootinfo (physical address)
126 # r4 = translate table (physical address)
127 # r5 = pages to translate
128 # r6 = real mode meeting point (physical address)
129 # r7 = kernel entry point (virtual address in kernel's address space)
130
131 # disable interrupts
132
133 mfmsr r31
134 rlwinm r31, r31, 0, 17, 15
135 mtmsr r31
136
137 # set real mode meeting point physical address
138
139 mtspr srr0, r6
140
141 # jump to real_mode
142
143 mfmsr r31
144 lis r30, ~0@h
145 ori r30, r30, ~(msr_ir | msr_dr | msr_ee)@l
146 and r31, r31, r30
147 mtspr srr1, r31
148
149 sync
150 isync
151 rfi
152FUNCTION_END(jump_to_kernel)
153
154SYMBOL(real_mode)
155
156 # arguments:
157 # r3 = bootinfo (physical address)
158 # r4 = translate table (physical address)
159 # r5 = pages to translate
160 # r7 = kernel entry point (virtual address in kernel's address space)
161
162 # move the images of components to the proper
163 # location using the translate table
164
165 li r31, PAGE_SIZE >> 2
166 li r30, 0
167
168 page_copy:
169
170 cmpwi r5, 0
171 beq copy_end
172
173 mtctr r31
174 lwz r29, 0(r4)
175
176 copy_loop:
177
178 lwz r28, 0(r29)
179 stw r28, 0(r30)
180
181 SMC_COHERENCY r30
182
183 addi r29, r29, 4
184 addi r30, r30, 4
185
186 bdnz copy_loop
187
188 addi r4, r4, 4
189 subi r5, r5, 1
190 b page_copy
191
192 copy_end:
193
194 # initially fill segment registers
195
196 li r31, 0
197
198 li r29, 8
199 mtctr r29
200 li r30, 0 # ASID 0 (VSIDs 0 .. 7)
201
202 seg_fill_uspace:
203
204 mtsrin r30, r31
205 addi r30, r30, 1
206 addis r31, r31, 0x1000 # move to next SR
207
208 bdnz seg_fill_uspace
209
210 li r29, 8
211 mtctr r29
212 lis r30, 0x4000 # priviledged access only
213 ori r30, r30, 8 # ASID 0 (VSIDs 8 .. 15)
214
215 seg_fill_kernel:
216
217 mtsrin r30, r31
218 addi r30, r30, 1
219 addis r31, r31, 0x1000 # move to next SR
220
221 bdnz seg_fill_kernel
222
223 # invalidate block address translation registers
224
225 li r30, 0
226
227 mtspr ibat0u, r30
228 mtspr ibat0l, r30
229
230 mtspr ibat1u, r30
231 mtspr ibat1l, r30
232
233 mtspr ibat2u, r30
234 mtspr ibat2l, r30
235
236 mtspr ibat3u, r30
237 mtspr ibat3l, r30
238
239 mtspr dbat0u, r30
240 mtspr dbat0l, r30
241
242 mtspr dbat1u, r30
243 mtspr dbat1l, r30
244
245 mtspr dbat2u, r30
246 mtspr dbat2l, r30
247
248 mtspr dbat3u, r30
249 mtspr dbat3l, r30
250
251 # create empty Page Hash Table
252 # on top of memory, size 64 KB
253
254 lwz r31, 4(r3) # r31 = memory size
255
256 lis r30, 65536@h
257 ori r30, r30, 65536@l # r30 = 65536
258
259 subi r29, r30, 1 # r29 = 65535
260
261 sub r31, r31, r30
262 andc r31, r31, r29 # pht = ALIGN_DOWN(memory_size - 65536, 65536)
263
264 mtsdr1 r31
265
266 li r29, 2
267 srw r30, r30, r29 # r30 = 16384
268 li r29, 0
269
270 pht_clear:
271
272 # write zeroes
273
274 stw r29, 0(r31)
275 FLUSH_DCACHE r31
276
277 addi r31, r31, 4
278 subi r30, r30, 4
279
280 cmpwi r30, 0
281 beq clear_end
282
283 bdnz pht_clear
284
285 clear_end:
286
287 # create BAT identity mapping
288
289 lwz r31, 4(r3) # r31 = memory size
290
291 lis r30, 268435456@h
292 ori r30, r30, 268435456@l # r30 = 256 MB
293
294 # BAT0
295
296 # r29 = min(r31, r30)
297
298 cmpw r31, r30
299 blt bat0_r31
300
301 mr r29, r30
302 b bat0_r30
303
304 bat0_r31:
305
306 mr r29, r31
307
308 bat0_r30:
309
310 BAT_COMPUTE 0x0000 r29 r28 r27 r26
311 mtspr ibat0u, r26
312 mtspr ibat0l, r27
313
314 mtspr dbat0u, r26
315 mtspr dbat0l, r27
316
317 # BAT1
318
319 sub r31, r31, r29 # r31 = r31 - r29
320
321 # r29 = min(r31, r30)
322
323 cmpw r31, r30
324 blt bat1_r31
325
326 mr r29, r30
327 b bat1_r30
328
329 bat1_r31:
330
331 mr r29, r31
332
333 bat1_r30:
334
335 BAT_COMPUTE 0x1000 r29 r28 r27 r26
336 mtspr ibat1u, r26
337 mtspr ibat1l, r27
338
339 mtspr dbat1u, r26
340 mtspr dbat1l, r27
341
342 # BAT2
343
344 sub r31, r31, r29 # r31 = r31 - r29
345
346 # r29 = min(r31, r30)
347
348 cmpw r31, r30
349 blt bat2_r31
350
351 mr r29, r30
352 b bat2_r30
353
354 bat2_r31:
355
356 mr r29, r31
357
358 bat2_r30:
359
360 BAT_COMPUTE 0x2000 r29 r28 r27 r26
361 mtspr ibat2u, r26
362 mtspr ibat2l, r27
363
364 mtspr dbat2u, r26
365 mtspr dbat2l, r27
366
367 # BAT3
368
369 sub r31, r31, r29 # r31 = r31 - r29
370
371 # r29 = min(r31, r30)
372
373 cmpw r31, r30
374 blt bat3_r31
375
376 mr r29, r30
377 b bat3_r30
378
379 bat3_r31:
380
381 mr r29, r31
382
383 bat3_r30:
384
385 BAT_COMPUTE 0x3000 r29 r28 r27 r26
386 mtspr ibat3u, r26
387 mtspr ibat3l, r27
388
389 mtspr dbat3u, r26
390 mtspr dbat3l, r27
391
392 no_bat:
393
394 # flush TLB
395
396 TLB_FLUSH r31
397
398 # start the kernel
399 #
400 # pc = kernel's entry point (r7)
401 # r3 = bootinfo (physical address)
402 # sprg3 = physical memory size
403 # sp = 0 (enforces the usage of sprg0 as exception stack)
404
405 mtspr srr0, r7
406
407 # Clear sprg0. Kernel will set it.
408 li r31, 0
409 mtsprg0 r31
410
411 # bootinfo starts with a 64 bit integer containing
412 # the physical memory size, get the lower 4 bytes
413
414 // FIXME: unchecked magic offset
415 lwz r31, 4(r3)
416 mtsprg3 r31
417
418 li sp, 0
419
420 mfmsr r31
421 ori r31, r31, (msr_ir | msr_dr)@l
422 mtspr srr1, r31
423
424 sync
425 isync
426 rfi
Note: See TracBrowser for help on using the repository browser.