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