(c) versus (C)
[helenos.git] / boot / arch / ppc32 / loader / asm.S
bloba1e377989edf6fb5f555a4b2fbf4b77d2b389a41
2 # Copyright (c) 2006 Martin Decky
3 # All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
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.
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.
29 #include "asm.h"
30 #include "regname.h"
31 #include "debug.inc"
33 .text
35 .global halt
36 .global memcpy
37 .global jump_to_kernel
39 halt:
40         b halt
42 memcpy:
43         srwi. r7, r5, 3
44         addi r6, r3, -4
45         addi r4, r4, -4
46         beq     2f
47         
48         andi. r0, r6, 3
49         mtctr r7
50         bne 5f
51         
52         1:
53         
54         lwz r7, 4(r4)
55         lwzu r8, 8(r4)
56         stw r7, 4(r6)
57         stwu r8, 8(r6)
58         bdnz 1b
59         
60         andi. r5, r5, 7
61         
62         2:
63         
64         cmplwi 0, r5, 4
65         blt 3f
66         
67         lwzu r0, 4(r4)
68         addi r5, r5, -4
69         stwu r0, 4(r6)
70         
71         3:
72         
73         cmpwi 0, r5, 0
74         beqlr
75         mtctr r5
76         addi r4, r4, 3
77         addi r6, r6, 3
78         
79         4:
80         
81         lbzu r0, 1(r4)
82         stbu r0, 1(r6)
83         bdnz 4b
84         blr
85         
86         5:
87         
88         subfic r0, r0, 4
89         mtctr r0
90         
91         6:
92         
93         lbz r7, 4(r4)
94         addi r4, r4, 1
95         stb r7, 4(r6)
96         addi r6, r6, 1
97         bdnz 6b
98         subf r5, r0, r5
99         rlwinm. r7, r5, 32-3, 3, 31
100         beq 2b
101         mtctr r7
102         b 1b
105 jump_to_kernel:
106         
107         # r3 = bootinfo (pa)
108         # r4 = bootinfo_size
109         # r5 = trans (pa)
110         # r6 = bytes to copy
111         # r7 = real_mode (pa)
112         # r8 = framebuffer (pa)
113         # r9 = scanline
114         
115         # disable interrupts
116         
117         mfmsr r31
118         rlwinm r31, r31, 0, 17, 15
119         mtmsr r31
120         
121         # set real_mode meeting point address
122         
123         mtspr srr0, r7
124         
125         # jumps to real_mode
126         
127         mfmsr r31
128         lis r30, ~0@h
129         ori r30, r30, ~(msr_ir | msr_dr | msr_ee)@l
130         and r31, r31, r30
131         mtspr srr1, r31
132         
133         sync
134         isync
135         rfi
137 .section REALMODE, "ax"
138 .align PAGE_WIDTH
139 .global real_mode
141 real_mode:
142         
143         DEBUG_INIT
144         DEBUG_real_mode
145         
146         # copy kernel to proper location
147         #
148         # r5 = trans (pa)
149         # r6 = bytes to copy
150         # r8 = framebuffer (pa)
151         # r9 = scanline
152         
153         li r31, PAGE_SIZE >> 2
154         li r30, 0
155         
156         page_copy:
157                 
158                 cmpwi r6, 0
159                 beq copy_end
160                 
161                 # copy page
162                 
163                 mtctr r31
164                 lwz r29, 0(r5)
165                 
166                 DEBUG_INIT
167                 DEBUG_copy_loop
168                 
169                 copy_loop:
170                         
171                         lwz r28, 0(r29)
172                         stw r28, 0(r30)
173                         
174                         addi r29, r29, 4
175                         addi r30, r30, 4
176                         subi r6, r6, 4
177                         
178                         cmpwi r6, 0
179                         beq copy_end
180                         
181                         bdnz copy_loop
182                         
183                         DEBUG_end_copy_loop
184                 
185                 addi r5, r5, 4
186                 b page_copy
187         
188         copy_end:
189         
190         DEBUG_segments
191         
192         # initially fill segment registers
193         
194         li r31, 0
195         
196         li r29, 8
197         mtctr r29
198         li r30, 0                     # ASID 0 (VSIDs 0 .. 7)
200         seg_fill_uspace:
201         
202                 mtsrin r30, r31
203                 addi r30, r30, 1
204                 addis r31, r31, 0x1000    # move to next SR
205                 
206                 bdnz seg_fill_uspace
207         
208         li r29, 8
209         mtctr r29
210         lis r30, 0x4000               # priviledged access only
211         ori r30, r30, 8               # ASID 0 (VSIDs 8 .. 15)
212         
213         seg_fill_kernel:
214         
215                 mtsrin r30, r31
216                 addi r30, r30, 1
217                 addis r31, r31, 0x1000    # move to next SR
218                 
219                 bdnz seg_fill_kernel
220         
221         # invalidate block address translation registers
222         
223         DEBUG_bat
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         DEBUG_pht
255         
256         lwz r31, 0(r3)                # r31 = memory size
257         
258         lis r30, 65536@h
259         ori r30, r30, 65536@l         # r30 = 65536
260         
261         subi r29, r30, 1              # r29 = 65535
262         
263         sub r31, r31, r30
264         andc r31, r31, r29            # pht = ALIGN_DOWN(memory_size - 65536, 65536)
265         
266         mtsdr1 r31
267         
268         li r29, 2
269         srw r30, r30, r29             # r30 = 16384
270         li r29, 0
271         
272         pht_clear:
273                 
274                 # write zeroes
275                 
276                 stw r29, 0(r31)
277                 
278                 addi r31, r31, 4
279                 subi r30, r30, 4
280                 
281                 cmpwi r30, 0
282                 beq clear_end
283                 
284                 bdnz pht_clear
286                 DEBUG_end_pht_clear
287                 
288         clear_end:
289         
290 #ifdef CONFIG_BAT
291         
292         # create BAT identity mapping
293         
294         DEBUG_mapping
295         
296         lwz r31, 0(r3)                # r31 = memory size
297         
298         lis r29, 0x0002
299         cmpw r31, r29
300         blt no_bat                    # less than 128 KB -> no BAT
301         
302         li r29, 18
303         srw r31, r31, r29             # r31 = total >> 18
304         
305         # create Block Length mask by replicating
306         # the leading logical one 14 times
307         
308         li r29, 14
309         mtctr r31
310         li r29, 1
311         
312         bat_mask:
313                 srw r30, r31, r29         # r30 = mask >> 1
314                 or r31, r31, r30          # mask = mask | r30
315                 
316                 bdnz bat_mask
317         
318         DEBUG_bat_mask
319         
320         andi. r31, r31, 0x07ff        # mask = mask & 0x07ff (BAT can map up to 256 MB)
321         
322         li r29, 2
323         slw r31, r31, r29             # mask = mask << 2
324         ori r31, r31, 0x0002          # mask = mask | 0x0002 (priviledged access only)
325         
326         lis r29, 0x8000
327         or r29, r29, r31
328         
329         lis r30, 0x0000
330         ori r30, r30, 0x0002
331         
332         mtspr ibat0u, r29
333         mtspr ibat0l, r30
334         
335         mtspr dbat0u, r29
336         mtspr dbat0l, r30
337         
338         no_bat:
340 #endif
341         
342         DEBUG_tlb
343         
344         tlbia
345         tlbsync
346         
347         DEBUG_prepare
348         
349         # start the kernel
350         #
351         # pc = KERNEL_START_ADDR
352         # r3 = bootinfo (pa)
353         # sprg0 = KA2PA(KERNEL_START_ADDR)
354         # sprg3 = physical memory size
355         # sp = 0 (pa)
356         
357         lis r31, KERNEL_START_ADDR@ha
358         addi r31, r31, KERNEL_START_ADDR@l
359         
360         mtspr srr0, r31
361         
362         subis r31, r31, 0x8000
363         mtsprg0 r31
364         
365         lwz r31, 0(r3)
366         mtsprg3 r31
367         
368         li sp, 0
369         
370         mfmsr r31
371         ori r31, r31, (msr_ir | msr_dr)@l
372         mtspr srr1, r31
373         
374         sync
375         isync
376         
377         DEBUG_rfi
378         rfi
380 .align PAGE_WIDTH
381 .global trans
382 trans:
383         .space (TRANS_SIZE * TRANS_ITEM_SIZE)