Fix a couple of problems with FreeLDR portability.
[reactos.git] / reactos / boot / freeldr / bootsect / ofwboot.s
1 .section .text
2 .globl setup_bats
3
4 _start:
5 .long 0xe00000 + 12
6 .long 0
7 .long 0
8
9 _begin:
10 sync
11 isync
12
13 lis %r1,stack@ha
14 addi %r1,%r1,stack@l
15 addi %r1,%r1,16384 - 0x10
16
17 mfmsr %r8
18 li %r0,0
19 mtmsr %r0
20 isync
21
22 bl setup_bats
23
24 li %r8,0x3030
25 mtmsr %r8
26
27 /* Store ofw call addr */
28 mr %r21,%r5
29 lis %r10,0xe00000@ha
30 stw %r5,ofw_call_addr - _start@l(%r10)
31
32 lis %r4,_binary_freeldr_tmp_end@ha
33 addi %r4,%r4,_binary_freeldr_tmp_end@l
34 lis %r3,_binary_freeldr_tmp_start@ha
35 addi %r3,%r3,_binary_freeldr_tmp_start@l
36
37 lis %r5,0x8000@ha
38 addi %r5,%r5,0x8000@l
39
40 bl copy_bits
41
42 bl zero_registers
43
44 lis %r3,0xe00000@ha
45 addi %r3,%r3,freeldr_banner - _start
46
47 bl ofw_print_string
48
49 bl ofw_print_eol
50
51 bl setup_exc
52
53 /* Zero CTR */
54 mtcr %r31
55
56 lis %r3,0x8000@ha
57 addi %r3,%r3,0x8000@l
58
59 mtlr %r3
60
61 lis %r3,call_ofw@ha
62 addi %r3,%r3,call_ofw - _start
63
64 b call_freeldr
65
66 /*
67 * lifted from ppc/boot/openfirmware/misc.S
68 * Copyright (C) Paul Mackerras 1997.
69 *
70 * This program is free software; you can redistribute it and/or
71 * modify it under the terms of the GNU General Public License
72 * as published by the Free Software Foundation ; either version
73 * 2 of the License, or (at your option) any later version.
74 */
75
76 /*
77 * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to
78 * the address given as the 1st argument.
79 */
80 setup_bats:
81 mfpvr 5
82 rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */
83 cmpwi 0,5,1
84 li 0,0
85 bne 4f
86 mtibatl 3,0 /* invalidate BAT first */
87 ori 3,3,4 /* set up BAT registers for 601 */
88 li 4,0x7f
89 mtibatu 2,3
90 mtibatl 2,4
91 oris 3,3,0x80
92 oris 4,4,0x80
93 mtibatu 3,3
94 mtibatl 3,4
95 b 5f
96 4: mtdbatu 3,0 /* invalidate BATs first */
97 mtibatu 3,0
98 ori 3,3,0xff /* set up BAT registers for 604 */
99 li 4,2
100 mtdbatl 2,4
101 mtdbatu 2,3
102 mtibatl 2,4
103 mtibatu 2,3
104 oris 3,3,0x80
105 oris 4,4,0x80
106 mtdbatl 3,4
107 mtdbatu 3,3
108 mtibatl 3,4
109 mtibatu 3,3
110 5: sync
111 isync
112 blr
113
114 .align 4
115 call_freeldr:
116 /* Get the address of the functions list --
117 * Note:
118 * Because of little endian switch we must use an even number of
119 * instructions here.. Pad with a nop if needed. */
120 mfmsr %r10
121 ori %r10,%r10,1
122 mtmsr %r10
123
124 nop
125
126 /* Note that this is little-endian from here on */
127 blr
128 nop
129
130 .align 4
131 call_ofw:
132 /* R3 has the function offset to call (n * 4)
133 * Other arg registers are unchanged.
134 * Note that these 4 instructions are in reverse order due to
135 * little-endian convention */
136 andi. %r0,%r0,65534
137 mfmsr %r0
138 mtmsr %r0
139 /* Now normal ordering resumes */
140 subi %r1,%r1,0x100
141
142 stw %r8,4(%r1)
143 stw %r9,8(%r1)
144 stw %r10,12(%r1)
145 mflr %r8
146 stw %r8,16(%r1)
147
148 lis %r10,0xe00000@ha
149 add %r9,%r3,%r10
150 lwz %r3,ofw_functions - _start@l(%r9)
151 mtctr %r3
152
153 mr %r3,%r4
154 mr %r4,%r5
155 mr %r5,%r6
156 mr %r6,%r7
157 mr %r7,%r8
158
159 /* Goto the swapped function */
160 bctrl
161
162 lwz %r8,16(%r1)
163 mtlr %r8
164
165 lwz %r8,4(%r1)
166 lwz %r9,8(%r1)
167 lwz %r10,12(%r1)
168
169 addi %r1,%r1,0x100
170 /* Ok, go back to little endian */
171 mfmsr %r0
172 ori %r0,%r0,1
173 mtmsr %r0
174
175 /* Note that this is little-endian from here on */
176 blr
177 nop
178
179 zero_registers:
180 xor %r2,%r2,%r2
181 mr %r0,%r2
182 mr %r3,%r2
183
184 mr %r4,%r2
185 mr %r5,%r2
186 mr %r6,%r2
187 mr %r7,%r2
188
189 mr %r8,%r2
190 mr %r9,%r2
191 mr %r10,%r2
192 mr %r11,%r2
193
194 mr %r12,%r2
195 mr %r13,%r2
196 mr %r14,%r2
197 mr %r15,%r2
198
199 mr %r12,%r2
200 mr %r13,%r2
201 mr %r14,%r2
202 mr %r15,%r2
203
204 mr %r16,%r2
205 mr %r17,%r2
206 mr %r18,%r2
207 mr %r19,%r2
208
209 mr %r20,%r2
210 mr %r21,%r2
211 mr %r22,%r2
212 mr %r23,%r2
213
214 mr %r24,%r2
215 mr %r25,%r2
216 mr %r26,%r2
217 mr %r27,%r2
218
219 mr %r28,%r2
220 mr %r29,%r2
221 mr %r30,%r2
222 mr %r31,%r2
223
224 blr
225
226 prim_strlen:
227 mr %r5,%r3
228 prim_strlen_loop:
229 lbz %r4,0(%r3)
230 cmpi 0,0,%r4,0
231 beq prim_strlen_done
232 addi %r3,%r3,1
233 b prim_strlen_loop
234
235 prim_strlen_done:
236 sub %r3,%r3,%r5
237 blr
238
239 copy_bits:
240 cmp 0,0,%r3,%r4
241 beqlr
242 lwz %r6,0(%r3)
243 stw %r6,0(%r5)
244 addi %r3,%r3,4
245 addi %r5,%r5,4
246 b copy_bits
247
248 ofw_print_string_hook:
249 bl ofw_print_number
250 bl ofw_exit
251
252 ofw_print_string:
253 /* Reserve some stack space */
254 subi %r1,%r1,32
255
256 /* Save args */
257 stw %r3,0(%r1)
258
259 /* Save the lr, a scratch register */
260 stw %r8,8(%r1)
261 mflr %r8
262 stw %r8,12(%r1)
263
264 /* Load the package name */
265 lis %r3,0xe00000@ha
266 addi %r3,%r3,ofw_chosen_name - _start
267
268 /* Fire */
269 bl ofw_finddevice
270
271 /* Load up for getprop */
272 stw %r3,16(%r1)
273
274 lis %r4,0xe00000@ha
275 addi %r4,%r4,ofw_stdout_name - _start
276
277 addi %r5,%r1,20
278
279 li %r6,4
280
281 bl ofw_getprop
282
283 /* Measure the string and remember the length */
284 lwz %r3,0(%r1)
285 bl prim_strlen
286 mr %r5,%r3
287
288 lwz %r3,20(%r1)
289 lwz %r4,0(%r1)
290
291 /* Write the string */
292 bl ofw_write
293
294 /* Return */
295 lwz %r8,12(%r1)
296 mtlr %r8
297 lwz %r8,8(%r1)
298
299 addi %r1,%r1,32
300 blr
301
302 /* Print 8 hex digits representing a number in r3 */
303 ofw_print_number:
304 subi %r1,%r1,32
305 stw %r8,0(%r1)
306 mflr %r8
307 stw %r8,4(%r1)
308 stw %r9,8(%r1)
309
310 xor %r9,%r9,%r9
311 stw %r9,12(%r1)
312
313 /* Set up and, devide, shift */
314 mr %r8,%r3
315 lis %r6,0xf0000000@ha
316 lis %r7,0x10000000@ha
317 li %r9,8
318
319 ofw_number_loop:
320 nop
321 cmpi 0,0,%r9,0
322 beq ofw_number_return
323 subi %r9,%r9,1
324
325 /* Body: isolate digit, divide, print */
326 and %r5,%r6,%r8
327 divwu %r4,%r5,%r7
328 srwi %r6,%r6,4
329 srwi %r7,%r7,4
330
331 nop
332
333 cmpi 0,0,%r4,10
334 bge ofw_number_letter
335 addi %r4,%r4,'0'
336 b ofw_number_digit_out
337
338 ofw_number_letter:
339 addi %r4,%r4,'A' - 10
340
341 ofw_number_digit_out:
342 stb %r4,12(%r1)
343 addi %r3,%r1,12
344
345 stw %r6,16(%r1)
346 stw %r7,20(%r1)
347 stw %r8,24(%r1)
348 stw %r9,28(%r1)
349
350 bl ofw_print_string
351
352 lwz %r6,16(%r1)
353 lwz %r7,20(%r1)
354 lwz %r8,24(%r1)
355 lwz %r9,28(%r1)
356
357 b ofw_number_loop
358
359 ofw_number_return:
360 /* Return */
361 lwz %r9,8(%r1)
362 lwz %r8,4(%r1)
363 mtlr %r8
364 lwz %r8,0(%r1)
365 addi %r1,%r1,32
366 blr
367
368 ofw_print_eol:
369 subi %r1,%r1,16
370 stw %r8,0(%r1)
371 mflr %r8
372 stw %r8,4(%r1)
373 li %r4,0x0d0a
374 sth %r4,8(%r1)
375 xor %r4,%r4,%r4
376 sth %r4,10(%r1)
377 addi %r3,%r1,8
378 bl ofw_print_string
379 lwz %r8,4(%r1)
380 mtlr %r8
381 lwz %r8,0(%r1)
382 addi %r1,%r1,16
383 blr
384
385 ofw_print_nothing:
386 subi %r1,%r1,16
387 stw %r8,0(%r1)
388 mflr %r8
389 stw %r8,4(%r1)
390 li %r4,0
391 sth %r4,8(%r1)
392 xor %r4,%r4,%r4
393 sth %r4,10(%r1)
394 addi %r3,%r1,8
395 bl ofw_print_string
396 lwz %r8,4(%r1)
397 mtlr %r8
398 lwz %r8,0(%r1)
399 addi %r1,%r1,16
400 blr
401
402 ofw_print_space:
403 subi %r1,%r1,16
404 stw %r8,0(%r1)
405 mflr %r8
406 stw %r8,4(%r1)
407 li %r4,0x2000
408 sth %r4,8(%r1)
409 xor %r4,%r4,%r4
410 sth %r4,10(%r1)
411 addi %r3,%r1,8
412 bl ofw_print_string
413 lwz %r8,4(%r1)
414 mtlr %r8
415 lwz %r8,0(%r1)
416 addi %r1,%r1,16
417 blr
418
419 ofw_print_regs:
420 /* Construct ofw exit call */
421 subi %r1,%r1,0xa0
422
423 stw %r0,0(%r1)
424 stw %r1,4(%r1)
425 stw %r2,8(%r1)
426 stw %r3,12(%r1)
427
428 stw %r4,16(%r1)
429 stw %r5,20(%r1)
430 stw %r6,24(%r1)
431 stw %r7,28(%r1)
432
433 stw %r8,32(%r1)
434 stw %r9,36(%r1)
435 stw %r10,40(%r1)
436 stw %r11,44(%r1)
437
438 stw %r12,48(%r1)
439 stw %r13,52(%r1)
440 stw %r14,56(%r1)
441 stw %r15,60(%r1)
442
443 stw %r16,64(%r1)
444 stw %r17,68(%r1)
445 stw %r18,72(%r1)
446 stw %r19,76(%r1)
447
448 stw %r20,80(%r1)
449 stw %r21,84(%r1)
450 stw %r22,88(%r1)
451 stw %r23,92(%r1)
452
453 stw %r24,96(%r1)
454 stw %r25,100(%r1)
455 stw %r26,104(%r1)
456 stw %r27,108(%r1)
457
458 stw %r28,112(%r1)
459 stw %r29,116(%r1)
460 stw %r30,120(%r1)
461 stw %r31,124(%r1)
462
463 mflr %r0
464 stw %r0,128(%r1)
465 mfcr %r0
466 stw %r0,132(%r1)
467 mfctr %r0
468 stw %r0,136(%r1)
469 mfmsr %r0
470 stw %r0,140(%r1)
471
472 /* Count at zero */
473 xor %r0,%r0,%r0
474 stw %r0,144(%r1)
475 mr %r3,%r1
476 stw %r3,148(%r1)
477
478 /* Body, print the regname, then the register */
479 ofw_register_loop:
480 lwz %r3,144(%r1)
481 cmpi 0,0,%r3,32
482 beq ofw_register_special
483 lis %r3,0xe00000@ha
484 addi %r3,%r3,freeldr_reg_init - _start
485 bl ofw_print_string
486 lwz %r3,144(%r1)
487 bl ofw_print_number
488 bl ofw_print_space
489 lwz %r3,144(%r1)
490 mulli %r3,%r3,4
491 add %r3,%r1,%r3
492 lwz %r3,0(%r3)
493 stw %r3,152(%r1)
494 bl ofw_print_number
495 lwz %r3,144(%r1)
496 addi %r3,%r3,1
497 stw %r3,144(%r1)
498 b done_dump
499
500 dump_optional:
501 bl ofw_print_space
502 bl ofw_print_space
503 lwz %r3,152(%r1)
504 lwz %r3,0(%r3)
505 bl ofw_print_number
506 bl ofw_print_space
507 lwz %r3,152(%r1)
508 lwz %r3,4(%r3)
509 bl ofw_print_number
510 bl ofw_print_space
511 lwz %r3,152(%r1)
512 lwz %r3,8(%r3)
513 bl ofw_print_number
514 bl ofw_print_space
515 lwz %r3,152(%r1)
516 lwz %r3,12(%r3)
517 bl ofw_print_number
518 bl ofw_print_space
519 done_dump:
520 bl ofw_print_eol
521 b ofw_register_loop
522
523 ofw_register_special:
524 /* LR */
525 lis %r3,0xe00000@ha
526 addi %r3,%r3,freeldr_reg_lr - _start
527 bl ofw_print_string
528 bl ofw_print_space
529 lwz %r3,128(%r1)
530 bl ofw_print_number
531 bl ofw_print_eol
532
533 /* CR */
534 lis %r3,0xe00000@ha
535 addi %r3,%r3,freeldr_reg_cr - _start
536 bl ofw_print_string
537 bl ofw_print_space
538 lwz %r3,132(%r1)
539 bl ofw_print_number
540 bl ofw_print_eol
541
542 /* CTR */
543 lis %r3,0xe00000@ha
544 addi %r3,%r3,freeldr_reg_ctr - _start
545 bl ofw_print_string
546 bl ofw_print_space
547 lwz %r3,136(%r1)
548 bl ofw_print_number
549 bl ofw_print_eol
550
551 /* MSR */
552 lis %r3,0xe00000@ha
553 addi %r3,%r3,freeldr_reg_msr - _start
554 bl ofw_print_string
555 bl ofw_print_space
556 lwz %r3,140(%r1)
557 bl ofw_print_number
558 bl ofw_print_eol
559
560 /* Return */
561 lwz %r0,128(%r1)
562 mtlr %r0
563
564 lwz %r0,0(%r1)
565 lwz %r2,8(%r1)
566 lwz %r3,12(%r1)
567
568 lwz %r4,16(%r1)
569 lwz %r5,20(%r1)
570 lwz %r6,24(%r1)
571 lwz %r7,28(%r1)
572
573 addi %r1,%r1,0xa0
574
575 blr
576
577 ofw_finddevice_hook:
578 subi %r1,%r1,32
579 stw %r3,0(%r1)
580 mflr %r3
581 stw %r3,4(%r1)
582 lwz %r3,0(%r1)
583 bl ofw_finddevice
584 stw %r3,0(%r1)
585 lwz %r3,4(%r1)
586 mtlr %r3
587 lwz %r3,0(%r1)
588 addi %r1,%r1,32
589 blr
590
591 ofw_finddevice:
592 /* Reserve stack space ...
593 * 20 bytes for the ofw call,
594 * r8, r9, and lr */
595 subi %r1,%r1,32
596
597 /* Store r8, r9, lr */
598 stw %r8,20(%r1)
599 stw %r9,24(%r1)
600 mflr %r8
601 stw %r8,28(%r1)
602
603 /* Get finddevice name */
604 lis %r8,0xe00000@ha
605 addi %r9,%r8,ofw_finddevice_name - _start
606 stw %r9,0(%r1)
607
608 /* 1 Argument and 1 return */
609 li %r9,1
610 stw %r9,4(%r1)
611 stw %r9,8(%r1)
612
613 stw %r3,12(%r1)
614
615 /* Load up the call address */
616 lwz %r9,ofw_call_addr - _start(%r8)
617 mtlr %r9
618
619 /* Set argument */
620 mr %r3,%r1
621
622 /* Fire */
623 blrl
624
625 lwz %r3,16(%r1)
626
627 /* Restore registers */
628 lwz %r8,28(%r1)
629 mtlr %r8
630 lwz %r9,24(%r1)
631 lwz %r8,20(%r1)
632
633 addi %r1,%r1,32
634
635 /* Return */
636 blr
637
638 ofw_open:
639 /* Reserve stack space ...
640 * 20 bytes for the ofw call,
641 * r8, r9, and lr */
642 subi %r1,%r1,32
643
644 /* Store r8, r9, lr */
645 stw %r8,20(%r1)
646 stw %r9,24(%r1)
647 mflr %r8
648 stw %r8,28(%r1)
649
650 /* Get open name */
651 lis %r8,0xe00000@ha
652 addi %r9,%r8,ofw_open_name - _start
653 stw %r9,0(%r1)
654
655 /* 1 Argument and 1 return */
656 li %r9,1
657 stw %r9,4(%r1)
658 stw %r9,8(%r1)
659
660 stw %r3,12(%r1)
661
662 /* Load up the call address */
663 lwz %r9,ofw_call_addr - _start(%r8)
664 mtlr %r9
665
666 /* Set argument */
667 mr %r3,%r1
668
669 /* Fire */
670 blrl
671
672 lwz %r3,16(%r1)
673
674 /* Restore registers */
675 lwz %r8,28(%r1)
676 mtlr %r8
677 lwz %r9,24(%r1)
678 lwz %r8,20(%r1)
679
680 addi %r1,%r1,32
681
682 /* Return */
683 blr
684
685 ofw_getprop_hook:
686 /* Reserve stack space:
687 * 32 bytes for the ofw call
688 * 12 bytes for r8, r9, lr
689 */
690 /* Reserve stack space ...
691 * 20 bytes for the ofw call,
692 * r8, r9, and lr */
693 subi %r1,%r1,48
694
695 /* Store r8, r9, lr */
696 stw %r8,32(%r1)
697 stw %r9,36(%r1)
698 mflr %r8
699 stw %r8,40(%r1)
700
701 /* Get getprop name */
702 lis %r8,0xe00000@ha
703 addi %r9,%r8,ofw_getprop_name - _start
704 stw %r9,0(%r1)
705
706 /* 4 Argument and 1 return */
707 li %r9,4
708 stw %r9,4(%r1)
709 li %r9,1
710 stw %r9,8(%r1)
711
712 stw %r3,12(%r1) /* Package */
713 stw %r4,16(%r1) /* Property */
714 stw %r5,20(%r1) /* Return buffer */
715 stw %r6,24(%r1) /* Buffer size */
716
717 /* Load up the call address */
718 lwz %r9,ofw_call_addr - _start(%r8)
719 mtlr %r9
720
721 /* Set argument */
722 mr %r3,%r1
723
724 /* Fire */
725 blrl
726
727 /* Workaround to a wierd crash ... not sure what causes it.
728 * XXX investigate me */
729 bl ofw_print_nothing
730
731 /* Return */
732 lwz %r3,28(%r1)
733
734 /* Restore registers */
735 lwz %r8,40(%r1)
736 mtlr %r8
737 lwz %r9,36(%r1)
738 lwz %r8,32(%r1)
739
740 addi %r1,%r1,48
741
742 /* Return */
743 blr
744
745 ofw_getprop:
746 /* Reserve stack space:
747 * 32 bytes for the ofw call
748 * 12 bytes for r8, r9, lr
749 */
750 /* Reserve stack space ...
751 * 20 bytes for the ofw call,
752 * r8, r9, and lr */
753 subi %r1,%r1,48
754
755 /* Store r8, r9, lr */
756 stw %r8,32(%r1)
757 stw %r9,36(%r1)
758 mflr %r8
759 stw %r8,40(%r1)
760
761 /* Get getprop name */
762 lis %r8,0xe00000@ha
763 addi %r9,%r8,ofw_getprop_name - _start
764 stw %r9,0(%r1)
765
766 /* 4 Argument and 1 return */
767 li %r9,4
768 stw %r9,4(%r1)
769 li %r9,1
770 stw %r9,8(%r1)
771
772 stw %r3,12(%r1) /* Package */
773 stw %r4,16(%r1) /* Property */
774 stw %r5,20(%r1) /* Return buffer */
775 stw %r6,24(%r1) /* Buffer size */
776
777 /* Load up the call address */
778 lwz %r9,ofw_call_addr - _start(%r8)
779 mtlr %r9
780
781 /* Set argument */
782 mr %r3,%r1
783
784 /* Fire */
785 blrl
786
787 /* Return */
788 lwz %r3,28(%r1)
789
790 /* Restore registers */
791 lwz %r8,40(%r1)
792
793 mtlr %r8
794 lwz %r9,36(%r1)
795 lwz %r8,32(%r1)
796
797 addi %r1,%r1,48
798
799 /* Return */
800 blr
801
802 ofw_write:
803 /* Reserve stack space:
804 * 28 bytes for the ofw call
805 * 12 bytes for r8, r9, lr
806 */
807 /* Reserve stack space ...
808 * 20 bytes for the ofw call,
809 * r8, r9, and lr */
810 subi %r1,%r1,48
811
812 nop
813
814 /* Store r8, r9, lr */
815 stw %r8,28(%r1)
816 stw %r9,32(%r1)
817 mflr %r8
818 stw %r8,36(%r1)
819
820 /* Get write name */
821 lis %r8,0xe00000@ha
822 addi %r9,%r8,ofw_write_name - _start
823 stw %r9,0(%r1)
824
825 /* 3 Arguments and 1 return */
826 li %r9,3
827 stw %r9,4(%r1)
828 li %r9,1
829 stw %r9,8(%r1)
830
831 stw %r3,12(%r1)
832 stw %r4,16(%r1)
833 stw %r5,20(%r1)
834
835 /* Load up the call address */
836 lwz %r9,ofw_call_addr - _start(%r8)
837 mtlr %r9
838
839 /* Set argument */
840 mr %r3,%r1
841
842 /* Fire */
843 blrl
844
845 /* Return */
846 lwz %r3,24(%r1)
847
848 /* Restore registers */
849 lwz %r8,36(%r1)
850 mtlr %r8
851 lwz %r9,32(%r1)
852 lwz %r8,28(%r1)
853
854 addi %r1,%r1,48
855
856 /* Return */
857 blr
858
859 ofw_read:
860 /* Reserve stack space:
861 * 28 bytes for the ofw call
862 * 12 bytes for r8, r9, lr
863 */
864 /* Reserve stack space ...
865 * 20 bytes for the ofw call,
866 * r8, r9, and lr */
867 subi %r1,%r1,48
868
869 nop
870
871 /* Store r8, r9, lr */
872 stw %r8,28(%r1)
873 stw %r9,32(%r1)
874 mflr %r8
875 stw %r8,36(%r1)
876
877 /* Get read name */
878 lis %r8,0xe00000@ha
879 addi %r9,%r8,ofw_read_name - _start
880 stw %r9,0(%r1)
881
882 /* 3 Arguments and 1 return */
883 li %r9,3
884 stw %r9,4(%r1)
885 li %r9,1
886 stw %r9,8(%r1)
887
888 stw %r3,12(%r1)
889 stw %r4,16(%r1)
890 stw %r5,20(%r1)
891
892 /* Load up the call address */
893 lwz %r9,ofw_call_addr - _start(%r8)
894 mtlr %r9
895
896 /* Set argument */
897 mr %r3,%r1
898
899 /* Fire */
900 blrl
901
902 /* Return */
903 lwz %r3,24(%r1)
904
905 /* Restore registers */
906 lwz %r8,36(%r1)
907 mtlr %r8
908 lwz %r9,32(%r1)
909 lwz %r8,28(%r1)
910
911 addi %r1,%r1,48
912
913 /* Return */
914 blr
915
916 ofw_exit:
917 lis %r3,0xe00000@ha
918 addi %r3,%r3,freeldr_halt - _start
919
920 bl ofw_print_string
921 /*
922 ofw_exit_loop:
923 b ofw_exit_loop
924 */
925 /* Load the exit name */
926 lis %r8,0xe00000@ha
927 addi %r9,%r8,ofw_exit_name - _start
928 stw %r9,0(%r1)
929
930 /* Zero args, zero returns */
931 xor %r9,%r9,%r9
932 stw %r9,4(%r1)
933 stw %r9,8(%r1)
934
935 /* Load up the call address */
936 lwz %r9,ofw_call_addr - _start(%r8)
937 mtlr %r9
938
939 mr %r3,%r1
940
941 /* Fire */
942 blrl
943 /* No return from exit */
944
945 ofw_child:
946 /* Reserve stack space ...
947 * 20 bytes for the ofw call,
948 * r8, r9, and lr */
949 subi %r1,%r1,32
950
951 /* Store r8, r9, lr */
952 stw %r8,20(%r1)
953 stw %r9,24(%r1)
954 mflr %r8
955 stw %r8,28(%r1)
956
957 /* Get child name */
958 lis %r8,0xe00000@ha
959 addi %r9,%r8,ofw_child_name - _start
960 stw %r9,0(%r1)
961
962 /* 1 Argument and 1 return */
963 li %r9,1
964 stw %r9,4(%r1)
965 stw %r9,8(%r1)
966
967 stw %r3,12(%r1)
968
969 /* Load up the call address */
970 lwz %r9,ofw_call_addr - _start(%r8)
971 mtlr %r9
972
973 /* Set argument */
974 mr %r3,%r1
975
976 /* Fire */
977 blrl
978
979 lwz %r3,16(%r1)
980
981 /* Restore registers */
982 lwz %r8,28(%r1)
983 mtlr %r8
984 lwz %r9,24(%r1)
985 lwz %r8,20(%r1)
986
987 addi %r1,%r1,32
988
989 /* Return */
990 blr
991
992 ofw_peer:
993 /* Reserve stack space ...
994 * 20 bytes for the ofw call,
995 * r8, r9, and lr */
996 subi %r1,%r1,32
997
998 /* Store r8, r9, lr */
999 stw %r8,20(%r1)
1000 stw %r9,24(%r1)
1001 mflr %r8
1002 stw %r8,28(%r1)
1003
1004 /* Get peer name */
1005 lis %r8,0xe00000@ha
1006 addi %r9,%r8,ofw_peer_name - _start
1007 stw %r9,0(%r1)
1008
1009 /* 1 Argument and 1 return */
1010 li %r9,1
1011 stw %r9,4(%r1)
1012 stw %r9,8(%r1)
1013
1014 stw %r3,12(%r1)
1015
1016 /* Load up the call address */
1017 lwz %r9,ofw_call_addr - _start(%r8)
1018 mtlr %r9
1019
1020 /* Set argument */
1021 mr %r3,%r1
1022
1023 /* Fire */
1024 blrl
1025
1026 lwz %r3,16(%r1)
1027
1028 /* Restore registers */
1029 lwz %r8,28(%r1)
1030 mtlr %r8
1031 lwz %r9,24(%r1)
1032 lwz %r8,20(%r1)
1033
1034 addi %r1,%r1,32
1035
1036 /* Return */
1037 blr
1038
1039 ofw_seek:
1040 /* Reserve stack space ...
1041 * 20 bytes for the ofw call,
1042 * r8, r9, and lr */
1043 subi %r1,%r1,32
1044
1045 /* Store r8, r9, lr */
1046 stw %r8,20(%r1)
1047 stw %r9,24(%r1)
1048 mflr %r8
1049 stw %r8,28(%r1)
1050
1051 /* Get peer name */
1052 lis %r8,0xe00000@ha
1053 addi %r9,%r8,ofw_seek_name - _start
1054 stw %r9,0(%r1)
1055
1056 /* 3 Arguments and 1 return */
1057 li %r9,3
1058 stw %r9,4(%r1)
1059 li %r9,1
1060 stw %r9,8(%r1)
1061
1062 stw %r3,12(%r1)
1063 stw %r4,16(%r1)
1064 stw %r5,20(%r1)
1065
1066 /* Load up the call address */
1067 lwz %r9,ofw_call_addr - _start(%r8)
1068 mtlr %r9
1069
1070 /* Set argument */
1071 mr %r3,%r1
1072
1073 /* Fire */
1074 blrl
1075
1076 lwz %r3,16(%r1)
1077
1078 /* Restore registers */
1079 lwz %r8,28(%r1)
1080 mtlr %r8
1081 lwz %r9,24(%r1)
1082 lwz %r8,20(%r1)
1083
1084 addi %r1,%r1,32
1085
1086 /* Return */
1087 blr
1088
1089
1090 setup_exc:
1091 subi %r1,%r1,32
1092
1093 stw %r3,0(%r1)
1094 mflr %r3
1095 stw %r3,4(%r1)
1096 stw %r8,8(%r1)
1097 stw %r9,12(%r1)
1098 stw %r10,16(%r1)
1099 stw %r12,20(%r1)
1100
1101 lis %r8,0xe00000@ha
1102 xor %r12,%r12,%r12
1103 addi %r12,%r12,0x300
1104 addi %r9,%r8,dsi_exc - _start
1105 addi %r10,%r8,dsi_end - _start
1106
1107 copy_loop:
1108 cmp 0,0,%r9,%r10
1109 beq ret_setup_exc
1110
1111 mr %r3,%r12
1112 bl ofw_print_number
1113 bl ofw_print_space
1114
1115 lwz %r3,0(%r9)
1116 stw %r3,0(%r12)
1117
1118 bl ofw_print_number
1119 bl ofw_print_eol
1120
1121 addi %r12,%r12,4
1122 addi %r9,%r9,4
1123 b copy_loop
1124
1125 ret_setup_exc:
1126 mfmsr %r12
1127 andi. %r12,%r12,0xffbf
1128 mtmsr %r12
1129
1130 lwz %r12,20(%r1)
1131 lwz %r10,16(%r1)
1132 lwz %r9,12(%r1)
1133 lwz %r8,8(%r1)
1134
1135 lwz %r3,4(%r1)
1136 mtlr %r3
1137 lwz %r3,0(%r1)
1138
1139 blr
1140
1141 dsi_exc:
1142 subi %r1,%r1,16
1143
1144 stw %r0,0(%r1)
1145 stw %r3,4(%r1)
1146
1147 mfsrr0 %r3
1148 addi %r3,%r3,4
1149 mtsrr0 %r3
1150
1151 /* mfsrr1 %r3 */
1152 /* ori %r3,%r3,2 */
1153 /* mtsrr1 %r3 */
1154
1155 lwz %r3,4(%r1)
1156 lwz %r0,0(%r1)
1157
1158 addi %r1,%r1,16
1159 rfi
1160 dsi_end:
1161
1162 .org 0x1000
1163 freeldr_banner:
1164 .ascii "ReactOS OpenFirmware Boot Program\r\n\0"
1165
1166 freeldr_halt:
1167 .ascii "ReactOS OpenFirmware Boot Program Halting\r\n\0"
1168
1169 freeldr_reg_init:
1170 .ascii "r\0"
1171 freeldr_reg_lr:
1172 .ascii "lr \0"
1173 freeldr_reg_cr:
1174 .ascii "cr \0"
1175 freeldr_reg_ctr:
1176 .ascii "ctr\0"
1177 freeldr_reg_msr:
1178 .ascii "msr\0"
1179
1180 ofw_call_addr:
1181 .long 0
1182
1183 ofw_memory_size:
1184 .long 0
1185 .long 0
1186 .long 0
1187 .long 0
1188
1189 ofw_finddevice_name:
1190 .ascii "finddevice\0"
1191
1192 ofw_getprop_name:
1193 .ascii "getprop\0"
1194
1195 ofw_write_name:
1196 .ascii "write\0"
1197
1198 ofw_read_name:
1199 .ascii "read\0"
1200
1201 ofw_exit_name:
1202 .ascii "exit\0"
1203
1204 ofw_open_name:
1205 .ascii "open\0"
1206
1207 ofw_child_name:
1208 .ascii "child\0"
1209
1210 ofw_peer_name:
1211 .ascii "peer\0"
1212
1213 ofw_seek_name:
1214 .ascii "seek\0"
1215
1216 ofw_chosen_name:
1217 .ascii "/chosen\0"
1218
1219 ofw_stdout_name:
1220 .ascii "stdout\0"
1221
1222 ofw_memory_name:
1223 .ascii "/memory@0\0"
1224
1225 ofw_reg_name:
1226 .ascii "reg\0"
1227
1228 ofw_functions:
1229 .long ofw_finddevice_hook
1230 .long ofw_getprop_hook
1231 .long ofw_write
1232 .long ofw_read
1233 .long ofw_exit
1234 .long ofw_print_regs
1235 .long ofw_print_string
1236 .long ofw_print_number
1237 .long ofw_open
1238 .long ofw_child
1239 .long ofw_peer
1240 .long ofw_seek
1241
1242 .org 0x2000
1243 stack:
1244 .space 0x4000
1245