No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / ofppc / stand / ofwboot / Locore.c
blob0dbfc302942f6bf65b3a3da2f88181d2466c2c28
1 /* $NetBSD: Locore.c,v 1.21 2008/02/12 04:27:46 garbled Exp $ */
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
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.
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.
34 #include "openfirm.h"
35 #include <sys/param.h>
36 #include <lib/libsa/stand.h>
38 #include <machine/cpu.h>
40 static int (*openfirmware_entry)(void *);
41 static int openfirmware(void *);
43 void startup(void *, int, int (*)(void *), char *, int)
44 __attribute__((__used__));
45 static void setup(void);
47 /* this pad gets the rodata laignment right, don't EVER fiddle it */
48 char *pad __attribute__((__aligned__ (8))) = "pad";
49 int stack[8192/4 + 4] __attribute__((__aligned__ (4), __used__));
50 char *heapspace __attribute__((__aligned__ (4)));
51 char altheap[0x20000] __attribute__((__aligned__ (4)));
53 static int
54 openfirmware(void *arg)
56 int r;
58 __asm volatile ("sync; isync");
59 r = openfirmware_entry(arg);
60 __asm volatile ("sync; isync");
62 return r;
65 void
66 startup(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl)
69 openfirmware_entry = openfirm;
70 setup();
71 main();
72 OF_exit();
75 __dead void
76 OF_exit(void)
78 static struct {
79 char *name;
80 int nargs;
81 int nreturns;
82 } args = {
83 "exit",
88 openfirmware(&args);
89 for (;;); /* just in case */
92 __dead void
93 OF_boot(char *bootspec)
95 static struct {
96 char *name;
97 int nargs;
98 int nreturns;
99 char *bootspec;
100 } args = {
101 "boot",
106 args.bootspec = bootspec;
107 openfirmware(&args);
108 for (;;); /* just in case */
112 OF_finddevice(char *name)
114 static struct {
115 char *name;
116 int nargs;
117 int nreturns;
118 char *device;
119 int phandle;
120 } args = {
121 "finddevice",
126 args.device = name;
127 if (openfirmware(&args) == -1)
128 return -1;
129 return args.phandle;
133 OF_instance_to_package(int ihandle)
135 static struct {
136 char *name;
137 int nargs;
138 int nreturns;
139 int ihandle;
140 int phandle;
141 } args = {
142 "instance-to-package",
147 args.ihandle = ihandle;
148 if (openfirmware(&args) == -1)
149 return -1;
150 return args.phandle;
154 OF_getprop(int handle, char *prop, void *buf, int buflen)
156 static struct {
157 char *name;
158 int nargs;
159 int nreturns;
160 int phandle;
161 char *prop;
162 void *buf;
163 int buflen;
164 int size;
165 } args = {
166 "getprop",
171 args.phandle = handle;
172 args.prop = prop;
173 args.buf = buf;
174 args.buflen = buflen;
175 if (openfirmware(&args) == -1)
176 return -1;
177 return args.size;
180 #ifdef __notyet__ /* Has a bug on FirePower */
182 OF_setprop(int handle, char *prop, void *buf, int len)
184 static struct {
185 char *name;
186 int nargs;
187 int nreturns;
188 int phandle;
189 char *prop;
190 void *buf;
191 int len;
192 int size;
193 } args = {
194 "setprop",
199 args.phandle = handle;
200 args.prop = prop;
201 args.buf = buf;
202 args.len = len;
203 if (openfirmware(&args) == -1)
204 return -1;
205 return args.size;
207 #endif
210 OF_open(char *dname)
212 static struct {
213 char *name;
214 int nargs;
215 int nreturns;
216 char *dname;
217 int handle;
218 } args = {
219 "open",
224 #ifdef OFW_DEBUG
225 printf("OF_open(%s) -> ", dname);
226 #endif
227 args.dname = dname;
228 if (openfirmware(&args) == -1 ||
229 args.handle == 0) {
230 #ifdef OFW_DEBUG
231 printf("lose\n");
232 #endif
233 return -1;
235 #ifdef OFW_DEBUG
236 printf("%d\n", args.handle);
237 #endif
238 return args.handle;
241 void
242 OF_close(int handle)
244 static struct {
245 char *name;
246 int nargs;
247 int nreturns;
248 int handle;
249 } args = {
250 "close",
255 #ifdef OFW_DEBUG
256 printf("OF_close(%d)\n", handle);
257 #endif
258 args.handle = handle;
259 openfirmware(&args);
263 OF_write(int handle, void *addr, int len)
265 static struct {
266 char *name;
267 int nargs;
268 int nreturns;
269 int ihandle;
270 void *addr;
271 int len;
272 int actual;
273 } args = {
274 "write",
279 #ifdef OFW_DEBUG
280 if (len != 1)
281 printf("OF_write(%d, %p, %x) -> ", handle, addr, len);
282 #endif
283 args.ihandle = handle;
284 args.addr = addr;
285 args.len = len;
286 if (openfirmware(&args) == -1) {
287 #ifdef OFW_DEBUG
288 printf("lose\n");
289 #endif
290 return -1;
292 #ifdef OFW_DEBUG
293 if (len != 1)
294 printf("%x\n", args.actual);
295 #endif
296 return args.actual;
300 OF_read(int handle, void *addr, int len)
302 static struct {
303 char *name;
304 int nargs;
305 int nreturns;
306 int ihandle;
307 void *addr;
308 int len;
309 int actual;
310 } args = {
311 "read",
316 #ifdef OFW_DEBUG
317 if (len != 1)
318 printf("OF_read(%d, %p, %x) -> ", handle, addr, len);
319 #endif
320 args.ihandle = handle;
321 args.addr = addr;
322 args.len = len;
323 if (openfirmware(&args) == -1) {
324 #ifdef OFW_DEBUG
325 printf("lose\n");
326 #endif
327 return -1;
329 #ifdef OFW_DEBUG
330 if (len != 1)
331 printf("%x\n", args.actual);
332 #endif
333 return args.actual;
337 OF_seek(int handle, u_quad_t pos)
339 static struct {
340 char *name;
341 int nargs;
342 int nreturns;
343 int handle;
344 int poshi;
345 int poslo;
346 int status;
347 } args = {
348 "seek",
353 #ifdef OFW_DEBUG
354 printf("OF_seek(%d, %x, %x) -> ", handle, (int)(pos >> 32), (int)pos);
355 #endif
356 args.handle = handle;
357 args.poshi = (int)(pos >> 32);
358 args.poslo = (int)pos;
359 if (openfirmware(&args) == -1) {
360 #ifdef OFW_DEBUG
361 printf("lose\n");
362 #endif
363 return -1;
365 #ifdef OFW_DEBUG
366 printf("%d\n", args.status);
367 #endif
368 return args.status;
371 void *
372 OF_alloc_mem(u_int size)
374 static struct {
375 char *name;
376 int nargs;
377 int nreturns;
378 u_int size;
379 void *baseaddr;
380 } args = {
381 "alloc-mem",
385 #ifdef OFW_DEBUG
386 printf("alloc-mem %x -> ", size);
387 #endif
388 if (openfirmware(&args) == -1) {
389 #ifdef OFW_DEBUG
390 printf("lose\n");
391 #endif
392 return (void *)-1;
394 #ifdef OFW_DEBUG
395 printf("%p\n", args.baseaddr);
396 #endif
397 return args.baseaddr;
400 void *
401 OF_claim(void *virt, u_int size, u_int align)
403 static struct {
404 char *name;
405 int nargs;
406 int nreturns;
407 void *virt;
408 u_int size;
409 u_int align;
410 void *baseaddr;
411 } args = {
412 "claim",
417 #ifdef OFW_DEBUG
418 printf("OF_claim(%p, %x, %x) -> ", virt, size, align);
419 #endif
420 args.virt = virt;
421 args.size = size;
422 args.align = align;
423 if (openfirmware(&args) == -1) {
424 #ifdef OFW_DEBUG
425 printf("lose\n");
426 #endif
427 return (void *)-1;
429 #ifdef OFW_DEBUG
430 printf("%p\n", args.baseaddr);
431 #endif
432 return args.baseaddr;
435 void
436 OF_release(void *virt, u_int size)
438 static struct {
439 char *name;
440 int nargs;
441 int nreturns;
442 void *virt;
443 u_int size;
444 } args = {
445 "release",
450 #ifdef OFW_DEBUG
451 printf("OF_release(%p, %x)\n", virt, size);
452 #endif
453 args.virt = virt;
454 args.size = size;
455 openfirmware(&args);
459 OF_milliseconds(void)
461 static struct {
462 char *name;
463 int nargs;
464 int nreturns;
465 int ms;
466 } args = {
467 "milliseconds",
472 openfirmware(&args);
473 return args.ms;
476 #ifdef __notyet__
477 void
478 OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
480 static struct {
481 char *name;
482 int nargs;
483 int nreturns;
484 void *virt;
485 u_int size;
486 void (*entry)();
487 void *arg;
488 u_int len;
489 } args = {
490 "chain",
495 args.virt = virt;
496 args.size = size;
497 args.entry = entry;
498 args.arg = arg;
499 args.len = len;
500 openfirmware(&args);
502 #else
503 void
504 OF_chain(void *virt, u_int size, boot_entry_t entry, void *arg, u_int len)
507 * This is a REALLY dirty hack till the firmware gets this going
509 #if 0
510 OF_release(virt, size);
511 #endif
512 entry(0, 0, openfirmware_entry, arg, len);
514 #endif
516 static int stdin;
517 static int stdout;
519 static void
520 setup(void)
522 int chosen;
524 if ((chosen = OF_finddevice("/chosen")) == -1)
525 OF_exit();
526 if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) !=
527 sizeof(stdin) ||
528 OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
529 sizeof(stdout))
530 OF_exit();
532 //printf("Allocating 0x20000 bytes of ram for boot\n");
533 heapspace = OF_claim(0, 0x20000, NBPG);
534 if (heapspace == (char *)-1) {
535 printf("WARNING: Failed to alloc ram, using bss\n");
536 setheap(&altheap, &altheap[0x20000]);
537 } else
538 setheap(heapspace, heapspace+0x20000);
541 void
542 putchar(int c)
544 char ch = c;
546 if (c == '\n')
547 putchar('\r');
548 OF_write(stdout, &ch, 1);
552 getchar(void)
554 unsigned char ch = '\0';
555 int l;
557 while ((l = OF_read(stdin, &ch, 1)) != 1)
558 if (l != -2 && l != 0)
559 return -1;
560 return ch;
563 #ifdef OFWDUMP
565 static int
566 OF_peer(int phandle)
568 static struct {
569 const char *name;
570 int nargs;
571 int nreturns;
572 int phandle;
573 int sibling;
574 } args = {
575 "peer",
580 args.phandle = phandle;
581 if (openfirmware(&args) == -1)
582 return 0;
583 return args.sibling;
586 static int
587 OF_child(int phandle)
589 static struct {
590 const char *name;
591 int nargs;
592 int nreturns;
593 int phandle;
594 int child;
595 } args = {
596 "child",
601 args.phandle = phandle;
602 if (openfirmware(&args) == -1)
603 return 0;
604 return args.child;
608 OF_nextprop(int handle, const char *prop, void *nextprop)
610 static struct {
611 const char *name;
612 int nargs;
613 int nreturns;
614 int phandle;
615 const char *prop;
616 char *buf;
617 int flag;
618 } args = {
619 "nextprop",
624 args.phandle = handle;
625 args.prop = prop;
626 args.buf = nextprop;
627 if (openfirmware(&args) == -1)
628 return -1;
629 return args.flag;
632 static int
633 OF_package_to_path(int phandle, char *buf, int buflen)
635 static struct {
636 const char *name;
637 int nargs;
638 int nreturns;
639 int phandle;
640 char *buf;
641 int buflen;
642 int length;
643 } args = {
644 "package-to-path",
649 if (buflen > 4096)
650 return -1;
651 args.phandle = phandle;
652 args.buf = buf;
653 args.buflen = buflen;
654 if (openfirmware(&args) < 0)
655 return -1;
656 if (args.length > buflen)
657 args.length = buflen;
658 return args.length;
661 void
662 dump_ofwtree(int node)
664 int peer, child, namelen, dlen, i;
665 char namebuf[33], newnamebuf[33];
666 char path[256], data[256];
668 for (peer = node; peer; peer = OF_peer(peer)) {
669 printf("\nnode: 0x%x ", peer);
670 if (OF_package_to_path(peer, path, 512) >= 0)
671 printf("path=%s", path);
672 printf("\n");
673 namebuf[0] = '\0';
674 namelen = OF_nextprop(peer, namebuf, &newnamebuf);
675 while (namelen >= 0) {
676 /*printf("namelen == %d namebuf=%s new=%s\n", namelen,
677 namebuf, newnamebuf);*/
678 //newnamebuf[namelen] = '\0';
679 strcpy(namebuf, newnamebuf);
680 printf(" %s :", newnamebuf);
681 dlen = OF_getprop(peer, newnamebuf, data, 256);
682 if (dlen > 0) {
683 if (data[0] < 0177)
684 printf(" %s\n", data);
685 else
686 printf("\n");
687 printf(" ");
688 for (i=0; i < dlen && i < 256; i++) {
689 if (data[i] < 0x10)
690 printf("0");
691 printf("%x", data[i]);
692 if ((i+1)%4 == 0)
693 printf(" ");
694 if ((i+1)%32 == 0)
695 printf("\n ");
698 printf("\n");
699 namelen = OF_nextprop(peer, namebuf, &newnamebuf);
700 if (newnamebuf[0] == '\0' ||
701 strcmp(namebuf, newnamebuf) == 0)
702 break;
704 child = OF_child(peer);
705 if (child > 0)
706 dump_ofwtree(child);
710 #endif /* OFWDUMP */