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