Annotation of sys/arch/macppc/stand/Locore.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: Locore.c,v 1.13 2007/06/23 18:51:45 drahn Exp $ */
2: /* $NetBSD: Locore.c,v 1.1 1997/04/16 20:29:11 thorpej Exp $ */
3:
4: /*
5: * Copyright (C) 1995, 1996 Wolfgang Solfrank.
6: * Copyright (C) 1995, 1996 TooLs GmbH.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by TooLs GmbH.
20: * 4. The name of TooLs GmbH may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33: */
34:
35: #include <lib/libsa/stand.h>
36: #include <macppc/stand/openfirm.h>
37: #include <dev/cons.h>
38:
39:
40: /*
41: #include "machine/cpu.h"
42: */
43:
44: #define ENABLE_DECREMENTER_WORKAROUND
45:
46: static int (*openfirmware)(void *);
47:
48: static void setup(void);
49:
50: asm (".text; .globl _entry; _entry: .long _start,0,0");
51: asm(" .text \n"
52: " .globl bat_init \n"
53: "bat_init: \n"
54: " \n"
55: " mfmsr 8 \n"
56: " li 0,0 \n"
57: " mtmsr 0 \n"
58: " isync \n"
59: " \n"
60: " mtibatu 0,0 \n"
61: " mtibatu 1,0 \n"
62: " mtibatu 2,0 \n"
63: " mtibatu 3,0 \n"
64: " mtdbatu 0,0 \n"
65: " mtdbatu 1,0 \n"
66: " mtdbatu 2,0 \n"
67: " mtdbatu 3,0 \n"
68: " \n"
69: " li 9,0x12 \n" /* BATL(0, BAT_M, BAT_PP_RW) */
70: " mtibatl 0,9 \n"
71: " mtdbatl 0,9 \n"
72: " li 9,0x1ffe \n" /* BATU(0, BAT_BL_256M, BAT_Vs) */
73: " mtibatu 0,9 \n"
74: " mtdbatu 0,9 \n"
75: " isync \n"
76: " \n"
77: " mtmsr 8 \n"
78: " isync \n"
79: " blr \n");
80:
81: #ifdef XCOFF_GLUE
82: static int stack[8192/4 + 4] __attribute__((__used__));
83: #endif
84:
85: __dead void
86: _start(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl)
87: {
88: extern char etext[];
89:
90: #ifdef XCOFF_GLUE
91: asm(
92: "sync \n"
93: "isync \n"
94: "lis %r1,stack@ha \n"
95: "addi %r1,%r1,stack@l \n"
96: "addi %r1,%r1,8192 \n");
97: #endif
98: syncicache((void *)RELOC, etext - (char *)RELOC);
99:
100: bat_init();
101: openfirmware = openfirm; /* Save entry to Open Firmware */
102: #ifdef ENABLE_DECREMENTER_WORKAROUND
103: patch_dec_intr();
104: #endif
105: setup();
106: main(arg, argl);
107: exit();
108: }
109:
110: #ifdef ENABLE_DECREMENTER_WORKAROUND
111: void handle_decr_intr();
112: __asm ( " .globl handle_decr_intr\n"
113: " .type handle_decr_intr@function\n"
114: "handle_decr_intr:\n"
115: " rfi\n");
116:
117:
118: patch_dec_intr()
119: {
120: int time;
121: unsigned int *decr_intr = (unsigned int *)0x900;
122: unsigned int br_instr;
123:
124: /* this hack is to prevent unexpected Decrementer Exceptions
125: * when Apple openfirmware enables interrupts
126: */
127: time = 0x40000000;
128: asm("mtdec %0" :: "r"(time));
129:
130: /* we assume that handle_decr_intr is in the first 128 Meg */
131: br_instr = (18 << 23) | (unsigned int)handle_decr_intr;
132: *decr_intr = br_instr;
133: }
134: #endif
135:
136: __dead void
137: _rtt()
138: {
139: static struct {
140: char *name;
141: int nargs;
142: int nreturns;
143: } args = {
144: "exit",
145: 0,
146: 0
147: };
148:
149: openfirmware(&args);
150: while (1); /* just in case */
151: }
152:
153: int
154: OF_finddevice(char *name)
155: {
156: static struct {
157: char *name;
158: int nargs;
159: int nreturns;
160: char *device;
161: int phandle;
162: } args = {
163: "finddevice",
164: 1,
165: 1,
166: };
167:
168: args.device = name;
169: if (openfirmware(&args) == -1)
170: return -1;
171: return args.phandle;
172: }
173:
174: int
175: OF_instance_to_package(int ihandle)
176: {
177: static struct {
178: char *name;
179: int nargs;
180: int nreturns;
181: int ihandle;
182: int phandle;
183: } args = {
184: "instance-to-package",
185: 1,
186: 1,
187: };
188:
189: args.ihandle = ihandle;
190: if (openfirmware(&args) == -1)
191: return -1;
192: return args.phandle;
193: }
194:
195: int
196: OF_getprop(int handle, char *prop, void *buf, int buflen)
197: {
198: static struct {
199: char *name;
200: int nargs;
201: int nreturns;
202: int phandle;
203: char *prop;
204: void *buf;
205: int buflen;
206: int size;
207: } args = {
208: "getprop",
209: 4,
210: 1,
211: };
212:
213: args.phandle = handle;
214: args.prop = prop;
215: args.buf = buf;
216: args.buflen = buflen;
217: if (openfirmware(&args) == -1)
218: return -1;
219: return args.size;
220: }
221:
222: int
223: OF_open(char *dname)
224: {
225: static struct {
226: char *name;
227: int nargs;
228: int nreturns;
229: char *dname;
230: int handle;
231: } args = {
232: "open",
233: 1,
234: 1,
235: };
236:
237: args.dname = dname;
238: if (openfirmware(&args) == -1)
239: return -1;
240: return args.handle;
241: }
242:
243: void
244: OF_close(int handle)
245: {
246: static struct {
247: char *name;
248: int nargs;
249: int nreturns;
250: int handle;
251: } args = {
252: "close",
253: 1,
254: 0,
255: };
256:
257: args.handle = handle;
258: openfirmware(&args);
259: }
260:
261: int
262: OF_write(int handle, void *addr, int len)
263: {
264: static struct {
265: char *name;
266: int nargs;
267: int nreturns;
268: int ihandle;
269: void *addr;
270: int len;
271: int actual;
272: } args = {
273: "write",
274: 3,
275: 1,
276: };
277:
278: args.ihandle = handle;
279: args.addr = addr;
280: args.len = len;
281: if (openfirmware(&args) == -1)
282: return -1;
283: return args.actual;
284: }
285:
286: int
287: OF_read(int handle, void *addr, int len)
288: {
289: static struct {
290: char *name;
291: int nargs;
292: int nreturns;
293: int ihandle;
294: void *addr;
295: int len;
296: int actual;
297: } args = {
298: "read",
299: 3,
300: 1,
301: };
302:
303: args.ihandle = handle;
304: args.addr = addr;
305: args.len = len;
306: if (openfirmware(&args) == -1)
307: return -1;
308: return args.actual;
309: }
310:
311: int
312: OF_seek(int handle, u_quad_t pos)
313: {
314: static struct {
315: char *name;
316: int nargs;
317: int nreturns;
318: int handle;
319: int poshi;
320: int poslo;
321: int status;
322: } args = {
323: "seek",
324: 3,
325: 1,
326: };
327:
328: args.handle = handle;
329: args.poshi = (int)(pos >> 32);
330: args.poslo = (int)pos;
331: if (openfirmware(&args) == -1)
332: return -1;
333: return args.status;
334: }
335:
336: void *
337: OF_claim(void *virt, u_int size, u_int align)
338: {
339: static struct {
340: char *name;
341: int nargs;
342: int nreturns;
343: void *virt;
344: u_int size;
345: u_int align;
346: void *baseaddr;
347: } args = {
348: "claim",
349: 3,
350: 1,
351: };
352:
353: args.virt = virt;
354: args.size = size;
355: args.align = align;
356: if (openfirmware(&args) == -1)
357: return (void *)-1;
358: if (virt != 0)
359: return virt;
360: return args.baseaddr;
361: }
362:
363: void
364: OF_release(void *virt, u_int size)
365: {
366: static struct {
367: char *name;
368: int nargs;
369: int nreturns;
370: void *virt;
371: u_int size;
372: } args = {
373: "release",
374: 2,
375: 0,
376: };
377:
378: args.virt = virt;
379: args.size = size;
380: openfirmware(&args);
381: }
382:
383: int
384: OF_milliseconds()
385: {
386: static struct {
387: char *name;
388: int nargs;
389: int nreturns;
390: int ms;
391: } args = {
392: "milliseconds",
393: 0,
394: 1,
395: };
396:
397: openfirmware(&args);
398: return args.ms;
399: }
400:
401: #ifdef __notyet__
402: void
403: OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
404: {
405: static struct {
406: char *name;
407: int nargs;
408: int nreturns;
409: void *virt;
410: u_int size;
411: void (*entry)();
412: void *arg;
413: u_int len;
414: } args = {
415: "chain",
416: 5,
417: 0,
418: };
419:
420: args.virt = virt;
421: args.size = size;
422: args.entry = entry;
423: args.arg = arg;
424: args.len = len;
425: openfirmware(&args);
426: }
427: #else
428: void
429: OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
430: {
431: /*
432: * This is a REALLY dirty hack till the firmware gets this going
433: OF_release(virt, size);
434: */
435: entry(0, 0, openfirmware, arg, len);
436: }
437: #endif
438:
439: int
440: OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...)
441: {
442: va_list ap;
443: static struct {
444: char *name;
445: int nargs;
446: int nreturns;
447: char *method;
448: int ihandle;
449: int args_n_results[12];
450: } args = {
451: "call-method",
452: 2,
453: 1,
454: };
455: int *ip, n;
456:
457: if (nargs > 6)
458: return -1;
459: args.nargs = nargs + 2;
460: args.nreturns = nreturns + 1;
461: args.method = method;
462: args.ihandle = ihandle;
463: va_start(ap, nreturns);
464: for (ip = args.args_n_results + (n = nargs); --n >= 0;)
465: *--ip = va_arg(ap, int);
466:
467: if (openfirmware(&args) == -1) {
468: va_end(ap);
469: return -1;
470: }
471: if (args.args_n_results[nargs]) {
472: va_end(ap);
473: return args.args_n_results[nargs];
474: }
475: for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
476: *va_arg(ap, int *) = *--ip;
477: va_end(ap);
478: return 0;
479: }
480:
481: static int stdin;
482: static int stdout;
483:
484: static void
485: setup()
486: {
487: int chosen;
488:
489: if ((chosen = OF_finddevice("/chosen")) == -1)
490: _rtt();
491: if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != sizeof(stdin)
492: || OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
493: sizeof(stdout))
494: _rtt();
495: if (stdout == 0) {
496: /* screen should be console, but it is not open */
497: stdout = OF_open("screen");
498: }
499: }
500:
501: void
502: putchar(int c)
503: {
504: char ch = c;
505: if (c == '\177') {
506: ch = '\b';
507: OF_write(stdout, &ch, 1);
508: ch = ' ';
509: OF_write(stdout, &ch, 1);
510: ch = '\b';
511: }
512: if (c == '\n')
513: putchar('\r');
514: OF_write(stdout, &ch, 1);
515: }
516:
517: int
518: getchar()
519: {
520: int c = cngetc();
521:
522: if (c == '\r')
523: c = '\n';
524:
525: if ((c < ' ' && c != '\n') || c == '\177')
526: return(c);
527:
528: putchar(c);
529:
530: return(c);
531: }
532:
533: void
534: ofc_probe(struct consdev *cn)
535: {
536: cn->cn_pri = CN_NORMAL;
537: cn->cn_dev = makedev(0,0); /* WTF */
538: }
539:
540:
541: void
542: ofc_init(struct consdev *cn)
543: {
544: }
545:
546: char buffered_char;
547: int
548: ofc_getc(dev_t dev)
549: {
550: u_int8_t ch;
551: int l;
552:
553: if (dev & 0x80) {
554: if (buffered_char != 0)
555: return 1;
556:
557: l = OF_read(stdin, &ch, 1);
558: if (l == 1) {
559: buffered_char = ch;
560: return 1;
561: }
562: return 0;
563: }
564:
565: if (buffered_char != 0) {
566: ch = buffered_char;
567: buffered_char = 0;
568: return ch;
569: }
570:
571: while ((l = OF_read(stdin, &ch, 1)) != 1)
572: if (l != -2 && l != 0)
573: return 0;
574: return ch;
575:
576: }
577:
578: void
579: ofc_putc(dev_t dev, int c)
580: {
581: char ch;
582:
583: ch = 'a';
584: OF_write(stdout, &ch, 1);
585: ch = c;
586: if (c == '\177' && c == '\b') {
587: ch = 'A';
588: }
589: OF_write(stdout, &ch, 1);
590: }
591:
592:
593: void
594: machdep()
595: {
596: cninit();
597: }
CVSweb