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