source: mainline/boot/arch/ppc32/loader/asm.S@ 14fc1d9

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 14fc1d9 was 7b187ef, checked in by Martin Decky <martin@…>, 17 years ago

ppc32: strict coherency, compatible TLB flush

  • Property mode set to 100644
File size: 7.2 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 "asm.h"
30#include "regname.h"
31
32.macro SMC_COHERENCY addr
33 dcbst 0, \addr
34 sync
35 icbi 0, \addr
36 sync
37 isync
38.endm
39
40.macro FLUSH_DCACHE addr
41 dcbst 0, \addr
42 sync
43 isync
44.endm
45
46.macro TLB_FLUSH reg
47 tlbie \reg
48 addi \reg, \reg, 0x1000
49.endm
50
51.text
52
53.global halt
54.global memcpy
55.global jump_to_kernel
56
57halt:
58 b halt
59
60memcpy:
61 srwi. r7, r5, 3
62 addi r6, r3, -4
63 addi r4, r4, -4
64 beq 2f
65
66 andi. r0, r6, 3
67 mtctr r7
68 bne 5f
69
70 1:
71
72 lwz r7, 4(r4)
73 lwzu r8, 8(r4)
74 stw r7, 4(r6)
75 stwu r8, 8(r6)
76 bdnz 1b
77
78 andi. r5, r5, 7
79
80 2:
81
82 cmplwi 0, r5, 4
83 blt 3f
84
85 lwzu r0, 4(r4)
86 addi r5, r5, -4
87 stwu r0, 4(r6)
88
89 3:
90
91 cmpwi 0, r5, 0
92 beqlr
93 mtctr r5
94 addi r4, r4, 3
95 addi r6, r6, 3
96
97 4:
98
99 lbzu r0, 1(r4)
100 stbu r0, 1(r6)
101 bdnz 4b
102 blr
103
104 5:
105
106 subfic r0, r0, 4
107 mtctr r0
108
109 6:
110
111 lbz r7, 4(r4)
112 addi r4, r4, 1
113 stb r7, 4(r6)
114 addi r6, r6, 1
115 bdnz 6b
116 subf r5, r0, r5
117 rlwinm. r7, r5, 32-3, 3, 31
118 beq 2b
119 mtctr r7
120 b 1b
121
122
123jump_to_kernel:
124
125 # r3 = bootinfo (pa)
126 # r4 = bootinfo_size
127 # r5 = trans (pa)
128 # r6 = bytes to copy
129 # r7 = real_mode (pa)
130 # r8 = framebuffer (pa)
131 # r9 = scanline
132
133 # disable interrupts
134
135 mfmsr r31
136 rlwinm r31, r31, 0, 17, 15
137 mtmsr r31
138
139 # set real_mode meeting point address
140
141 mtspr srr0, r7
142
143 # jumps to real_mode
144
145 mfmsr r31
146 lis r30, ~0@h
147 ori r30, r30, ~(msr_ir | msr_dr | msr_ee)@l
148 and r31, r31, r30
149 mtspr srr1, r31
150
151 sync
152 isync
153 rfi
154
155.section REALMODE, "ax"
156.align PAGE_WIDTH
157.global real_mode
158
159real_mode:
160
161 # copy kernel to proper location
162 #
163 # r5 = trans (pa)
164 # r6 = bytes to copy
165 # r8 = framebuffer (pa)
166 # r9 = scanline
167
168 li r31, PAGE_SIZE >> 2
169 li r30, 0
170
171 page_copy:
172
173 cmpwi r6, 0
174 beq copy_end
175
176 # copy page
177
178 mtctr r31
179 lwz r29, 0(r5)
180
181 copy_loop:
182
183 lwz r28, 0(r29)
184 stw r28, 0(r30)
185
186 SMC_COHERENCY r30
187
188 addi r29, r29, 4
189 addi r30, r30, 4
190 subi r6, r6, 4
191
192 cmpwi r6, 0
193 beq copy_end
194
195 bdnz copy_loop
196
197 addi r5, r5, 4
198 b page_copy
199
200 copy_end:
201
202 # initially fill segment registers
203
204 li r31, 0
205
206 li r29, 8
207 mtctr r29
208 li r30, 0 # ASID 0 (VSIDs 0 .. 7)
209
210 seg_fill_uspace:
211
212 mtsrin r30, r31
213 addi r30, r30, 1
214 addis r31, r31, 0x1000 # move to next SR
215
216 bdnz seg_fill_uspace
217
218 li r29, 8
219 mtctr r29
220 lis r30, 0x4000 # priviledged access only
221 ori r30, r30, 8 # ASID 0 (VSIDs 8 .. 15)
222
223 seg_fill_kernel:
224
225 mtsrin r30, r31
226 addi r30, r30, 1
227 addis r31, r31, 0x1000 # move to next SR
228
229 bdnz seg_fill_kernel
230
231 # invalidate block address translation registers
232
233 li r30, 0
234
235 mtspr ibat0u, r30
236 mtspr ibat0l, r30
237
238 mtspr ibat1u, r30
239 mtspr ibat1l, r30
240
241 mtspr ibat2u, r30
242 mtspr ibat2l, r30
243
244 mtspr ibat3u, r30
245 mtspr ibat3l, r30
246
247 mtspr dbat0u, r30
248 mtspr dbat0l, r30
249
250 mtspr dbat1u, r30
251 mtspr dbat1l, r30
252
253 mtspr dbat2u, r30
254 mtspr dbat2l, r30
255
256 mtspr dbat3u, r30
257 mtspr dbat3l, r30
258
259 # create empty Page Hash Table
260 # on top of memory, size 64 KB
261
262 lwz r31, 0(r3) # r31 = memory size
263
264 lis r30, 65536@h
265 ori r30, r30, 65536@l # r30 = 65536
266
267 subi r29, r30, 1 # r29 = 65535
268
269 sub r31, r31, r30
270 andc r31, r31, r29 # pht = ALIGN_DOWN(memory_size - 65536, 65536)
271
272 mtsdr1 r31
273
274 li r29, 2
275 srw r30, r30, r29 # r30 = 16384
276 li r29, 0
277
278 pht_clear:
279
280 # write zeroes
281
282 stw r29, 0(r31)
283 FLUSH_DCACHE r31
284
285 addi r31, r31, 4
286 subi r30, r30, 4
287
288 cmpwi r30, 0
289 beq clear_end
290
291 bdnz pht_clear
292
293 clear_end:
294
295#ifdef CONFIG_BAT
296
297 # create BAT identity mapping
298
299 lwz r31, 0(r3) # r31 = memory size
300
301 lis r29, 0x0002
302 cmpw r31, r29
303 blt no_bat # less than 128 KB -> no BAT
304
305 li r29, 18
306 srw r31, r31, r29 # r31 = total >> 18
307
308 # create Block Length mask by replicating
309 # the leading logical one 14 times
310
311 li r29, 14
312 mtctr r31
313 li r29, 1
314
315 bat_mask:
316 srw r30, r31, r29 # r30 = mask >> 1
317 or r31, r31, r30 # mask = mask | r30
318
319 bdnz bat_mask
320
321 andi. r31, r31, 0x07ff # mask = mask & 0x07ff (BAT can map up to 256 MB)
322
323 li r29, 2
324 slw r31, r31, r29 # mask = mask << 2
325 ori r31, r31, 0x0002 # mask = mask | 0x0002 (priviledged access only)
326
327 lis r29, 0x8000
328 or r29, r29, r31
329
330 lis r30, 0x0000
331 ori r30, r30, 0x0002
332
333 mtspr ibat0u, r29
334 mtspr ibat0l, r30
335
336 mtspr dbat0u, r29
337 mtspr dbat0l, r30
338
339 no_bat:
340
341#endif
342
343 # flush TLB
344
345 li r31, 0
346 sync
347
348 TLB_FLUSH r31
349 TLB_FLUSH r31
350 TLB_FLUSH r31
351 TLB_FLUSH r31
352 TLB_FLUSH r31
353 TLB_FLUSH r31
354 TLB_FLUSH r31
355 TLB_FLUSH r31
356
357 TLB_FLUSH r31
358 TLB_FLUSH r31
359 TLB_FLUSH r31
360 TLB_FLUSH r31
361 TLB_FLUSH r31
362 TLB_FLUSH r31
363 TLB_FLUSH r31
364 TLB_FLUSH r31
365
366 TLB_FLUSH r31
367 TLB_FLUSH r31
368 TLB_FLUSH r31
369 TLB_FLUSH r31
370 TLB_FLUSH r31
371 TLB_FLUSH r31
372 TLB_FLUSH r31
373 TLB_FLUSH r31
374
375 TLB_FLUSH r31
376 TLB_FLUSH r31
377 TLB_FLUSH r31
378 TLB_FLUSH r31
379 TLB_FLUSH r31
380 TLB_FLUSH r31
381 TLB_FLUSH r31
382 TLB_FLUSH r31
383
384 TLB_FLUSH r31
385 TLB_FLUSH r31
386 TLB_FLUSH r31
387 TLB_FLUSH r31
388 TLB_FLUSH r31
389 TLB_FLUSH r31
390 TLB_FLUSH r31
391 TLB_FLUSH r31
392
393 TLB_FLUSH r31
394 TLB_FLUSH r31
395 TLB_FLUSH r31
396 TLB_FLUSH r31
397 TLB_FLUSH r31
398 TLB_FLUSH r31
399 TLB_FLUSH r31
400 TLB_FLUSH r31
401
402 TLB_FLUSH r31
403 TLB_FLUSH r31
404 TLB_FLUSH r31
405 TLB_FLUSH r31
406 TLB_FLUSH r31
407 TLB_FLUSH r31
408 TLB_FLUSH r31
409 TLB_FLUSH r31
410
411 TLB_FLUSH r31
412 TLB_FLUSH r31
413 TLB_FLUSH r31
414 TLB_FLUSH r31
415 TLB_FLUSH r31
416 TLB_FLUSH r31
417 TLB_FLUSH r31
418 TLB_FLUSH r31
419
420 eieio
421 tlbsync
422 sync
423
424 # start the kernel
425 #
426 # pc = KERNEL_START_ADDR
427 # r3 = bootinfo (pa)
428 # sprg0 = KA2PA(KERNEL_START_ADDR)
429 # sprg3 = physical memory size
430 # sp = 0 (pa)
431
432 lis r31, KERNEL_START_ADDR@ha
433 addi r31, r31, KERNEL_START_ADDR@l
434
435 mtspr srr0, r31
436
437 subis r31, r31, 0x8000
438 mtsprg0 r31
439
440 lwz r31, 0(r3)
441 mtsprg3 r31
442
443 li sp, 0
444
445 mfmsr r31
446 ori r31, r31, (msr_ir | msr_dr)@l
447 mtspr srr1, r31
448
449 sync
450 isync
451 rfi
452
453.align PAGE_WIDTH
454.global trans
455trans:
456 .space (TRANS_SIZE * TRANS_ITEM_SIZE)
Note: See TracBrowser for help on using the repository browser.