Remove the need to relocate freeldr. We now use it in-place as stored in
[reactos.git] / reactos / boot / freeldr / bootsect / ofw_util.s
1 .section .text
2
3 .globl ofw_functions_addr
4 ofw_functions_addr:
5 .long ofw_functions
6
7 .align 4
8 call_freeldr:
9 /* Get the address of the functions list --
10 * Note:
11 * Because of little endian switch we must use an even number of
12 * instructions here.. Pad with a nop if needed. */
13 mfmsr %r10
14 ori %r10,%r10,1
15 nop
16 mtmsr %r10
17
18 /* Note that this is little-endian from here on */
19 blr
20 nop
21
22 .align 4
23 call_ofw:
24 /* R3 has the function offset to call (n * 4)
25 * Other arg registers are unchanged.
26 * Note that these 4 instructions are in reverse order due to
27 * little-endian convention */
28 stw %r8,24(%r1)
29 subi %r1,%r1,0x100
30 stw %r8,0(%r1)
31 mflr %r8
32 /* - */
33 stw %r3,4(%r1)
34 stw %r4,8(%r1)
35 stw %r5,12(%r1)
36 stw %r6,16(%r1)
37 /* - */
38 stw %r7,20(%r1)
39 stw %r9,28(%r1)
40 stw %r10,32(%r1)
41 stw %r20,36(%r1)
42
43 /* - */
44 subi %r20,%r20,1
45 mfmsr %r20
46 mtmsr %r20
47 nop
48
49 sync
50 isync
51
52 /* BE MODE */
53 mflr %r8
54 stw %r8,16(%r1)
55
56 lis %r10,0xe00000@ha
57 addi %r8,%r10,ofw_functions_addr@l
58 /* - */
59 lwz %r9,0(%r8)
60 add %r8,%r3,%r9
61 lwz %r9,0(%r8)
62 mtctr %r9
63
64 /* - */
65 mr %r3,%r4
66 mr %r4,%r5
67 mr %r5,%r6
68 mr %r6,%r7
69 /* - */
70 mr %r7,%r8
71 mr %r8,%r9
72
73 /* Call ofw proxy function */
74 bctrl
75 nop
76
77 /* Ok, go back to little endian */
78 mfmsr %r10
79 ori %r10,%r10,1
80 nop
81 mtmsr %r10
82
83 sync
84 isync
85
86 /* LE MODE */
87 mtlr %r8
88 lwz %r8,0(%r1)
89 lwz %r4,8(%r1)
90 lwz %r5,12(%r1)
91 /* - */
92 lwz %r6,16(%r1)
93 lwz %r7,20(%r1)
94 lwz %r8,24(%r1)
95 lwz %r9,28(%r1)
96 /* - */
97 lwz %r10,32(%r1)
98 lwz %r20,36(%r1)
99 /* - */
100 blr
101 addi %r1,%r1,0x100
102
103 prim_strlen:
104 mr %r5,%r3
105 prim_strlen_loop:
106 lbz %r4,0(%r3)
107 cmpi 0,0,%r4,0
108 beq prim_strlen_done
109 addi %r3,%r3,1
110 b prim_strlen_loop
111
112 prim_strlen_done:
113 sub %r3,%r3,%r5
114 blr
115
116 copy_bits:
117 cmp 0,0,%r3,%r4
118 bgelr
119
120 andi. %r6,%r3,0xfff
121 beql ofw_dumpregs
122 mtdec %r3
123
124 lwz %r6,0(%r3)
125 stw %r6,0(%r5)
126 addi %r3,%r3,4
127 addi %r5,%r5,4
128 b copy_bits
129
130 ofw_print_string:
131 /* Reserve some stack space */
132 subi %r1,%r1,32
133
134 /* Save args */
135 stw %r3,0(%r1)
136
137 /* Save the lr, a scratch register */
138 stw %r8,8(%r1)
139 mflr %r8
140 stw %r8,12(%r1)
141
142 /* Load the package name */
143 lis %r3,0xe00000@ha
144 addi %r3,%r3,ofw_chosen_name - _start
145
146 /* Fire */
147 bl ofw_finddevice
148
149 /* Load up for getprop */
150 stw %r3,16(%r1)
151
152 lis %r4,0xe00000@ha
153 addi %r4,%r4,ofw_stdout_name - _start
154
155 addi %r5,%r1,20
156
157 li %r6,4
158
159 bl ofw_getprop
160
161 /* Measure the string and remember the length */
162 lwz %r3,0(%r1)
163 bl prim_strlen
164 mr %r5,%r3
165
166 lwz %r3,20(%r1)
167 lwz %r4,0(%r1)
168
169 /* Write the string */
170 bl ofw_write
171
172 /* Return */
173 lwz %r8,12(%r1)
174 mtlr %r8
175 lwz %r8,8(%r1)
176
177 addi %r1,%r1,32
178 blr
179
180 /* Print 8 hex digits representing a number in r3 */
181 ofw_print_number:
182 subi %r1,%r1,32
183 stw %r8,0(%r1)
184 mflr %r8
185 stw %r8,4(%r1)
186 stw %r9,8(%r1)
187
188 xor %r9,%r9,%r9
189 stw %r9,12(%r1)
190
191 /* Set up and, devide, shift */
192 mr %r8,%r3
193 lis %r6,0xf0000000@ha
194 lis %r7,0x10000000@ha
195 li %r9,8
196
197 ofw_number_loop:
198 nop
199 cmpi 0,0,%r9,0
200 beq ofw_number_return
201 subi %r9,%r9,1
202
203 /* Body: isolate digit, divide, print */
204 and %r5,%r6,%r8
205 divwu %r4,%r5,%r7
206 srwi %r6,%r6,4
207 srwi %r7,%r7,4
208
209 nop
210
211 cmpi 0,0,%r4,10
212 bge ofw_number_letter
213 addi %r4,%r4,'0'
214 b ofw_number_digit_out
215
216 ofw_number_letter:
217 addi %r4,%r4,'A' - 10
218
219 ofw_number_digit_out:
220 stb %r4,12(%r1)
221 addi %r3,%r1,12
222
223 stw %r6,16(%r1)
224 stw %r7,20(%r1)
225 stw %r8,24(%r1)
226 stw %r9,28(%r1)
227
228 bl ofw_print_string
229
230 lwz %r6,16(%r1)
231 lwz %r7,20(%r1)
232 lwz %r8,24(%r1)
233 lwz %r9,28(%r1)
234
235 b ofw_number_loop
236
237 ofw_number_return:
238 /* Return */
239 lwz %r9,8(%r1)
240 lwz %r8,4(%r1)
241 mtlr %r8
242 lwz %r8,0(%r1)
243 addi %r1,%r1,32
244 blr
245
246 ofw_print_eol:
247 subi %r1,%r1,16
248 stw %r8,0(%r1)
249 mflr %r8
250 stw %r8,4(%r1)
251 li %r4,0x0d0a
252 sth %r4,8(%r1)
253 xor %r4,%r4,%r4
254 sth %r4,10(%r1)
255 addi %r3,%r1,8
256 bl ofw_print_string
257 lwz %r8,4(%r1)
258 mtlr %r8
259 lwz %r8,0(%r1)
260 addi %r1,%r1,16
261 blr
262
263 ofw_print_nothing:
264 subi %r1,%r1,16
265 stw %r8,0(%r1)
266 mflr %r8
267 stw %r8,4(%r1)
268 li %r4,0
269 sth %r4,8(%r1)
270 xor %r4,%r4,%r4
271 sth %r4,10(%r1)
272 addi %r3,%r1,8
273 bl ofw_print_string
274 lwz %r8,4(%r1)
275 mtlr %r8
276 lwz %r8,0(%r1)
277 addi %r1,%r1,16
278 blr
279
280 ofw_print_space:
281 subi %r1,%r1,16
282 stw %r8,0(%r1)
283 mflr %r8
284 stw %r8,4(%r1)
285 li %r4,0x2000
286 sth %r4,8(%r1)
287 xor %r4,%r4,%r4
288 sth %r4,10(%r1)
289 addi %r3,%r1,8
290 bl ofw_print_string
291 lwz %r8,4(%r1)
292 mtlr %r8
293 lwz %r8,0(%r1)
294 addi %r1,%r1,16
295 blr
296
297 ofw_dumpregs:
298 /* Construct ofw exit call */
299 subi %r1,%r1,0xa0
300
301 stw %r0,0(%r1)
302 stw %r1,4(%r1)
303 stw %r2,8(%r1)
304 stw %r3,12(%r1)
305
306 stw %r4,16(%r1)
307 stw %r5,20(%r1)
308 stw %r6,24(%r1)
309 stw %r7,28(%r1)
310
311 stw %r8,32(%r1)
312 stw %r9,36(%r1)
313 stw %r10,40(%r1)
314 stw %r11,44(%r1)
315
316 stw %r12,48(%r1)
317 stw %r13,52(%r1)
318 stw %r14,56(%r1)
319 stw %r15,60(%r1)
320
321 stw %r16,64(%r1)
322 stw %r17,68(%r1)
323 stw %r18,72(%r1)
324 stw %r19,76(%r1)
325
326 stw %r20,80(%r1)
327 stw %r21,84(%r1)
328 stw %r22,88(%r1)
329 stw %r23,92(%r1)
330
331 stw %r24,96(%r1)
332 stw %r25,100(%r1)
333 stw %r26,104(%r1)
334 stw %r27,108(%r1)
335
336 stw %r28,112(%r1)
337 stw %r29,116(%r1)
338 stw %r30,120(%r1)
339 stw %r31,124(%r1)
340
341 mflr %r0
342 stw %r0,128(%r1)
343 mfcr %r0
344 stw %r0,132(%r1)
345 mfctr %r0
346 stw %r0,136(%r1)
347 mfmsr %r0
348 stw %r0,140(%r1)
349
350 /* Count at zero */
351 xor %r0,%r0,%r0
352 stw %r0,144(%r1)
353 mr %r3,%r1
354 stw %r3,148(%r1)
355
356 /* Body, print the regname, then the register */
357 ofw_register_loop:
358 lwz %r3,144(%r1)
359 cmpi 0,0,%r3,32
360 beq ofw_register_special
361 lis %r3,0xe00000@ha
362 addi %r3,%r3,freeldr_reg_init - _start
363 bl ofw_print_string
364 lwz %r3,144(%r1)
365 bl ofw_print_number
366 bl ofw_print_space
367 lwz %r3,144(%r1)
368 mulli %r3,%r3,4
369 add %r3,%r1,%r3
370 lwz %r3,0(%r3)
371 stw %r3,152(%r1)
372 bl ofw_print_number
373 lwz %r3,144(%r1)
374 addi %r3,%r3,1
375 stw %r3,144(%r1)
376
377 bl ofw_print_space
378
379 lis %r3,0xe00000@ha
380 addi %r3,%r3,freeldr_reg_init - _start
381 bl ofw_print_string
382 lwz %r3,144(%r1)
383 bl ofw_print_number
384 bl ofw_print_space
385 lwz %r3,144(%r1)
386 mulli %r3,%r3,4
387 add %r3,%r1,%r3
388 lwz %r3,0(%r3)
389 stw %r3,152(%r1)
390 bl ofw_print_number
391 lwz %r3,144(%r1)
392 addi %r3,%r3,1
393 stw %r3,144(%r1)
394
395 b done_dump
396
397 dump_optional:
398 bl ofw_print_space
399 bl ofw_print_space
400 lwz %r3,152(%r1)
401 lwz %r3,0(%r3)
402 bl ofw_print_number
403 bl ofw_print_space
404 lwz %r3,152(%r1)
405 lwz %r3,4(%r3)
406 bl ofw_print_number
407 bl ofw_print_space
408 lwz %r3,152(%r1)
409 lwz %r3,8(%r3)
410 bl ofw_print_number
411 bl ofw_print_space
412 lwz %r3,152(%r1)
413 lwz %r3,12(%r3)
414 bl ofw_print_number
415 bl ofw_print_space
416 done_dump:
417 bl ofw_print_eol
418 b ofw_register_loop
419
420 ofw_register_special:
421 /* LR */
422 lis %r3,0xe00000@ha
423 addi %r3,%r3,freeldr_reg_lr - _start
424 bl ofw_print_string
425 bl ofw_print_space
426 lwz %r3,128(%r1)
427 bl ofw_print_number
428 bl ofw_print_eol
429
430 /* CR */
431 lis %r3,0xe00000@ha
432 addi %r3,%r3,freeldr_reg_cr - _start
433 bl ofw_print_string
434 bl ofw_print_space
435 lwz %r3,132(%r1)
436 bl ofw_print_number
437 bl ofw_print_eol
438
439 /* CTR */
440 lis %r3,0xe00000@ha
441 addi %r3,%r3,freeldr_reg_ctr - _start
442 bl ofw_print_string
443 bl ofw_print_space
444 lwz %r3,136(%r1)
445 bl ofw_print_number
446 bl ofw_print_eol
447
448 /* MSR */
449 lis %r3,0xe00000@ha
450 addi %r3,%r3,freeldr_reg_msr - _start
451 bl ofw_print_string
452 bl ofw_print_space
453 lwz %r3,140(%r1)
454 bl ofw_print_number
455 bl ofw_print_eol
456
457 /* Return */
458 lwz %r0,128(%r1)
459 mtlr %r0
460
461 lwz %r0,0(%r1)
462 lwz %r2,8(%r1)
463 lwz %r3,12(%r1)
464
465 lwz %r4,16(%r1)
466 lwz %r5,20(%r1)
467 lwz %r6,24(%r1)
468 lwz %r7,28(%r1)
469
470 addi %r1,%r1,0xa0
471
472 blr
473
474 ofw_chosen_name:
475 .ascii "/chosen\0"
476
477 ofw_stdout_name:
478 .ascii "stdout\0"
479
480 ofw_memory_name:
481 .ascii "/memory@0\0"
482
483 ofw_reg_name:
484 .ascii "reg\0"
485
486 freeldr_reg_init:
487 .ascii "r\0"
488
489 freeldr_reg_lr:
490 .ascii "lr \0"
491
492 freeldr_reg_cr:
493 .ascii "cr \0"
494
495 freeldr_reg_ctr:
496 .ascii "ctr\0"
497
498 freeldr_reg_msr:
499 .ascii "msr\0"