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