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