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