Deleted Added
full compact
1/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai 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

--- 40 unchanged lines hidden (view full) ---

49 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 *
57 * $FreeBSD: head/sys/boot/ofw/libofw/openfirm.c 84617 2001-10-07 13:22:25Z benno $
57 * $FreeBSD: head/sys/boot/ofw/libofw/openfirm.c 84972 2001-10-15 09:51:09Z robert $
58 */
59
60#include <machine/stdarg.h>
61
62#include <stand.h>
63
64#include "openfirm.h"
65

--- 26 unchanged lines hidden (view full) ---

92 * Generic functions
93 */
94
95/* Test to see if a service exists. */
96int
97OF_test(char *name)
98{
99 static struct {
100 char *name;
101 int nargs;
102 int nreturns;
103 char *service;
104 int missing;
100 cell_t name;
101 cell_t nargs;
102 cell_t nreturns;
103 cell_t service;
104 cell_t missing;
105 } args = {
106 "test",
106 (cell_t)"test",
107 1,
108 1,
109 0,
110 0
111 };
112
111 args.service = name;
113 args.service = (cell_t)name;
114 if (openfirmware(&args) == -1)
115 return -1;
114 return args.missing;
116 return (int)args.missing;
117}
118
119/* Return firmware millisecond count. */
120int
121OF_milliseconds()
122{
123 static struct {
122 char *name;
123 int nargs;
124 int nreturns;
125 int ms;
124 cell_t name;
125 cell_t nargs;
126 cell_t nreturns;
127 cell_t ms;
128 } args = {
127 "milliseconds",
129 (cell_t)"milliseconds",
130 0,
131 1,
132 0
133 };
134
135 openfirmware(&args);
133 return args.ms;
136 return (int)args.ms;
137}
138
139/*
140 * Device tree functions
141 */
142
143/* Return the next sibling of this node or 0. */
144phandle_t
145OF_peer(phandle_t node)
146{
147 static struct {
145 char *name;
146 int nargs;
147 int nreturns;
148 phandle_t node;
149 phandle_t next;
148 cell_t name;
149 cell_t nargs;
150 cell_t nreturns;
151 cell_t node;
152 cell_t next;
153 } args = {
151 "peer",
154 (cell_t)"peer",
155 1,
156 1,
157 0,
158 0
159 };
160
156 args.node = node;
161 args.node = (u_int)node;
162 if (openfirmware(&args) == -1)
163 return -1;
159 return args.next;
164 return (phandle_t)args.next;
165}
166
167/* Return the first child of this node or 0. */
168phandle_t
169OF_child(phandle_t node)
170{
171 static struct {
167 char *name;
168 int nargs;
169 int nreturns;
170 phandle_t node;
171 phandle_t child;
172 cell_t name;
173 cell_t nargs;
174 cell_t nreturns;
175 cell_t node;
176 cell_t child;
177 } args = {
173 "child",
178 (cell_t)"child",
179 1,
180 1,
181 0,
182 0
183 };
184
178 args.node = node;
185 args.node = (u_int)node;
186 if (openfirmware(&args) == -1)
187 return -1;
181 return args.child;
188 return (phandle_t)args.child;
189}
190
191/* Return the parent of this node or 0. */
192phandle_t
193OF_parent(phandle_t node)
194{
195 static struct {
189 char *name;
190 int nargs;
191 int nreturns;
192 phandle_t node;
193 phandle_t parent;
196 cell_t name;
197 cell_t nargs;
198 cell_t nreturns;
199 cell_t node;
200 cell_t parent;
201 } args = {
195 "parent",
202 (cell_t)"parent",
203 1,
204 1,
205 0,
206 0
207 };
208
200 args.node = node;
209 args.node = (u_int)node;
210 if (openfirmware(&args) == -1)
211 return -1;
203 return args.parent;
212 return (phandle_t)args.parent;
213}
214
215/* Return the package handle that corresponds to an instance handle. */
216phandle_t
217OF_instance_to_package(ihandle_t instance)
218{
219 static struct {
211 char *name;
212 int nargs;
213 int nreturns;
214 ihandle_t instance;
215 phandle_t package;
220 cell_t name;
221 cell_t nargs;
222 cell_t nreturns;
223 cell_t instance;
224 cell_t package;
225 } args = {
217 "instance-to-package",
226 (cell_t)"instance-to-package",
227 1,
228 1,
229 0,
230 0
231 };
232
222 args.instance = instance;
233 args.instance = (u_int)instance;
234 if (openfirmware(&args) == -1)
235 return -1;
225 return args.package;
236 return (phandle_t)args.package;
237}
238
239/* Get the length of a property of a package. */
240int
241OF_getproplen(phandle_t package, char *propname)
242{
243 static struct {
233 char *name;
234 int nargs;
235 int nreturns;
236 phandle_t package;
237 char *propname;
238 int proplen;
244 cell_t name;
245 cell_t nargs;
246 cell_t nreturns;
247 cell_t package;
248 cell_t propname;
249 cell_t proplen;
250 } args = {
240 "getproplen",
251 (cell_t)"getproplen",
252 2,
253 1,
254 0,
255 0,
256 0
257 };
258
245 args.package = package;
246 args.propname = propname;
259 args.package = (u_int)package;
260 args.propname = (cell_t)propname;
261 if (openfirmware(&args) == -1)
262 return -1;
249 return args.proplen;
263 return (int)args.proplen;
264}
265
266/* Get the value of a property of a package. */
267int
268OF_getprop(phandle_t package, char *propname, void *buf, int buflen)
269{
270 static struct {
257 char *name;
258 int nargs;
259 int nreturns;
260 phandle_t package;
261 char *propname;
262 void *buf;
263 int buflen;
264 int size;
271 cell_t name;
272 cell_t nargs;
273 cell_t nreturns;
274 cell_t package;
275 cell_t propname;
276 cell_t buf;
277 cell_t buflen;
278 cell_t size;
279 } args = {
266 "getprop",
280 (cell_t)"getprop",
281 4,
282 1,
283 0,
284 0,
285 0,
286 0,
287 0
288 };
289
271 args.package = package;
272 args.propname = propname;
273 args.buf = buf;
274 args.buflen = buflen;
290 args.package = (u_int)package;
291 args.propname = (cell_t)propname;
292 args.buf = (cell_t)buf;
293 args.buflen = (u_int)buflen;
294 if (openfirmware(&args) == -1)
295 return -1;
277 return args.size;
296 return (int)args.size;
297}
298
299/* Get the next property of a package. */
300int
301OF_nextprop(phandle_t package, char *previous, char *buf)
302{
303 static struct {
285 char *name;
286 int nargs;
287 int nreturns;
288 phandle_t package;
289 char *previous;
290 char *buf;
291 int flag;
304 cell_t name;
305 cell_t nargs;
306 cell_t nreturns;
307 cell_t package;
308 cell_t previous;
309 cell_t buf;
310 cell_t flag;
311 } args = {
293 "nextprop",
312 (cell_t)"nextprop",
313 3,
314 1,
315 0,
316 0,
317 0,
318 0
319 };
320
298 args.package = package;
299 args.previous = previous;
300 args.buf = buf;
321 args.package = (u_int)package;
322 args.previous = (cell_t)previous;
323 args.buf = (cell_t)buf;
324 if (openfirmware(&args) == -1)
325 return -1;
303 return args.flag;
326 return (int)args.flag;
327}
328
329/* Set the value of a property of a package. */
330/* XXX Has a bug on FirePower */
331int
332OF_setprop(phandle_t package, char *propname, void *buf, int len)
333{
334 static struct {
312 char *name;
313 int nargs;
314 int nreturns;
315 phandle_t package;
316 char *propname;
317 void *buf;
318 int len;
319 int size;
335 cell_t name;
336 cell_t nargs;
337 cell_t nreturns;
338 cell_t package;
339 cell_t propname;
340 cell_t buf;
341 cell_t len;
342 cell_t size;
343 } args = {
321 "setprop",
344 (cell_t)"setprop",
345 4,
346 1,
347 0,
348 0,
349 0,
350 0,
351 0
352 };
353
326 args.package = package;
327 args.propname = propname;
328 args.buf = buf;
329 args.len = len;
354 args.package = (u_int)package;
355 args.propname = (cell_t)propname;
356 args.buf = (cell_t)buf;
357 args.len = (u_int)len;
358 if (openfirmware(&args) == -1)
359 return -1;
332 return args.size;
360 return (int)args.size;
361}
362
363/* Convert a device specifier to a fully qualified pathname. */
364int
365OF_canon(const char *device, char *buf, int len)
366{
367 static struct {
340 char *name;
341 int nargs;
342 int nreturns;
343 char *device;
344 char *buf;
345 int len;
346 int size;
368 cell_t name;
369 cell_t nargs;
370 cell_t nreturns;
371 cell_t device;
372 cell_t buf;
373 cell_t len;
374 cell_t size;
375 } args = {
348 "canon",
376 (cell_t)"canon",
377 3,
378 1,
379 0,
380 0,
381 0,
382 0
383 };
384
353 args.device = (char *)(uintptr_t *)device;
354 args.buf = buf;
355 args.len = len;
385 args.device = (cell_t)device;
386 args.buf = (cell_t)buf;
387 args.len = (cell_t)len;
388 if (openfirmware(&args) == -1)
389 return -1;
358 return args.size;
390 return (int)args.size;
391}
392
393/* Return a package handle for the specified device. */
394phandle_t
395OF_finddevice(const char *device)
396{
397 int i;
398 static struct {
366 char *name;
367 int nargs;
368 int nreturns;
369 char *device;
370 phandle_t package;
399 cell_t name;
400 cell_t nargs;
401 cell_t nreturns;
402 cell_t device;
403 cell_t package;
404 } args = {
372 "finddevice",
405 (cell_t)"finddevice",
406 1,
407 1,
408 0,
409 0
410 };
411
377 args.device = (char *)(uintptr_t *)device;
412 args.device = (cell_t)device;
413 if (openfirmware(&args) == -1)
414 return -1;
380 return args.package;
415
416 return (phandle_t)args.package;
417}
418
419/* Return the fully qualified pathname corresponding to an instance. */
420int
421OF_instance_to_path(ihandle_t instance, char *buf, int len)
422{
423 static struct {
388 char *name;
389 int nargs;
390 int nreturns;
391 ihandle_t instance;
392 char *buf;
393 int len;
394 int size;
424 cell_t name;
425 cell_t nargs;
426 cell_t nreturns;
427 cell_t instance;
428 cell_t buf;
429 cell_t len;
430 cell_t size;
431 } args = {
396 "instance-to-path",
432 (cell_t)"instance-to-path",
433 3,
434 1,
435 0,
436 0,
437 0,
438 0
439 };
440
401 args.instance = instance;
402 args.buf = buf;
403 args.len = len;
441 args.instance = (u_int)instance;
442 args.buf = (cell_t)buf;
443 args.len = (u_int)len;
444 if (openfirmware(&args) == -1)
445 return -1;
406 return(args.size);
446 return (int)args.size;
447}
448
449/* Return the fully qualified pathname corresponding to a package. */
450int
451OF_package_to_path(phandle_t package, char *buf, int len)
452{
453 static struct {
414 char *name;
415 int nargs;
416 int nreturns;
417 phandle_t package;
418 char *buf;
419 int len;
420 int size;
454 cell_t name;
455 cell_t nargs;
456 cell_t nreturns;
457 cell_t package;
458 cell_t buf;
459 cell_t len;
460 cell_t size;
461 } args = {
422 "package-to-path",
462 (cell_t)"package-to-path",
463 3,
464 1,
465 0,
466 0,
467 0,
468 0
469 };
470
427 args.package = package;
428 args.buf = buf;
429 args.len = len;
471 args.package = (u_int)package;
472 args.buf = (cell_t)buf;
473 args.len = (u_int)len;
474 if (openfirmware(&args) == -1)
475 return -1;
432 return(args.size);
476 return (int)args.size;
477}
478
479/* Call the method in the scope of a given instance. */
480int
481OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...)
482{
483 va_list ap;
484 static struct {
441 char *name;
442 int nargs;
443 int nreturns;
444 char *method;
445 ihandle_t instance;
446 int args_n_results[12];
485 cell_t name;
486 cell_t nargs;
487 cell_t nreturns;
488 cell_t method;
489 cell_t instance;
490 cell_t args_n_results[12];
491 } args = {
448 "call-method",
492 (cell_t)"call-method",
493 2,
494 1,
495 0,
496 0,
497 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
498 };
499 int *ip, n;
500
501 if (nargs > 6)
502 return -1;
503 args.nargs = nargs + 2;
504 args.nreturns = nreturns + 1;
458 args.method = method;
459 args.instance = instance;
505 args.method = (cell_t)method;
506 args.instance = (u_int)instance;
507 va_start(ap, nreturns);
461 for (ip = args.args_n_results + (n = nargs); --n >= 0;)
508 for (ip = (int *)(args.args_n_results + (n = nargs)); --n >= 0;)
509 *--ip = va_arg(ap, int);
510
511 if (openfirmware(&args) == -1)
512 return -1;
513 if (args.args_n_results[nargs])
467 return args.args_n_results[nargs];
468 for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
514 return (int)args.args_n_results[nargs];
515 for (ip = (int *)(args.args_n_results + nargs + (n = args.nreturns));
516 --n > 0;)
517 *va_arg(ap, int *) = *--ip;
518 va_end(ap);
519 return 0;
520}
521
522/*
523 * Device I/O functions.
524 */
525
526/* Open an instance for a device. */
527ihandle_t
528OF_open(char *device)
529{
530 static struct {
483 char *name;
484 int nargs;
485 int nreturns;
486 char *device;
487 ihandle_t instance;
531 cell_t name;
532 cell_t nargs;
533 cell_t nreturns;
534 cell_t device;
535 cell_t instance;
536 } args = {
489 "open",
537 (cell_t)"open",
538 1,
539 1,
540 0,
541 0
542 };
543
494 args.device = device;
544 args.device = (cell_t)device;
545 if (openfirmware(&args) == -1 || args.instance == 0) {
546 return -1;
547 }
498 return args.instance;
548 return (ihandle_t)args.instance;
549}
550
551/* Close an instance. */
552void
553OF_close(ihandle_t instance)
554{
555 static struct {
506 char *name;
507 int nargs;
508 int nreturns;
509 ihandle_t instance;
556 cell_t name;
557 cell_t nargs;
558 cell_t nreturns;
559 cell_t instance;
560 } args = {
511 "close",
561 (cell_t)"close",
562 1,
563 0,
564 0
565 };
566
516 args.instance = instance;
567 args.instance = (u_int)instance;
568 openfirmware(&args);
569}
570
571/* Read from an instance. */
572int
573OF_read(ihandle_t instance, void *addr, int len)
574{
575 static struct {
525 char *name;
526 int nargs;
527 int nreturns;
528 ihandle_t instance;
529 void *addr;
530 int len;
531 int actual;
576 cell_t name;
577 cell_t nargs;
578 cell_t nreturns;
579 cell_t instance;
580 cell_t addr;
581 cell_t len;
582 cell_t actual;
583 } args = {
533 "read",
584 (cell_t)"read",
585 3,
586 1,
587 0,
588 0,
589 0,
590 0
591 };
592
538 args.instance = instance;
539 args.addr = addr;
540 args.len = len;
593 args.instance = (u_int)instance;
594 args.addr = (cell_t)addr;
595 args.len = (u_int)len;
596
597#if defined(OPENFIRM_DEBUG)
598 printf("OF_read: called with instance=%08x, addr=%p, len=%d\n",
599 args.instance, args.addr, args.len);
600#endif
601
602 if (openfirmware(&args) == -1)
603 return -1;
604
605#if defined(OPENFIRM_DEBUG)
606 printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n",
607 args.instance, args.addr, args.len, args.actual);
608#endif
609
555 return args.actual;
610 return (int)args.actual;
611}
612
613/* Write to an instance. */
614int
615OF_write(ihandle_t instance, void *addr, int len)
616{
617 static struct {
563 char *name;
564 int nargs;
565 int nreturns;
566 ihandle_t instance;
567 void *addr;
568 int len;
569 int actual;
618 cell_t name;
619 cell_t nargs;
620 cell_t nreturns;
621 cell_t instance;
622 cell_t addr;
623 cell_t len;
624 cell_t actual;
625 } args = {
571 "write",
626 (cell_t)"write",
627 3,
628 1,
629 0,
630 0,
631 0,
632 0
633 };
634
576 args.instance = instance;
577 args.addr = addr;
578 args.len = len;
635 args.instance = (u_int)instance;
636 args.addr = (cell_t)addr;
637 args.len = (u_int)len;
638 if (openfirmware(&args) == -1)
639 return -1;
581 return args.actual;
640 return (int)args.actual;
641}
642
643/* Seek to a position. */
644int
645OF_seek(ihandle_t instance, u_int64_t pos)
646{
647 static struct {
589 char *name;
590 int nargs;
591 int nreturns;
592 ihandle_t instance;
593 int poshi;
594 int poslo;
595 int status;
648 cell_t name;
649 cell_t nargs;
650 cell_t nreturns;
651 cell_t instance;
652 cell_t poshi;
653 cell_t poslo;
654 cell_t status;
655 } args = {
597 "seek",
656 (cell_t)"seek",
657 3,
658 1,
659 0,
660 0,
661 0,
662 0
663 };
664
602 args.instance = instance;
603 args.poshi = (int)(pos >> 32);
604 args.poslo = (int)pos;
665 args.instance = (u_int)instance;
666 args.poshi = pos >> 32;
667 args.poslo = pos;
668 if (openfirmware(&args) == -1)
669 return -1;
607 return args.status;
670 return (int)args.status;
671}
672
673/*
674 * Memory functions.
675 */
676
677/* Claim an area of memory. */
678void *
679OF_claim(void *virt, u_int size, u_int align)
680{
681 static struct {
619 char *name;
620 int nargs;
621 int nreturns;
622 void *virt;
623 u_int size;
624 u_int align;
625 void *baseaddr;
682 cell_t name;
683 cell_t nargs;
684 cell_t nreturns;
685 cell_t virt;
686 cell_t size;
687 cell_t align;
688 cell_t baseaddr;
689 } args = {
627 "claim",
690 (cell_t)"claim",
691 3,
692 1,
693 0,
694 0,
695 0,
696 0
697 };
698
632 args.virt = virt;
699 args.virt = (cell_t)virt;
700 args.size = size;
701 args.align = align;
702 if (openfirmware(&args) == -1)
703 return (void *)-1;
637 return args.baseaddr;
704 return (void *)args.baseaddr;
705}
706
707/* Allocate an area of physical memory */
708void *
709OF_alloc_phys(size_t size, int align)
710{
711 static struct {
712 cell_t name;
713 cell_t nargs;
714 cell_t nret;
715 cell_t method;
716 cell_t ihandle;
717 cell_t align;
718 cell_t size;
719 cell_t status;
720 cell_t phys_hi;
721 cell_t phys_low;
722 } args = {
723 (cell_t)"call-method",
724 4,
725 3,
726 (cell_t)"claim",
727 0,
728 0,
729 0,
730 0, /* ret */
731 0,
732 0,
733 };
734
735 args.ihandle = memory;
736 args.size = size;
737 args.align = align;
738
739 if (openfirmware(&args) == -1)
740 return (void *)-1;
741
742 return (void *)(args.phys_hi << 32 | args.phys_low);
743}
744
745/* Release an area of memory. */
746void
747OF_release(void *virt, u_int size)
748{
749 static struct {
645 char *name;
646 int nargs;
647 int nreturns;
648 void *virt;
649 u_int size;
750 cell_t name;
751 cell_t nargs;
752 cell_t nreturns;
753 cell_t virt;
754 cell_t size;
755 } args = {
651 "release",
756 (cell_t)"release",
757 2,
758 0,
759 0,
760 0
761 };
762
656 args.virt = virt;
763 args.virt = (cell_t)virt;
764 args.size = size;
765 openfirmware(&args);
766}
767
768/*
769 * Control transfer functions.
770 */
771
772/* Reset the system and call "boot <bootspec>". */
773void
774OF_boot(char *bootspec)
775{
776 static struct {
670 char *name;
671 int nargs;
672 int nreturns;
673 char *bootspec;
777 cell_t name;
778 cell_t nargs;
779 cell_t nreturns;
780 cell_t bootspec;
781 } args = {
675 "boot",
782 (cell_t)"boot",
783 1,
784 0,
785 0
786 };
787
680 args.bootspec = bootspec;
788 args.bootspec = (cell_t)bootspec;
789 openfirmware(&args);
790 for (;;); /* just in case */
791}
792
793/* Suspend and drop back to the OpenFirmware interface. */
794void
795OF_enter()
796{
797 static struct {
690 char *name;
691 int nargs;
692 int nreturns;
798 cell_t name;
799 cell_t nargs;
800 cell_t nreturns;
801 } args = {
694 "enter",
802 (cell_t)"enter",
803 0,
804 0
805 };
806
807 openfirmware(&args);
700 return; /* We may come back. */
808}
809
810/* Shut down and drop back to the OpenFirmware interface. */
811void
812OF_exit()
813{
814 static struct {
708 char *name;
709 int nargs;
710 int nreturns;
815 cell_t name;
816 cell_t nargs;
817 cell_t nreturns;
818 } args = {
712 "exit",
819 (cell_t)"exit",
820 0,
821 0
822 };
823
824 openfirmware(&args);
825 for (;;); /* just in case */
826}
827
828/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */
722#if 0
829#ifdef __notyet__
830void
831OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
832{
833 static struct {
727 char *name;
728 int nargs;
729 int nreturns;
730 void *virt;
731 u_int size;
732 void (*entry)();
733 void *arg;
734 u_int len;
834 cell_t name;
835 cell_t nargs;
836 cell_t nreturns;
837 cell_t virt;
838 cell_t size;
839 cell_t entry;
840 cell_t arg;
841 cell_t len;
842 } args = {
736 "chain",
843 (cell_t)"chain",
844 5,
845 0,
846 0,
847 0,
848 0,
849 0,
850 0
851 };
852
741 args.virt = virt;
853 args.virt = (cell_t)virt;
854 args.size = size;
743 args.entry = entry;
744 args.arg = arg;
855 args.entry = (cell_t)entry;
856 args.arg = (cell_t)arg;
857 args.len = len;
858 openfirmware(&args);
859}
860#else
861void
862OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
863{
864 /*
865 * This is a REALLY dirty hack till the firmware gets this going
866 */
867 if (size > 0)
868 OF_release(virt, size);
869
870 entry(0, 0, openfirmware, arg, len);
871}
872#endif