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