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