Annotation of sys/arch/sparc64/stand/ofwboot/Locore.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: Locore.c,v 1.7 2007/01/16 14:39:57 tsi Exp $ */
2: /* $NetBSD: Locore.c,v 1.1 2000/08/20 14:58:36 mrg 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 "openfirm.h"
37:
38: #include <machine/cpu.h>
39:
40: static vaddr_t OF_claim_virt(vaddr_t vaddr, int len);
41: static vaddr_t OF_alloc_virt(int len, int align);
42: static int OF_free_virt(vaddr_t vaddr, int len);
43: static vaddr_t OF_map_phys(paddr_t paddr, off_t size, vaddr_t vaddr, int mode);
44: static paddr_t OF_alloc_phys(int len, int align);
45: static int OF_free_phys(paddr_t paddr, int len);
46:
47: extern int openfirmware(void *);
48:
49: void setup(void);
50:
51: #if 0
52: #ifdef XCOFF_GLUE
53: asm (".text; .globl _entry; _entry: .long _start,0,0");
54: #endif
55:
56: __dead void
57: _start(vpd, res, openfirm, arg, argl)
58: void *vpd;
59: int res;
60: int (*openfirm)(void *);
61: char *arg;
62: int argl;
63: {
64: extern char etext[];
65:
66: #ifdef FIRMWORKSBUGS
67: syncicache((void *)RELOC, etext - (char *)RELOC);
68: #endif
69: openfirmware = openfirm; /* Save entry to Open Firmware */
70: setup();
71: main(arg, argl);
72: exit();
73: }
74: #endif
75:
76: __dead void
77: _rtt()
78: {
79: struct {
80: cell_t name;
81: cell_t nargs;
82: cell_t nreturns;
83: } args;
84:
85: args.name = ADR2CELL("exit");
86: args.nargs = 0;
87: args.nreturns = 0;
88: openfirmware(&args);
89: while (1); /* just in case */
90: }
91:
92: void
93: OF_enter()
94: {
95: struct {
96: cell_t name;
97: cell_t nargs;
98: cell_t nreturns;
99: } args;
100:
101: args.name = ADR2CELL("enter");
102: args.nargs = 0;
103: args.nreturns = 0;
104: openfirmware(&args);
105: }
106:
107: int
108: OF_finddevice(name)
109: char *name;
110: {
111: struct {
112: cell_t name;
113: cell_t nargs;
114: cell_t nreturns;
115: cell_t device;
116: cell_t phandle;
117: } args;
118:
119: args.name = ADR2CELL("finddevice");
120: args.nargs = 1;
121: args.nreturns = 1;
122: args.device = ADR2CELL(name);
123: if (openfirmware(&args) == -1)
124: return -1;
125: return args.phandle;
126: }
127:
128: int
129: OF_instance_to_package(ihandle)
130: int ihandle;
131: {
132: struct {
133: cell_t name;
134: cell_t nargs;
135: cell_t nreturns;
136: cell_t ihandle;
137: cell_t phandle;
138: } args;
139:
140: args.name = ADR2CELL("instance-to-package");
141: args.nargs = 1;
142: args.nreturns = 1;
143: args.ihandle = HDL2CELL(ihandle);
144: if (openfirmware(&args) == -1)
145: return -1;
146: return args.phandle;
147: }
148:
149: int
150: OF_getprop(handle, prop, buf, buflen)
151: int handle;
152: char *prop;
153: void *buf;
154: int buflen;
155: {
156: struct {
157: cell_t name;
158: cell_t nargs;
159: cell_t nreturns;
160: cell_t phandle;
161: cell_t prop;
162: cell_t buf;
163: cell_t buflen;
164: cell_t size;
165: } args;
166:
167: args.name = ADR2CELL("getprop");
168: args.nargs = 4;
169: args.nreturns = 1;
170: args.phandle = HDL2CELL(handle);
171: args.prop = ADR2CELL(prop);
172: args.buf = ADR2CELL(buf);
173: args.buflen = buflen;
174: if (openfirmware(&args) == -1)
175: return -1;
176: return args.size;
177: }
178:
179: #ifdef __notyet__ /* Has a bug on FirePower */
180: int
181: OF_setprop(handle, prop, buf, len)
182: u_int handle;
183: char *prop;
184: void *buf;
185: int len;
186: {
187: struct {
188: cell_t name;
189: cell_t nargs;
190: cell_t nreturns;
191: cell_t phandle;
192: cell_t prop;
193: cell_t buf;
194: cell_t len;
195: cell_t size;
196: } args;
197:
198: args.name = ADR2CELL("setprop");
199: args.nargs = 4;
200: args.nreturns = 1;
201: args.phandle = HDL2CELL(handle);
202: args.prop = ADR2CELL(prop);
203: args.buf = ADR2CELL(buf);
204: args.len = len;
205: if (openfirmware(&args) == -1)
206: return -1;
207: return args.size;
208: }
209: #endif
210:
211: int
212: OF_open(dname)
213: char *dname;
214: {
215: struct {
216: cell_t name;
217: cell_t nargs;
218: cell_t nreturns;
219: cell_t dname;
220: cell_t handle;
221: } args;
222:
223: args.name = ADR2CELL("open");
224: args.nargs = 1;
225: args.nreturns = 1;
226: args.dname = ADR2CELL(dname);
227: if (openfirmware(&args) == -1 ||
228: args.handle == 0)
229: return -1;
230: return args.handle;
231: }
232:
233: void
234: OF_close(handle)
235: int handle;
236: {
237: struct {
238: cell_t name;
239: cell_t nargs;
240: cell_t nreturns;
241: cell_t handle;
242: } args;
243:
244: args.name = ADR2CELL("close");
245: args.nargs = 1;
246: args.nreturns = 1;
247: args.handle = HDL2CELL(handle);
248: openfirmware(&args);
249: }
250:
251: int
252: OF_write(handle, addr, len)
253: int handle;
254: void *addr;
255: int len;
256: {
257: struct {
258: cell_t name;
259: cell_t nargs;
260: cell_t nreturns;
261: cell_t ihandle;
262: cell_t addr;
263: cell_t len;
264: cell_t actual;
265: } args;
266:
267: args.name = ADR2CELL("write");
268: args.nargs = 3;
269: args.nreturns = 1;
270: args.ihandle = HDL2CELL(handle);
271: args.addr = ADR2CELL(addr);
272: args.len = len;
273: if (openfirmware(&args) == -1)
274: return -1;
275: return args.actual;
276: }
277:
278: int
279: OF_read(handle, addr, len)
280: int handle;
281: void *addr;
282: int len;
283: {
284: struct {
285: cell_t name;
286: cell_t nargs;
287: cell_t nreturns;
288: cell_t ihandle;
289: cell_t addr;
290: cell_t len;
291: cell_t actual;
292: } args;
293:
294: args.name = ADR2CELL("read");
295: args.nargs = 3;
296: args.nreturns = 1;
297: args.ihandle = HDL2CELL(handle);
298: args.addr = ADR2CELL(addr);
299: args.len = len;
300: if (openfirmware(&args) == -1) {
301: return -1;
302: }
303: return args.actual;
304: }
305:
306: int
307: OF_seek(handle, pos)
308: int handle;
309: u_quad_t pos;
310: {
311: struct {
312: cell_t name;
313: cell_t nargs;
314: cell_t nreturns;
315: cell_t handle;
316: cell_t poshi;
317: cell_t poslo;
318: cell_t status;
319: } args;
320:
321: args.name = ADR2CELL("seek");
322: args.nargs = 3;
323: args.nreturns = 1;
324: args.handle = HDL2CELL(handle);
325: args.poshi = HDQ2CELL_HI(pos);
326: args.poslo = HDQ2CELL_LO(pos);
327: if (openfirmware(&args) == -1) {
328: return -1;
329: }
330: return args.status;
331: }
332:
333: void
334: OF_release(virt, size)
335: void *virt;
336: u_int size;
337: {
338: struct {
339: cell_t name;
340: cell_t nargs;
341: cell_t nreturns;
342: cell_t virt;
343: cell_t size;
344: } args;
345:
346: args.name = ADR2CELL("release");
347: args.nargs = 2;
348: args.nreturns = 0;
349: args.virt = ADR2CELL(virt);
350: args.size = size;
351: openfirmware(&args);
352: }
353:
354: int
355: OF_milliseconds()
356: {
357: struct {
358: cell_t name;
359: cell_t nargs;
360: cell_t nreturns;
361: cell_t ms;
362: } args;
363:
364: args.name = ADR2CELL("milliseconds");
365: args.nargs = 0;
366: args.nreturns = 1;
367: openfirmware(&args);
368: return args.ms;
369: }
370:
371: void
372: OF_chain(virt, size, entry, arg, len)
373: void *virt;
374: u_int size;
375: void (*entry)();
376: void *arg;
377: u_int len;
378: {
379: extern int64_t romp;
380: extern int debug;
381: struct {
382: cell_t name;
383: cell_t nargs;
384: cell_t nreturns;
385: cell_t virt;
386: cell_t size;
387: cell_t entry;
388: cell_t arg;
389: cell_t len;
390: } args;
391:
392: args.name = ADR2CELL("chain");
393: args.nargs = 5;
394: args.nreturns = 0;
395: args.virt = ADR2CELL(virt);
396: args.size = size;
397: args.entry = ADR2CELL(entry);
398: args.arg = ADR2CELL(arg);
399: args.len = len;
400: openfirmware(&args);
401: if (debug) {
402: printf("OF_chain: prom returned!\n");
403:
404: /* OK, firmware failed us. Try calling prog directly */
405: printf("Calling entry(0, %p, %x, %lx, %lx)\n", arg, len,
406: (unsigned long)romp, (unsigned long)romp);
407: }
408: entry(0, arg, len, (unsigned long)romp, (unsigned long)romp);
409: panic("OF_chain: kernel returned!");
410: __asm("ta 2" : :);
411: }
412:
413: static u_int stdin;
414: static u_int stdout;
415: static u_int mmuh = -1;
416: static u_int memh = -1;
417:
418: void
419: setup()
420: {
421: u_int chosen;
422:
423: if ((chosen = OF_finddevice("/chosen")) == -1)
424: _rtt();
425: if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != sizeof(stdin)
426: || OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) != sizeof(stdout)
427: || OF_getprop(chosen, "mmu", &mmuh, sizeof(mmuh)) != sizeof(mmuh)
428: || OF_getprop(chosen, "memory", &memh, sizeof(memh)) != sizeof(memh))
429: _rtt();
430: }
431:
432: /*
433: * The following need either the handle to memory or the handle to the MMU.
434: */
435:
436: /*
437: * Grab some address space from the prom
438: *
439: * Only works while the prom is actively mapping us.
440: */
441: static vaddr_t
442: OF_claim_virt(vaddr, len)
443: vaddr_t vaddr;
444: int len;
445: {
446: struct {
447: cell_t name;
448: cell_t nargs;
449: cell_t nreturns;
450: cell_t method;
451: cell_t ihandle;
452: cell_t align;
453: cell_t len;
454: cell_t vaddr;
455: cell_t status;
456: cell_t retaddr;
457: } args;
458:
459: #ifdef __notyet
460: if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
461: printf("OF_claim_virt: cannot get mmuh\r\n");
462: return -1LL;
463: }
464: #endif
465: args.name = ADR2CELL("call-method");
466: args.nargs = 5;
467: args.nreturns = 2;
468: args.method = ADR2CELL("claim");
469: args.ihandle = HDL2CELL(mmuh);
470: args.align = 0;
471: args.len = len;
472: args.vaddr = ADR2CELL(vaddr);
473: if (openfirmware(&args) != 0)
474: return -1LL;
475: return (vaddr_t)args.retaddr;
476: }
477:
478: /*
479: * Request some address space from the prom
480: *
481: * Only works while the prom is actively mapping us.
482: */
483: static vaddr_t
484: OF_alloc_virt(len, align)
485: int len;
486: int align;
487: {
488: int retaddr=-1;
489: struct {
490: cell_t name;
491: cell_t nargs;
492: cell_t nreturns;
493: cell_t method;
494: cell_t ihandle;
495: cell_t align;
496: cell_t len;
497: cell_t status;
498: cell_t retaddr;
499: } args;
500:
501: #ifdef __notyet
502: if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
503: printf("OF_alloc_virt: cannot get mmuh\r\n");
504: return -1LL;
505: }
506: #endif
507: args.name = ADR2CELL("call-method");
508: args.nargs = 4;
509: args.nreturns = 2;
510: args.method = ADR2CELL("claim");
511: args.ihandle = HDL2CELL(mmuh);
512: args.align = align;
513: args.len = len;
514: args.retaddr = ADR2CELL(&retaddr);
515: if (openfirmware(&args) != 0)
516: return -1LL;
517: return (vaddr_t)args.retaddr;
518: }
519:
520: /*
521: * Release some address space to the prom
522: *
523: * Only works while the prom is actively mapping us.
524: */
525: static int
526: OF_free_virt(vaddr, len)
527: vaddr_t vaddr;
528: int len;
529: {
530: struct {
531: cell_t name;
532: cell_t nargs;
533: cell_t nreturns;
534: cell_t method;
535: cell_t ihandle;
536: cell_t len;
537: cell_t vaddr;
538: } args;
539:
540: #ifdef __notyet
541: if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
542: printf("OF_free_virt: cannot get mmuh\r\n");
543: return -1;
544: }
545: #endif
546: args.name = ADR2CELL("call-method");
547: args.nargs = 4;
548: args.nreturns = 0;
549: args.method = ADR2CELL("release");
550: args.ihandle = HDL2CELL(mmuh);
551: args.vaddr = ADR2CELL(vaddr);
552: args.len = len;
553: return openfirmware(&args);
554: }
555:
556:
557: /*
558: * Have prom map in some memory
559: *
560: * Only works while the prom is actively mapping us.
561: */
562: static vaddr_t
563: OF_map_phys(paddr, size, vaddr, mode)
564: paddr_t paddr;
565: off_t size;
566: vaddr_t vaddr;
567: int mode;
568: {
569: struct {
570: cell_t name;
571: cell_t nargs;
572: cell_t nreturns;
573: cell_t method;
574: cell_t ihandle;
575: cell_t mode;
576: cell_t size;
577: cell_t vaddr;
578: cell_t paddr_hi;
579: cell_t paddr_lo;
580: cell_t status;
581: cell_t retaddr;
582: } args;
583:
584: #ifdef __notyet
585: if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
586: printf("OF_map_phys: cannot get mmuh\r\n");
587: return 0LL;
588: }
589: #endif
590: args.name = ADR2CELL("call-method");
591: args.nargs = 7;
592: args.nreturns = 1;
593: args.method = ADR2CELL("map");
594: args.ihandle = HDL2CELL(mmuh);
595: args.mode = mode;
596: args.size = size;
597: args.vaddr = ADR2CELL(vaddr);
598: args.paddr_hi = HDQ2CELL_HI(paddr);
599: args.paddr_lo = HDQ2CELL_LO(paddr);
600:
601: if (openfirmware(&args) == -1)
602: return -1;
603: if (args.status)
604: return -1;
605: return (vaddr_t)args.retaddr;
606: }
607:
608:
609: /*
610: * Request some RAM from the prom
611: *
612: * Only works while the prom is actively mapping us.
613: */
614: static paddr_t
615: OF_alloc_phys(len, align)
616: int len;
617: int align;
618: {
619: struct {
620: cell_t name;
621: cell_t nargs;
622: cell_t nreturns;
623: cell_t method;
624: cell_t ihandle;
625: cell_t align;
626: cell_t len;
627: cell_t status;
628: cell_t phys_hi;
629: cell_t phys_lo;
630: } args;
631:
632: #ifdef __notyet
633: if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
634: printf("OF_alloc_phys: cannot get memh\r\n");
635: return -1LL;
636: }
637: #endif
638: args.name = ADR2CELL("call-method");
639: args.nargs = 4;
640: args.nreturns = 3;
641: args.method = ADR2CELL("claim");
642: args.ihandle = HDL2CELL(memh);
643: args.align = align;
644: args.len = len;
645: if (openfirmware(&args) != 0)
646: return -1LL;
647: return (paddr_t)CELL2HDQ(args.phys_hi, args.phys_lo);
648: }
649:
650:
651: /*
652: * Free some RAM to prom
653: *
654: * Only works while the prom is actively mapping us.
655: */
656: static int
657: OF_free_phys(phys, len)
658: paddr_t phys;
659: int len;
660: {
661: struct {
662: cell_t name;
663: cell_t nargs;
664: cell_t nreturns;
665: cell_t method;
666: cell_t ihandle;
667: cell_t len;
668: cell_t phys_hi;
669: cell_t phys_lo;
670: } args;
671:
672: #ifdef __notyet
673: if (memh == -1 && ((memh = get_memory_handle()) == -1)) {
674: printf("OF_free_phys: cannot get memh\r\n");
675: return -1;
676: }
677: #endif
678: args.name = ADR2CELL("call-method");
679: args.nargs = 5;
680: args.nreturns = 0;
681: args.method = ADR2CELL("release");
682: args.ihandle = HDL2CELL(memh);
683: args.len = len;
684: args.phys_hi = HDQ2CELL_HI(phys);
685: args.phys_lo = HDQ2CELL_LO(phys);
686: return openfirmware(&args);
687: }
688:
689:
690: /*
691: * Claim virtual memory -- does not map it in.
692: */
693:
694: void *
695: OF_claim(virt, size, align)
696: void *virt;
697: u_int size;
698: u_int align;
699: {
700: #define SUNVMOF
701: #ifndef SUNVMOF
702: struct {
703: cell_t name;
704: cell_t nargs;
705: cell_t nreturns;
706: cell_t virt;
707: cell_t size;
708: cell_t align;
709: cell_t baseaddr;
710: } args;
711:
712:
713: args.name = ADR2CELL("claim");
714: args.nargs = 3;
715: args.nreturns = 1;
716: args.virt = virt;
717: args.size = size;
718: args.align = align;
719: if (openfirmware(&args) == -1)
720: return (void *)-1;
721: return (void *)args.baseaddr;
722: #else
723: /*
724: * Sun Ultra machines run the firmware with VM enabled,
725: * so you need to handle allocating and mapping both
726: * virtual and physical memory. Ugh.
727: */
728:
729: paddr_t paddr;
730: void * newvirt = NULL;
731:
732: if (virt == NULL) {
733: virt = (void *)OF_alloc_virt(size, align);
734: if (virt == (void *)-1LL) {
735: printf("OF_alloc_virt(%d,%d) failed w/%x\n",
736: size, align, virt);
737: return virt;
738: }
739: } else {
740: newvirt = (void *)OF_claim_virt((vaddr_t)virt, size);
741: if (newvirt == (void *)-1LL) {
742: printf("OF_claim_virt(%x,%d) failed w/%x\n",
743: virt, size, newvirt);
744: return newvirt;
745: }
746: virt = newvirt;
747: }
748: if ((paddr = OF_alloc_phys(size, align)) == (paddr_t)-1LL) {
749: printf("OF_alloc_phys(%d,%d) failed\n", size, align);
750: OF_free_virt((vaddr_t)virt, size);
751: return (void *)-1LL;
752: }
753: if (OF_map_phys(paddr, size, (vaddr_t)virt, -1) == -1) {
754: printf("OF_map_phys(%x,%d,%x,%d) failed\n",
755: paddr, size, virt, -1);
756: OF_free_phys((paddr_t)paddr, size);
757: OF_free_virt((vaddr_t)virt, size);
758: return (void *)-1LL;
759: }
760: return virt;
761: #endif
762: }
763:
764:
765: void
766: putchar(c)
767: int c;
768: {
769: char ch = c;
770:
771: if (c == '\n')
772: putchar('\r');
773: OF_write(stdout, &ch, 1);
774: }
775:
776: int
777: getchar()
778: {
779: unsigned char ch = '\0';
780: int l;
781:
782: while ((l = OF_read(stdin, &ch, 1)) != 1)
783: if (l != -2 && l != 0)
784: return -1;
785: return ch;
786: }
CVSweb