xref: /netbsd-src/sys/arch/sparc/stand/ofwboot/Locore.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: Locore.c,v 1.6 2005/12/11 12:19:08 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5  * Copyright (C) 1995, 1996 TooLs GmbH.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by TooLs GmbH.
19  * 4. The name of TooLs GmbH may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <lib/libsa/stand.h>
35 #include "openfirm.h"
36 
37 #include <machine/cpu.h>
38 
39 vaddr_t OF_claim_virt __P((vaddr_t vaddr, int len));
40 vaddr_t OF_alloc_virt __P((int len, int align));
41 int OF_free_virt __P((vaddr_t vaddr, int len));
42 int OF_unmap_virt __P((vaddr_t vaddr, int len));
43 vaddr_t OF_map_phys __P((paddr_t paddr, off_t size, vaddr_t vaddr, int mode));
44 paddr_t OF_alloc_phys __P((int len, int align));
45 paddr_t OF_claim_phys __P((paddr_t phys, int len));
46 int OF_free_phys __P((paddr_t paddr, int len));
47 
48 extern int openfirmware(void *);
49 
50 void setup __P((void));
51 
52 __dead void
53 _rtt()
54 {
55 	struct {
56 		cell_t name;
57 		cell_t nargs;
58 		cell_t nreturns;
59 	} args;
60 
61 	args.name = ADR2CELL("exit");
62 	args.nargs = 0;
63 	args.nreturns = 0;
64 	openfirmware(&args);
65 	while (1);			/* just in case */
66 }
67 
68 void
69 OF_enter()
70 {
71 	struct {
72 		cell_t name;
73 		cell_t nargs;
74 		cell_t nreturns;
75 	} args;
76 
77 	args.name = ADR2CELL("enter");
78 	args.nargs = 0;
79 	args.nreturns = 0;
80 	openfirmware(&args);
81 }
82 
83 int
84 OF_finddevice(name)
85 	const char *name;
86 {
87 	struct {
88 		cell_t name;
89 		cell_t nargs;
90 		cell_t nreturns;
91 		cell_t device;
92 		cell_t phandle;
93 	} args;
94 
95 	args.name = ADR2CELL("finddevice");
96 	args.nargs = 1;
97 	args.nreturns = 1;
98 	args.device = ADR2CELL(name);
99 	if (openfirmware(&args) == -1)
100 		return -1;
101 	return args.phandle;
102 }
103 
104 int
105 OF_instance_to_package(ihandle)
106 	int ihandle;
107 {
108 	struct {
109 		cell_t name;
110 		cell_t nargs;
111 		cell_t nreturns;
112 		cell_t ihandle;
113 		cell_t phandle;
114 	} args;
115 
116 	args.name = ADR2CELL("instance-to-package");
117 	args.nargs = 1;
118 	args.nreturns = 1;
119 	args.ihandle = HDL2CELL(ihandle);
120 	if (openfirmware(&args) == -1)
121 		return -1;
122 	return args.phandle;
123 }
124 
125 int
126 OF_getprop(handle, prop, buf, buflen)
127 	int handle;
128 	const char *prop;
129 	void *buf;
130 	int buflen;
131 {
132 	struct {
133 		cell_t name;
134 		cell_t nargs;
135 		cell_t nreturns;
136 		cell_t phandle;
137 		cell_t prop;
138 		cell_t buf;
139 		cell_t buflen;
140 		cell_t size;
141 	} args;
142 
143 	args.name = ADR2CELL("getprop");
144 	args.nargs = 4;
145 	args.nreturns = 1;
146 	args.phandle = HDL2CELL(handle);
147 	args.prop = ADR2CELL(prop);
148 	args.buf = ADR2CELL(buf);
149 	args.buflen = buflen;
150 	if (openfirmware(&args) == -1)
151 		return -1;
152 	return args.size;
153 }
154 
155 #ifdef	__notyet__	/* Has a bug on FirePower */
156 int
157 OF_setprop(handle, prop, buf, len)
158 	u_int handle;
159 	char *prop;
160 	void *buf;
161 	int len;
162 {
163 	struct {
164 		cell_t name;
165 		cell_t nargs;
166 		cell_t nreturns;
167 		cell_t phandle;
168 		cell_t prop;
169 		cell_t buf;
170 		cell_t len;
171 		cell_t size;
172 	} args;
173 
174 	args.name = ADR2CELL("setprop");
175 	args.nargs = 4;
176 	args.nreturns = 1;
177 	args.phandle = HDL2CELL(handle);
178 	args.prop = ADR2CELL(prop);
179 	args.buf = ADR2CELL(buf);
180 	args.len = len;
181 	if (openfirmware(&args) == -1)
182 		return -1;
183 	return args.size;
184 }
185 #endif
186 
187 int
188 OF_open(dname)
189 	const char *dname;
190 {
191 	struct {
192 		cell_t name;
193 		cell_t nargs;
194 		cell_t nreturns;
195 		cell_t dname;
196 		cell_t handle;
197 	} args;
198 
199 	args.name = ADR2CELL("open");
200 	args.nargs = 1;
201 	args.nreturns = 1;
202 	args.dname = ADR2CELL(dname);
203 	if (openfirmware(&args) == -1 ||
204 	    args.handle == 0)
205 		return -1;
206 	return args.handle;
207 }
208 
209 void
210 OF_close(handle)
211 	int handle;
212 {
213 	struct {
214 		cell_t name;
215 		cell_t nargs;
216 		cell_t nreturns;
217 		cell_t handle;
218 	} args;
219 
220 	args.name = ADR2CELL("close");
221 	args.nargs = 1;
222 	args.nreturns = 1;
223 	args.handle = HDL2CELL(handle);
224 	openfirmware(&args);
225 }
226 
227 int
228 OF_write(handle, addr, len)
229 	int handle;
230 	const void *addr;
231 	int len;
232 {
233 	struct {
234 		cell_t name;
235 		cell_t nargs;
236 		cell_t nreturns;
237 		cell_t ihandle;
238 		cell_t addr;
239 		cell_t len;
240 		cell_t actual;
241 	} args;
242 
243 	args.name = ADR2CELL("write");
244 	args.nargs = 3;
245 	args.nreturns = 1;
246 	args.ihandle = HDL2CELL(handle);
247 	args.addr = ADR2CELL(addr);
248 	args.len = len;
249 	if (openfirmware(&args) == -1)
250 		return -1;
251 	return args.actual;
252 }
253 
254 int
255 OF_read(handle, addr, len)
256 	int handle;
257 	void *addr;
258 	int len;
259 {
260 	struct {
261 		cell_t name;
262 		cell_t nargs;
263 		cell_t nreturns;
264 		cell_t ihandle;
265 		cell_t addr;
266 		cell_t len;
267 		cell_t actual;
268 	} args;
269 
270 	args.name = ADR2CELL("read");
271 	args.nargs = 3;
272 	args.nreturns = 1;
273 	args.ihandle = HDL2CELL(handle);
274 	args.addr = ADR2CELL(addr);
275 	args.len = len;
276 	if (openfirmware(&args) == -1) {
277 		return -1;
278 	}
279 	return args.actual;
280 }
281 
282 int
283 OF_seek(handle, pos)
284 	int handle;
285 	u_quad_t pos;
286 {
287 	struct {
288 		cell_t name;
289 		cell_t nargs;
290 		cell_t nreturns;
291 		cell_t handle;
292 		cell_t poshi;
293 		cell_t poslo;
294 		cell_t status;
295 	} args;
296 
297 	args.name = ADR2CELL("seek");
298 	args.nargs = 3;
299 	args.nreturns = 1;
300 	args.handle = HDL2CELL(handle);
301 	args.poshi = HDL2CELL(pos >> 32);
302 	args.poslo = HDL2CELL(pos);
303 	if (openfirmware(&args) == -1) {
304 		return -1;
305 	}
306 	return args.status;
307 }
308 
309 void
310 OF_release(virt, size)
311 	void *virt;
312 	u_int size;
313 {
314 	struct {
315 		cell_t name;
316 		cell_t nargs;
317 		cell_t nreturns;
318 		cell_t virt;
319 		cell_t size;
320 	} args;
321 
322 	args.name = ADR2CELL("release");
323 	args.nargs = 2;
324 	args.nreturns = 0;
325 	args.virt = ADR2CELL(virt);
326 	args.size = size;
327 	openfirmware(&args);
328 }
329 
330 int
331 OF_milliseconds()
332 {
333 	struct {
334 		cell_t name;
335 		cell_t nargs;
336 		cell_t nreturns;
337 		cell_t ms;
338 	} args;
339 
340 	args.name = ADR2CELL("milliseconds");
341 	args.nargs = 0;
342 	args.nreturns = 1;
343 	openfirmware(&args);
344 	return args.ms;
345 }
346 
347 void
348 OF_chain(virt, size, entry, arg, len)
349 	void *virt;
350 	u_int size;
351 	void (*entry)();
352 	void *arg;
353 	u_int len;
354 {
355 	extern int64_t romp;
356 	extern int debug;
357 	struct {
358 		cell_t name;
359 		cell_t nargs;
360 		cell_t nreturns;
361 		cell_t virt;
362 		cell_t size;
363 		cell_t entry;
364 		cell_t arg;
365 		cell_t len;
366 	} args;
367 
368 	args.name = ADR2CELL("chain");
369 	args.nargs = 5;
370 	args.nreturns = 0;
371 	args.virt = ADR2CELL(virt);
372 	args.size = size;
373 	args.entry = ADR2CELL(entry);
374 	args.arg = ADR2CELL(arg);
375 	args.len = len;
376 	openfirmware(&args);
377 	if (debug) {
378 		printf("OF_chain: prom returned!\n");
379 
380 		/* OK, firmware failed us.  Try calling prog directly */
381 		printf("Calling entry(%p, %p, %x, %lx, %lx)\n", entry, arg, len,
382 			(unsigned long)romp, (unsigned long)romp);
383 	}
384 	entry(0, arg, len, (unsigned long)romp, (unsigned long)romp);
385 	panic("OF_chain: kernel returned!");
386 	__asm("ta 2" : :);
387 }
388 
389 static u_int stdin;
390 static u_int stdout;
391 static u_int mmuh = -1;
392 static u_int memh = -1;
393 
394 void
395 setup()
396 {
397 	u_int chosen;
398 
399 	if ((chosen = OF_finddevice("/chosen")) == -1)
400 		_rtt();
401 	if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != sizeof(stdin)
402 	    || OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) != sizeof(stdout)
403 	    || OF_getprop(chosen, "mmu", &mmuh, sizeof(mmuh)) != sizeof(mmuh)
404 	    || OF_getprop(chosen, "memory", &memh, sizeof(memh)) != sizeof(memh))
405 		_rtt();
406 }
407 
408 /*
409  * The following need either the handle to memory or the handle to the MMU.
410  */
411 
412 /*
413  * Grab some address space from the prom
414  *
415  * Only works while the prom is actively mapping us.
416  */
417 vaddr_t
418 OF_claim_virt(vaddr, len)
419 vaddr_t vaddr;
420 int len;
421 {
422 	struct {
423 		cell_t name;
424 		cell_t nargs;
425 		cell_t nreturns;
426 		cell_t method;
427 		cell_t ihandle;
428 		cell_t align;
429 		cell_t len;
430 		cell_t vaddr;
431 		cell_t status;
432 		cell_t retaddr;
433 	} args;
434 
435 #ifdef	__notyet
436 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
437 		OF_printf("OF_claim_virt: cannot get mmuh\r\n");
438 		return -1LL;
439 	}
440 #endif
441 	args.name = ADR2CELL("call-method");
442 	args.nargs = 5;
443 	args.nreturns = 2;
444 	args.method = ADR2CELL("claim");
445 	args.ihandle = HDL2CELL(mmuh);
446 	args.align = 0;
447 	args.len = len;
448 	args.vaddr = ADR2CELL(vaddr);
449 	if(openfirmware(&args) != 0)
450 		return -1LL;
451 	return args.retaddr; /* Kluge till we go 64-bit */
452 }
453 
454 /*
455  * Request some address space from the prom
456  *
457  * Only works while the prom is actively mapping us.
458  */
459 vaddr_t
460 OF_alloc_virt(len, align)
461 int len;
462 int align;
463 {
464 	int retaddr=-1;
465 	struct {
466 		cell_t name;
467 		cell_t nargs;
468 		cell_t nreturns;
469 		cell_t method;
470 		cell_t ihandle;
471 		cell_t align;
472 		cell_t len;
473 		cell_t status;
474 		cell_t retaddr;
475 	} args;
476 
477 #ifdef	__notyet
478 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
479 		OF_printf("OF_alloc_virt: cannot get mmuh\r\n");
480 		return -1LL;
481 	}
482 #endif
483 	args.name = ADR2CELL("call-method");
484 	args.nargs = 4;
485 	args.nreturns = 2;
486 	args.method = ADR2CELL("claim");
487 	args.ihandle = mmuh;
488 	args.align = align;
489 	args.len = len;
490 	args.retaddr = ADR2CELL(&retaddr);
491 	if(openfirmware(&args) != 0)
492 		return -1LL;
493 	return (vaddr_t)args.retaddr; /* Kluge till we go 64-bit */
494 }
495 
496 /*
497  * Release some address space to the prom
498  *
499  * Only works while the prom is actively mapping us.
500  */
501 int
502 OF_free_virt(vaddr, len)
503 vaddr_t vaddr;
504 int len;
505 {
506 	struct {
507 		cell_t name;
508 		cell_t nargs;
509 		cell_t nreturns;
510 		cell_t method;
511 		cell_t ihandle;
512 		cell_t len;
513 		cell_t vaddr;
514 	} args;
515 
516 #ifdef	__notyet
517 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
518 		OF_printf("OF_claim_virt: cannot get mmuh\r\n");
519 		return -1;
520 	}
521 #endif
522 	args.name = ADR2CELL("call-method");
523 	args.nargs = 4;
524 	args.nreturns = 0;
525 	args.method = ADR2CELL("release");
526 	args.ihandle = HDL2CELL(mmuh);
527 	args.vaddr = ADR2CELL(vaddr);
528 	args.len = len;
529 	return openfirmware(&args);
530 }
531 
532 
533 /*
534  * Unmap some address space
535  *
536  * Only works while the prom is actively mapping us.
537  */
538 int
539 OF_unmap_virt(vaddr, len)
540 vaddr_t vaddr;
541 int len;
542 {
543 	struct {
544 		cell_t name;
545 		cell_t nargs;
546 		cell_t nreturns;
547 		cell_t method;
548 		cell_t ihandle;
549 		cell_t len;
550 		cell_t vaddr;
551 	} args;
552 
553 #ifdef	__notyet
554 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
555 		OF_printf("OF_claim_virt: cannot get mmuh\r\n");
556 		return -1;
557 	}
558 #endif
559 	args.name = ADR2CELL("call-method");
560 	args.nargs = 4;
561 	args.nreturns = 0;
562 	args.method = ADR2CELL("unmap");
563 	args.ihandle = HDL2CELL(mmuh);
564 	args.vaddr = ADR2CELL(vaddr);
565 	args.len = len;
566 	return openfirmware(&args);
567 }
568 
569 /*
570  * Have prom map in some memory
571  *
572  * Only works while the prom is actively mapping us.
573  */
574 vaddr_t
575 OF_map_phys(paddr, size, vaddr, mode)
576 paddr_t paddr;
577 off_t size;
578 vaddr_t vaddr;
579 int mode;
580 {
581 	struct {
582 		cell_t name;
583 		cell_t nargs;
584 		cell_t nreturns;
585 		cell_t method;
586 		cell_t ihandle;
587 		cell_t mode;
588 		cell_t size;
589 		cell_t vaddr;
590 		cell_t paddr_hi;
591 		cell_t paddr_lo;
592 		cell_t status;
593 		cell_t retaddr;
594 	} args;
595 
596 #ifdef	__notyet
597 	if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
598 		OF_printf("OF_map_phys: cannot get mmuh\r\n");
599 		return 0LL;
600 	}
601 #endif
602 	args.name = ADR2CELL("call-method");
603 	args.nargs = 7;
604 	args.nreturns = 1;
605 	args.method = ADR2CELL("map");
606 	args.ihandle = HDL2CELL(mmuh);
607 	args.mode = mode;
608 	args.size = size;
609 	args.vaddr = ADR2CELL(vaddr);
610 	args.paddr_hi = ADR2CELL(paddr>>32);
611 	args.paddr_lo = ADR2CELL(paddr);
612 
613 	if (openfirmware(&args) == -1)
614 		return -1;
615 	if (args.status)
616 		return -1;
617 	return (vaddr_t)args.retaddr;
618 }
619 
620 
621 /*
622  * Request some RAM from the prom
623  *
624  * Only works while the prom is actively mapping us.
625  */
626 paddr_t
627 OF_alloc_phys(len, align)
628 int len;
629 int align;
630 {
631 	paddr_t paddr;
632 	struct {
633 		cell_t name;
634 		cell_t nargs;
635 		cell_t nreturns;
636 		cell_t method;
637 		cell_t ihandle;
638 		cell_t align;
639 		cell_t len;
640 		cell_t status;
641 		cell_t phys_hi;
642 		cell_t phys_lo;
643 	} args;
644 
645 #ifdef	__notyet
646 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
647 		OF_printf("OF_alloc_phys: cannot get memh\r\n");
648 		return -1LL;
649 	}
650 #endif
651 	args.name = ADR2CELL("call-method");
652 	args.nargs = 4;
653 	args.nreturns = 3;
654 	args.method = ADR2CELL("claim");
655 	args.ihandle = HDL2CELL(memh);
656 	args.align = align;
657 	args.len = len;
658 	if(openfirmware(&args) != 0)
659 		return -1LL;
660 	paddr = (paddr_t)(args.phys_hi<<32)|((unsigned int)(args.phys_lo));
661 	return paddr; /* Kluge till we go 64-bit */
662 }
663 
664 /*
665  * Request some specific RAM from the prom
666  *
667  * Only works while the prom is actively mapping us.
668  */
669 paddr_t
670 OF_claim_phys(phys, len)
671 paddr_t phys;
672 int len;
673 {
674 	paddr_t paddr;
675 	struct {
676 		cell_t name;
677 		cell_t nargs;
678 		cell_t nreturns;
679 		cell_t method;
680 		cell_t ihandle;
681 		cell_t align;
682 		cell_t len;
683 		cell_t phys_hi;
684 		cell_t phys_lo;
685 		cell_t status;
686 		cell_t res;
687 		cell_t rphys_hi;
688 		cell_t rphys_lo;
689 	} args;
690 
691 #ifdef	__notyet
692 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
693 		OF_printf("OF_alloc_phys: cannot get memh\r\n");
694 		return 0LL;
695 	}
696 #endif
697 	args.name = ADR2CELL("call-method");
698 	args.nargs = 6;
699 	args.nreturns = 4;
700 	args.method = ADR2CELL("claim");
701 	args.ihandle = HDL2CELL(memh);
702 	args.align = 0;
703 	args.len = len;
704 	args.phys_hi = HDL2CELL(phys>>32);
705 	args.phys_lo = HDL2CELL(phys);
706 	if(openfirmware(&args) != 0)
707 		return 0LL;
708 	paddr = (paddr_t)(args.rphys_hi<<32)|((unsigned int)(args.rphys_lo));
709 	return paddr;
710 }
711 
712 /*
713  * Free some RAM to prom
714  *
715  * Only works while the prom is actively mapping us.
716  */
717 int
718 OF_free_phys(phys, len)
719 paddr_t phys;
720 int len;
721 {
722 	struct {
723 		cell_t name;
724 		cell_t nargs;
725 		cell_t nreturns;
726 		cell_t method;
727 		cell_t ihandle;
728 		cell_t len;
729 		cell_t phys_hi;
730 		cell_t phys_lo;
731 	} args;
732 
733 #ifdef	__notyet
734 	if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
735 		OF_printf("OF_free_phys: cannot get memh\r\n");
736 		return -1;
737 	}
738 #endif
739 	args.name = ADR2CELL("call-method");
740 	args.nargs = 5;
741 	args.nreturns = 0;
742 	args.method = ADR2CELL("release");
743 	args.ihandle = HDL2CELL(memh);
744 	args.len = len;
745 	args.phys_hi = HDL2CELL(phys>>32);
746 	args.phys_lo = HDL2CELL(phys);
747 	return openfirmware(&args);
748 }
749 
750 
751 /*
752  * Claim virtual memory -- does not map it in.
753  */
754 
755 void *
756 OF_claim(virt, size, align)
757 	void *virt;
758 	u_int size;
759 	u_int align;
760 {
761 #define SUNVMOF
762 #ifndef SUNVMOF
763 	struct {
764 		cell_t name;
765 		cell_t nargs;
766 		cell_t nreturns;
767 		cell_t virt;
768 		cell_t size;
769 		cell_t align;
770 		cell_t baseaddr;
771 	} args;
772 
773 
774 	args.name = ADR2CELL("claim");
775 	args.nargs = 3;
776 	args.nreturns = 1;
777 	args.virt = virt;
778 	args.size = size;
779 	args.align = align;
780 	if (openfirmware(&args) == -1)
781 		return (void *)-1;
782 	return args.baseaddr;
783 #else
784 /*
785  * Sun Ultra machines run the firmware with VM enabled,
786  * so you need to handle allocating and mapping both
787  * virtual and physical memory.  Ugh.
788  */
789 
790 	paddr_t paddr;
791 	void* newvirt = NULL;
792 
793 	if (virt == NULL) {
794 		if ((virt = (void*)OF_alloc_virt(size, align)) == (void*)-1) {
795 			printf("OF_alloc_virt(%d,%d) failed w/%x\n", size, align, virt);
796 			return (void *)-1;
797 		}
798 	} else {
799 		if ((newvirt = (void*)OF_claim_virt((vaddr_t)virt, size)) == (void*)-1) {
800 			printf("OF_claim_virt(%x,%d) failed w/%x\n", virt, size, newvirt);
801 			return (void *)-1;
802 		}
803 	}
804 	if ((paddr = OF_alloc_phys(size, align)) == -1) {
805 		printf("OF_alloc_phys(%d,%d) failed\n", size, align);
806 		OF_free_virt((vaddr_t)virt, size);
807 		return (void *)-1;
808 	}
809 	if (OF_map_phys(paddr, size, (vaddr_t)virt, -1) == -1) {
810 		printf("OF_map_phys(%x,%d,%x,%d) failed\n", paddr, size, virt, -1);
811 		OF_free_phys((paddr_t)paddr, size);
812 		OF_free_virt((vaddr_t)virt, size);
813 		return (void *)-1;
814 	}
815 	return (void *)virt;
816 #endif
817 }
818 
819 
820 void
821 putchar(c)
822 	int c;
823 {
824 	char ch = c;
825 
826 	if (c == '\n')
827 		putchar('\r');
828 	OF_write(stdout, &ch, 1);
829 }
830 
831 int
832 getchar()
833 {
834 	unsigned char ch = '\0';
835 	int l;
836 
837 	while ((l = OF_read(stdin, &ch, 1)) != 1)
838 		if (l != -2 && l != 0)
839 			return -1;
840 	return ch;
841 }
842