Locore.c revision 1.7.4.3 1 /* $NetBSD: Locore.c,v 1.7.4.3 2002/06/23 17:37:58 jdolecek 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
36 #include <machine/cpu.h>
37 #include <machine/stdarg.h>
38
39 #include "openfirm.h"
40
41 static int (*openfirmware) __P((void *));
42
43 static void startup __P((void *, int, int (*)(void *), char *, int));
44 static void setup __P((void));
45
46 static int stack[8192/4 + 4];
47
48 #ifdef XCOFF_GLUE
49 asm("
50 .text
51 .globl _entry
52 _entry:
53 .long _start,0,0
54 ");
55 #endif
56
57 asm("
58 .text
59 .globl _start
60 _start:
61 li 8,0
62 li 9,0x100
63 mtctr 9
64 1:
65 dcbf 0,8
66 icbi 0,8
67 addi 8,8,0x20
68 bdnz 1b
69 sync
70 isync
71
72 lis 1,stack@ha
73 addi 1,1,stack@l
74 addi 1,1,8192
75
76 mfmsr 8
77 li 0,0
78 mtmsr 0
79 isync
80
81 mtibatu 0,0
82 mtibatu 1,0
83 mtibatu 2,0
84 mtibatu 3,0
85 mtdbatu 0,0
86 mtdbatu 1,0
87 mtdbatu 2,0
88 mtdbatu 3,0
89
90 li 9,0x12 /* BATL(0, BAT_M, BAT_PP_RW) */
91 mtibatl 0,9
92 mtdbatl 0,9
93 li 9,0x1ffe /* BATU(0, BAT_BL_256M, BAT_Vs) */
94 mtibatu 0,9
95 mtdbatu 0,9
96 isync
97
98 mtmsr 8
99 isync
100
101 b startup
102 ");
103
104 #if 0
105 static int
106 openfirmware(arg)
107 void *arg;
108 {
109
110 asm volatile ("sync; isync");
111 openfirmware_entry(arg);
112 asm volatile ("sync; isync");
113 }
114 #endif
115
116 static void
117 startup(vpd, res, openfirm, arg, argl)
118 void *vpd;
119 int res;
120 int (*openfirm)(void *);
121 char *arg;
122 int argl;
123 {
124 extern char etext[], _end[], _edata[];
125
126 memset(_edata, 0, (_end - _edata));
127 openfirmware = openfirm;
128 setup();
129 main();
130 OF_exit();
131 }
132
133 __dead void
134 OF_exit()
135 {
136 static struct {
137 char *name;
138 int nargs;
139 int nreturns;
140 } args = {
141 "exit",
142 0,
143 0
144 };
145
146 openfirmware(&args);
147 for (;;); /* just in case */
148 }
149
150 int
151 OF_finddevice(name)
152 char *name;
153 {
154 static struct {
155 char *name;
156 int nargs;
157 int nreturns;
158 char *device;
159 int phandle;
160 } args = {
161 "finddevice",
162 1,
163 1,
164 };
165
166 args.device = name;
167 if (openfirmware(&args) == -1)
168 return -1;
169 return args.phandle;
170 }
171
172 int
173 OF_instance_to_package(ihandle)
174 int ihandle;
175 {
176 static struct {
177 char *name;
178 int nargs;
179 int nreturns;
180 int ihandle;
181 int phandle;
182 } args = {
183 "instance-to-package",
184 1,
185 1,
186 };
187
188 args.ihandle = ihandle;
189 if (openfirmware(&args) == -1)
190 return -1;
191 return args.phandle;
192 }
193
194 int
195 OF_getprop(handle, prop, buf, buflen)
196 int handle;
197 char *prop;
198 void *buf;
199 int buflen;
200 {
201 static struct {
202 char *name;
203 int nargs;
204 int nreturns;
205 int phandle;
206 char *prop;
207 void *buf;
208 int buflen;
209 int size;
210 } args = {
211 "getprop",
212 4,
213 1,
214 };
215
216 args.phandle = handle;
217 args.prop = prop;
218 args.buf = buf;
219 args.buflen = buflen;
220 if (openfirmware(&args) == -1)
221 return -1;
222 return args.size;
223 }
224
225 #ifdef __notyet__ /* Has a bug on FirePower */
226 int
227 OF_setprop(handle, prop, buf, len)
228 int handle;
229 char *prop;
230 void *buf;
231 int len;
232 {
233 static struct {
234 char *name;
235 int nargs;
236 int nreturns;
237 int phandle;
238 char *prop;
239 void *buf;
240 int len;
241 int size;
242 } args = {
243 "setprop",
244 4,
245 1,
246 };
247
248 args.phandle = handle;
249 args.prop = prop;
250 args.buf = buf;
251 args.len = len;
252 if (openfirmware(&args) == -1)
253 return -1;
254 return args.size;
255 }
256 #endif
257
258 int
259 OF_open(dname)
260 char *dname;
261 {
262 static struct {
263 char *name;
264 int nargs;
265 int nreturns;
266 char *dname;
267 int handle;
268 } args = {
269 "open",
270 1,
271 1,
272 };
273
274 #ifdef OFW_DEBUG
275 printf("OF_open(%s) -> ", dname);
276 #endif
277 args.dname = dname;
278 if (openfirmware(&args) == -1 ||
279 args.handle == 0) {
280 #ifdef OFW_DEBUG
281 printf("lose\n");
282 #endif
283 return -1;
284 }
285 #ifdef OFW_DEBUG
286 printf("%d\n", args.handle);
287 #endif
288 return args.handle;
289 }
290
291 void
292 OF_close(handle)
293 int handle;
294 {
295 static struct {
296 char *name;
297 int nargs;
298 int nreturns;
299 int handle;
300 } args = {
301 "close",
302 1,
303 0,
304 };
305
306 #ifdef OFW_DEBUG
307 printf("OF_close(%d)\n", handle);
308 #endif
309 args.handle = handle;
310 openfirmware(&args);
311 }
312
313 int
314 OF_write(handle, addr, len)
315 int handle;
316 void *addr;
317 int len;
318 {
319 static struct {
320 char *name;
321 int nargs;
322 int nreturns;
323 int ihandle;
324 void *addr;
325 int len;
326 int actual;
327 } args = {
328 "write",
329 3,
330 1,
331 };
332
333 #ifdef OFW_DEBUG
334 if (len != 1)
335 printf("OF_write(%d, %x, %x) -> ", handle, addr, len);
336 #endif
337 args.ihandle = handle;
338 args.addr = addr;
339 args.len = len;
340 if (openfirmware(&args) == -1) {
341 #ifdef OFW_DEBUG
342 printf("lose\n");
343 #endif
344 return -1;
345 }
346 #ifdef OFW_DEBUG
347 if (len != 1)
348 printf("%x\n", args.actual);
349 #endif
350 return args.actual;
351 }
352
353 int
354 OF_read(handle, addr, len)
355 int handle;
356 void *addr;
357 int len;
358 {
359 static struct {
360 char *name;
361 int nargs;
362 int nreturns;
363 int ihandle;
364 void *addr;
365 int len;
366 int actual;
367 } args = {
368 "read",
369 3,
370 1,
371 };
372
373 #ifdef OFW_DEBUG
374 if (len != 1)
375 printf("OF_read(%d, %x, %x) -> ", handle, addr, len);
376 #endif
377 args.ihandle = handle;
378 args.addr = addr;
379 args.len = len;
380 if (openfirmware(&args) == -1) {
381 #ifdef OFW_DEBUG
382 printf("lose\n");
383 #endif
384 return -1;
385 }
386 #ifdef OFW_DEBUG
387 if (len != 1)
388 printf("%x\n", args.actual);
389 #endif
390 return args.actual;
391 }
392
393 int
394 OF_seek(handle, pos)
395 int handle;
396 u_quad_t pos;
397 {
398 static struct {
399 char *name;
400 int nargs;
401 int nreturns;
402 int handle;
403 int poshi;
404 int poslo;
405 int status;
406 } args = {
407 "seek",
408 3,
409 1,
410 };
411
412 #ifdef OFW_DEBUG
413 printf("OF_seek(%d, %x, %x) -> ", handle, (int)(pos >> 32), (int)pos);
414 #endif
415 args.handle = handle;
416 args.poshi = (int)(pos >> 32);
417 args.poslo = (int)pos;
418 if (openfirmware(&args) == -1) {
419 #ifdef OFW_DEBUG
420 printf("lose\n");
421 #endif
422 return -1;
423 }
424 #ifdef OFW_DEBUG
425 printf("%d\n", args.status);
426 #endif
427 return args.status;
428 }
429
430 void *
431 OF_claim(virt, size, align)
432 void *virt;
433 u_int size;
434 u_int align;
435 {
436 static struct {
437 char *name;
438 int nargs;
439 int nreturns;
440 void *virt;
441 u_int size;
442 u_int align;
443 void *baseaddr;
444 } args = {
445 "claim",
446 3,
447 1,
448 };
449
450 #ifdef OFW_DEBUG
451 printf("OF_claim(%x, %x, %x) -> ", virt, size, align);
452 #endif
453 args.virt = virt;
454 args.size = size;
455 args.align = align;
456 if (openfirmware(&args) == -1) {
457 #ifdef OFW_DEBUG
458 printf("lose\n");
459 #endif
460 return (void *)-1;
461 }
462 #ifdef OFW_DEBUG
463 printf("%x\n", args.baseaddr);
464 #endif
465 return args.baseaddr;
466 }
467
468 void
469 OF_release(virt, size)
470 void *virt;
471 u_int size;
472 {
473 static struct {
474 char *name;
475 int nargs;
476 int nreturns;
477 void *virt;
478 u_int size;
479 } args = {
480 "release",
481 2,
482 0,
483 };
484
485 #ifdef OFW_DEBUG
486 printf("OF_release(%x, %x)\n", virt, size);
487 #endif
488 args.virt = virt;
489 args.size = size;
490 openfirmware(&args);
491 }
492
493 int
494 OF_milliseconds()
495 {
496 static struct {
497 char *name;
498 int nargs;
499 int nreturns;
500 int ms;
501 } args = {
502 "milliseconds",
503 0,
504 1,
505 };
506
507 openfirmware(&args);
508 return args.ms;
509 }
510
511 #ifdef __notyet__
512 void
513 OF_chain(virt, size, entry, arg, len)
514 void *virt;
515 u_int size;
516 void (*entry)();
517 void *arg;
518 u_int len;
519 {
520 static struct {
521 char *name;
522 int nargs;
523 int nreturns;
524 void *virt;
525 u_int size;
526 void (*entry)();
527 void *arg;
528 u_int len;
529 } args = {
530 "chain",
531 5,
532 0,
533 };
534
535 args.virt = virt;
536 args.size = size;
537 args.entry = entry;
538 args.arg = arg;
539 args.len = len;
540 openfirmware(&args);
541 }
542 #else
543 void
544 OF_chain(virt, size, entry, arg, len)
545 void *virt;
546 u_int size;
547 void (*entry)();
548 void *arg;
549 u_int len;
550 {
551 /*
552 * This is a REALLY dirty hack till the firmware gets this going
553 */
554 #if 0
555 OF_release(virt, size);
556 #endif
557 entry(0, 0, openfirmware, arg, len);
558 }
559 #endif
560
561 int
562 #ifdef __STDC__
563 OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...)
564 #else
565 OF_call_method(method, ihandle, nargs, nreturns, va_alist)
566 char *method;
567 int ihandle;
568 int nargs;
569 int nreturns;
570 va_dcl
571 #endif
572 {
573 va_list ap;
574 static struct {
575 char *name;
576 int nargs;
577 int nreturns;
578 char *method;
579 int ihandle;
580 int args_n_results[12];
581 } args = {
582 "call-method",
583 2,
584 1,
585 };
586 int *ip, n;
587
588 if (nargs > 6)
589 return -1;
590 args.nargs = nargs + 2;
591 args.nreturns = nreturns + 1;
592 args.method = method;
593 args.ihandle = ihandle;
594 va_start(ap, nreturns);
595 for (ip = args.args_n_results + (n = nargs); --n >= 0;)
596 *--ip = va_arg(ap, int);
597
598 if (openfirmware(&args) == -1) {
599 va_end(ap);
600 return -1;
601 }
602 if (args.args_n_results[nargs]) {
603 va_end(ap);
604 return args.args_n_results[nargs];
605 }
606 for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
607 *va_arg(ap, int *) = *--ip;
608 va_end(ap);
609 return 0;
610 }
611
612 static int stdin;
613 static int stdout;
614
615 static void
616 setup()
617 {
618 int chosen;
619
620 if ((chosen = OF_finddevice("/chosen")) == -1)
621 OF_exit();
622 if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) !=
623 sizeof(stdin) ||
624 OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
625 sizeof(stdout))
626 OF_exit();
627 }
628
629 void
630 putchar(c)
631 int c;
632 {
633 char ch = c;
634
635 if (c == '\n')
636 putchar('\r');
637 OF_write(stdout, &ch, 1);
638 }
639
640 int
641 getchar()
642 {
643 unsigned char ch = '\0';
644 int l;
645
646 while ((l = OF_read(stdin, &ch, 1)) != 1)
647 if (l != -2 && l != 0)
648 return -1;
649 return ch;
650 }
651