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