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