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