|
|
1.1 root 1: /* tag: openbios forth environment, executable code
2: *
3: * Copyright (C) 2003 Patrick Mauritz, Stefan Reinauer
4: *
5: * See the file "COPYING" for further information about
6: * the copyright and warranty status of this work.
7: */
8:
9: #include "config.h"
10: #include "libopenbios/openbios.h"
11: #include "libopenbios/bindings.h"
12: #include "drivers/drivers.h"
13: #include "asm/types.h"
14: #include "dict.h"
15: #include "kernel/kernel.h"
16: #include "kernel/stack.h"
17: #include "arch/common/nvram.h"
18: #include "packages/nvram.h"
19: #include "../../drivers/timer.h" // XXX
20: #include "libopenbios/sys_info.h"
21: #include "openbios.h"
22: #include "boot.h"
23: #include "romvec.h"
24: #include "openprom.h"
25: #include "packages/video.h"
26: #define NO_QEMU_PROTOS
27: #include "arch/common/fw_cfg.h"
28: #include "libopenbios/ofmem.h"
29:
30: #define MEMORY_SIZE (128*1024) /* 128K ram for hosted system */
31: #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
32: #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
33:
34: static ucell *memory;
35:
36: int qemu_machine_type;
37:
38: struct hwdef {
39: uint64_t iommu_base, slavio_base;
40: uint64_t intctl_base, counter_base, nvram_base, ms_kb_base, serial_base;
41: unsigned long fd_offset, counter_offset, intr_offset;
42: unsigned long aux1_offset, aux2_offset;
43: uint64_t dma_base, esp_base, le_base;
44: uint64_t tcx_base;
45: int mid_offset;
46: int machine_id_low, machine_id_high;
47: };
48:
49: static const struct hwdef hwdefs[] = {
50: /* SS-5 */
51: {
52: .iommu_base = 0x10000000,
53: .tcx_base = 0x50000000,
54: .slavio_base = 0x71000000,
55: .ms_kb_base = 0x71000000,
56: .serial_base = 0x71100000,
57: .nvram_base = 0x71200000,
58: .fd_offset = 0x00400000,
59: .counter_offset = 0x00d00000,
60: .intr_offset = 0x00e00000,
61: .aux1_offset = 0x00900000,
62: .aux2_offset = 0x00910000,
63: .dma_base = 0x78400000,
64: .esp_base = 0x78800000,
65: .le_base = 0x78c00000,
66: .mid_offset = 0,
67: .machine_id_low = 32,
68: .machine_id_high = 63,
69: },
70: /* SS-10 */
71: {
72: .iommu_base = 0xfe0000000ULL,
73: .tcx_base = 0xe20000000ULL,
74: .slavio_base = 0xff1000000ULL,
75: .ms_kb_base = 0xff1000000ULL,
76: .serial_base = 0xff1100000ULL,
77: .nvram_base = 0xff1200000ULL,
78: .fd_offset = 0x00700000, // 0xff1700000ULL,
79: .counter_offset = 0x00300000, // 0xff1300000ULL,
80: .intr_offset = 0x00400000, // 0xff1400000ULL,
81: .aux1_offset = 0x00800000, // 0xff1800000ULL,
82: .aux2_offset = 0x00a01000, // 0xff1a01000ULL,
83: .dma_base = 0xef0400000ULL,
84: .esp_base = 0xef0800000ULL,
85: .le_base = 0xef0c00000ULL,
86: .mid_offset = 8,
87: .machine_id_low = 64,
88: .machine_id_high = 65,
89: },
90: /* SS-600MP */
91: {
92: .iommu_base = 0xfe0000000ULL,
93: .tcx_base = 0xe20000000ULL,
94: .slavio_base = 0xff1000000ULL,
95: .ms_kb_base = 0xff1000000ULL,
96: .serial_base = 0xff1100000ULL,
97: .nvram_base = 0xff1200000ULL,
98: .fd_offset = -1,
99: .counter_offset = 0x00300000, // 0xff1300000ULL,
100: .intr_offset = 0x00400000, // 0xff1400000ULL,
101: .aux1_offset = 0x00800000, // 0xff1800000ULL,
102: .aux2_offset = 0x00a01000, // 0xff1a01000ULL, XXX should not exist
103: .dma_base = 0xef0081000ULL,
104: .esp_base = 0xef0080000ULL,
105: .le_base = 0xef0060000ULL,
106: .mid_offset = 8,
107: .machine_id_low = 66,
108: .machine_id_high = 66,
109: },
110: };
111:
112: static const struct hwdef *hwdef;
113:
114: void setup_timers(void)
115: {
116: }
117:
118: void udelay(unsigned int usecs)
119: {
120: }
121:
122: void mdelay(unsigned int msecs)
123: {
124: }
125:
126: static void mb86904_init(void)
127: {
128: PUSH(32);
129: fword("encode-int");
130: push_str("cache-line-size");
131: fword("property");
132:
133: PUSH(512);
134: fword("encode-int");
135: push_str("cache-nlines");
136: fword("property");
137:
138: PUSH(0x23);
139: fword("encode-int");
140: push_str("mask_rev");
141: fword("property");
142: }
143:
144: static void tms390z55_init(void)
145: {
146: push_str("");
147: fword("encode-string");
148: push_str("ecache-parity?");
149: fword("property");
150:
151: push_str("");
152: fword("encode-string");
153: push_str("bfill?");
154: fword("property");
155:
156: push_str("");
157: fword("encode-string");
158: push_str("bcopy?");
159: fword("property");
160:
161: push_str("");
162: fword("encode-string");
163: push_str("cache-physical?");
164: fword("property");
165:
166: PUSH(0xf);
167: fword("encode-int");
168: PUSH(0xf8fffffc);
169: fword("encode-int");
170: fword("encode+");
171: PUSH(4);
172: fword("encode-int");
173: fword("encode+");
174:
175: PUSH(0xf);
176: fword("encode-int");
177: fword("encode+");
178: PUSH(0xf8c00000);
179: fword("encode-int");
180: fword("encode+");
181: PUSH(0x1000);
182: fword("encode-int");
183: fword("encode+");
184:
185: PUSH(0xf);
186: fword("encode-int");
187: fword("encode+");
188: PUSH(0xf8000000);
189: fword("encode-int");
190: fword("encode+");
191: PUSH(0x1000);
192: fword("encode-int");
193: fword("encode+");
194:
195: PUSH(0xf);
196: fword("encode-int");
197: fword("encode+");
198: PUSH(0xf8800000);
199: fword("encode-int");
200: fword("encode+");
201: PUSH(0x1000);
202: fword("encode-int");
203: fword("encode+");
204: push_str("reg");
205: fword("property");
206: }
207:
208: static void rt625_init(void)
209: {
210: PUSH(32);
211: fword("encode-int");
212: push_str("cache-line-size");
213: fword("property");
214:
215: PUSH(512);
216: fword("encode-int");
217: push_str("cache-nlines");
218: fword("property");
219:
220: }
221:
222: static void bad_cpu_init(void)
223: {
224: printk("This CPU is not supported yet, freezing.\n");
225: for(;;);
226: }
227:
228: struct cpudef {
229: unsigned long iu_version;
230: const char *name;
231: int psr_impl, psr_vers, impl, vers;
232: int dcache_line_size, dcache_lines, dcache_assoc;
233: int icache_line_size, icache_lines, icache_assoc;
234: int ecache_line_size, ecache_lines, ecache_assoc;
235: int mmu_nctx;
236: void (*initfn)(void);
237: };
238:
239: static const struct cpudef sparc_defs[] = {
240: {
241: .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
242: .name = "FMI,MB86900",
243: .initfn = bad_cpu_init,
244: },
245: {
246: .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
247: .name = "FMI,MB86904",
248: .psr_impl = 0,
249: .psr_vers = 5,
250: .impl = 0,
251: .vers = 5,
252: .dcache_line_size = 0x10,
253: .dcache_lines = 0x200,
254: .dcache_assoc = 1,
255: .icache_line_size = 0x20,
256: .icache_lines = 0x200,
257: .icache_assoc = 1,
258: .ecache_line_size = 0x20,
259: .ecache_lines = 0x4000,
260: .ecache_assoc = 1,
261: .mmu_nctx = 0x100,
262: .initfn = mb86904_init,
263: },
264: {
265: .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
266: .name = "FMI,MB86907",
267: .psr_impl = 0,
268: .psr_vers = 5,
269: .impl = 0,
270: .vers = 5,
271: .dcache_line_size = 0x20,
272: .dcache_lines = 0x200,
273: .dcache_assoc = 1,
274: .icache_line_size = 0x20,
275: .icache_lines = 0x200,
276: .icache_assoc = 1,
277: .ecache_line_size = 0x20,
278: .ecache_lines = 0x4000,
279: .ecache_assoc = 1,
280: .mmu_nctx = 0x100,
281: .initfn = mb86904_init,
282: },
283: {
284: .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
285: .name = "LSI,L64811",
286: .initfn = bad_cpu_init,
287: },
288: {
289: .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
290: .name = "CY,CY7C601",
291: .psr_impl = 1,
292: .psr_vers = 1,
293: .impl = 1,
294: .vers = 1,
295: .mmu_nctx = 0x10,
296: .initfn = bad_cpu_init,
297: },
298: {
299: .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
300: .name = "CY,CY7C611",
301: .initfn = bad_cpu_init,
302: },
303: {
304: .iu_version = 0x40000000,
305: .name = "TI,TMS390Z55",
306: .psr_impl = 4,
307: .psr_vers = 0,
308: .impl = 0,
309: .vers = 4,
310: .dcache_line_size = 0x20,
311: .dcache_lines = 0x80,
312: .dcache_assoc = 4,
313: .icache_line_size = 0x40,
314: .icache_lines = 0x40,
315: .icache_assoc = 5,
316: .ecache_line_size = 0x20,
317: .ecache_lines = 0x8000,
318: .ecache_assoc = 1,
319: .mmu_nctx = 0x10000,
320: .initfn = tms390z55_init,
321: },
322: {
323: .iu_version = 0x41000000,
324: .name = "TI,TMS390S10",
325: .psr_impl = 4,
326: .psr_vers = 1,
327: .impl = 4,
328: .vers = 1,
329: .dcache_line_size = 0x10,
330: .dcache_lines = 0x80,
331: .dcache_assoc = 4,
332: .icache_line_size = 0x20,
333: .icache_lines = 0x80,
334: .icache_assoc = 5,
335: .ecache_line_size = 0x20,
336: .ecache_lines = 0x8000,
337: .ecache_assoc = 1,
338: .mmu_nctx = 0x10000,
339: .initfn = tms390z55_init,
340: },
341: {
342: .iu_version = 0x42000000,
343: .name = "TI,TMS390S10",
344: .psr_impl = 4,
345: .psr_vers = 2,
346: .impl = 4,
347: .vers = 2,
348: .dcache_line_size = 0x10,
349: .dcache_lines = 0x80,
350: .dcache_assoc = 4,
351: .icache_line_size = 0x20,
352: .icache_lines = 0x80,
353: .icache_assoc = 5,
354: .ecache_line_size = 0x20,
355: .ecache_lines = 0x8000,
356: .ecache_assoc = 1,
357: .mmu_nctx = 0x10000,
358: .initfn = tms390z55_init,
359: },
360: {
361: .iu_version = 0x43000000,
362: .name = "TI,TMS390S10",
363: .psr_impl = 4,
364: .psr_vers = 3,
365: .impl = 4,
366: .vers = 3,
367: .dcache_line_size = 0x10,
368: .dcache_lines = 0x80,
369: .dcache_assoc = 4,
370: .icache_line_size = 0x20,
371: .icache_lines = 0x80,
372: .icache_assoc = 5,
373: .ecache_line_size = 0x20,
374: .ecache_lines = 0x8000,
375: .ecache_assoc = 1,
376: .mmu_nctx = 0x10000,
377: .initfn = tms390z55_init,
378: },
379: {
380: .iu_version = 0x44000000,
381: .name = "TI,TMS390S10",
382: .psr_impl = 4,
383: .psr_vers = 4,
384: .impl = 4,
385: .vers = 4,
386: .dcache_line_size = 0x10,
387: .dcache_lines = 0x80,
388: .dcache_assoc = 4,
389: .icache_line_size = 0x20,
390: .icache_lines = 0x80,
391: .icache_assoc = 5,
392: .ecache_line_size = 0x20,
393: .ecache_lines = 0x8000,
394: .ecache_assoc = 1,
395: .mmu_nctx = 0x10000,
396: .initfn = tms390z55_init,
397: },
398: {
399: .iu_version = 0x1e000000,
400: .name = "Ross,RT625",
401: .psr_impl = 1,
402: .psr_vers = 14,
403: .impl = 1,
404: .vers = 7,
405: .dcache_line_size = 0x20,
406: .dcache_lines = 0x80,
407: .dcache_assoc = 4,
408: .icache_line_size = 0x40,
409: .icache_lines = 0x40,
410: .icache_assoc = 5,
411: .ecache_line_size = 0x20,
412: .ecache_lines = 0x8000,
413: .ecache_assoc = 1,
414: .mmu_nctx = 0x10000,
415: .initfn = rt625_init,
416: },
417: {
418: .iu_version = 0x1f000000,
419: .name = "Ross,RT620",
420: .psr_impl = 1,
421: .psr_vers = 15,
422: .impl = 1,
423: .vers = 7,
424: .dcache_line_size = 0x20,
425: .dcache_lines = 0x80,
426: .dcache_assoc = 4,
427: .icache_line_size = 0x40,
428: .icache_lines = 0x40,
429: .icache_assoc = 5,
430: .ecache_line_size = 0x20,
431: .ecache_lines = 0x8000,
432: .ecache_assoc = 1,
433: .mmu_nctx = 0x10000,
434: .initfn = rt625_init,
435: },
436: {
437: .iu_version = 0x20000000,
438: .name = "BIT,B5010",
439: .initfn = bad_cpu_init,
440: },
441: {
442: .iu_version = 0x50000000,
443: .name = "MC,MN10501",
444: .initfn = bad_cpu_init,
445: },
446: {
447: .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
448: .name = "Weitek,W8601",
449: .initfn = bad_cpu_init,
450: },
451: {
452: .iu_version = 0xf2000000,
453: .name = "GR,LEON2",
454: .initfn = bad_cpu_init,
455: },
456: {
457: .iu_version = 0xf3000000,
458: .name = "GR,LEON3",
459: .initfn = bad_cpu_init,
460: },
461: };
462:
463: static const struct cpudef *
464: id_cpu(void)
465: {
466: unsigned long iu_version;
467: unsigned int i;
468:
469: asm("rd %%psr, %0\n"
470: : "=r"(iu_version) :);
471: iu_version &= 0xff000000;
472:
473: for (i = 0; i < sizeof(sparc_defs)/sizeof(struct cpudef); i++) {
474: if (iu_version == sparc_defs[i].iu_version)
475: return &sparc_defs[i];
476: }
477: printk("Unknown cpu (psr %lx), freezing!\n", iu_version);
478: for (;;);
479: }
480:
481: static void setup_cpu(int mid_offset)
482: {
483: uint32_t temp;
484: unsigned int i;
485: const struct cpudef *cpu;
486:
487: // Add cpus
488: temp = fw_cfg_read_i32(FW_CFG_NB_CPUS);
489:
490: printk("CPUs: %x", temp);
491: cpu = id_cpu();
492: printk(" x %s\n", cpu->name);
493: for (i = 0; i < temp; i++) {
494: push_str("/");
495: fword("find-device");
496:
497: fword("new-device");
498:
499: push_str(cpu->name);
500: fword("device-name");
501:
502: push_str("cpu");
503: fword("device-type");
504:
505: PUSH(cpu->psr_impl);
506: fword("encode-int");
507: push_str("psr-implementation");
508: fword("property");
509:
510: PUSH(cpu->psr_vers);
511: fword("encode-int");
512: push_str("psr-version");
513: fword("property");
514:
515: PUSH(cpu->impl);
516: fword("encode-int");
517: push_str("implementation");
518: fword("property");
519:
520: PUSH(cpu->vers);
521: fword("encode-int");
522: push_str("version");
523: fword("property");
524:
525: PUSH(4096);
526: fword("encode-int");
527: push_str("page-size");
528: fword("property");
529:
530: PUSH(cpu->dcache_line_size);
531: fword("encode-int");
532: push_str("dcache-line-size");
533: fword("property");
534:
535: PUSH(cpu->dcache_lines);
536: fword("encode-int");
537: push_str("dcache-nlines");
538: fword("property");
539:
540: PUSH(cpu->dcache_assoc);
541: fword("encode-int");
542: push_str("dcache-associativity");
543: fword("property");
544:
545: PUSH(cpu->icache_line_size);
546: fword("encode-int");
547: push_str("icache-line-size");
548: fword("property");
549:
550: PUSH(cpu->icache_lines);
551: fword("encode-int");
552: push_str("icache-nlines");
553: fword("property");
554:
555: PUSH(cpu->icache_assoc);
556: fword("encode-int");
557: push_str("icache-associativity");
558: fword("property");
559:
560: PUSH(cpu->ecache_line_size);
561: fword("encode-int");
562: push_str("ecache-line-size");
563: fword("property");
564:
565: PUSH(cpu->ecache_lines);
566: fword("encode-int");
567: push_str("ecache-nlines");
568: fword("property");
569:
570: PUSH(cpu->ecache_assoc);
571: fword("encode-int");
572: push_str("ecache-associativity");
573: fword("property");
574:
575: PUSH(2);
576: fword("encode-int");
577: push_str("ncaches");
578: fword("property");
579:
580: PUSH(cpu->mmu_nctx);
581: fword("encode-int");
582: push_str("mmu-nctx");
583: fword("property");
584:
585: PUSH(8);
586: fword("encode-int");
587: push_str("sparc-version");
588: fword("property");
589:
590: push_str("");
591: fword("encode-string");
592: push_str("cache-coherence?");
593: fword("property");
594:
595: PUSH(i + mid_offset);
596: fword("encode-int");
597: push_str("mid");
598: fword("property");
599:
600: cpu->initfn();
601:
602: fword("finish-device");
603: }
604: }
605:
606: static void dummy_mach_init(uint64_t base)
607: {
608: }
609:
610: struct machdef {
611: uint16_t machine_id;
612: const char *banner_name;
613: const char *model;
614: const char *name;
615: void (*initfn)(uint64_t base);
616: };
617:
618: static const struct machdef sun4m_defs[] = {
619: {
620: .machine_id = 32,
621: .banner_name = "SPARCstation 5",
622: .model = "SUNW,501-3059",
623: .name = "SUNW,SPARCstation-5",
624: .initfn = ss5_init,
625: },
626: {
627: .machine_id = 33,
628: .banner_name = "SPARCstation Voyager",
629: .model = "SUNW,501-2581",
630: .name = "SUNW,SPARCstation-Voyager",
631: .initfn = dummy_mach_init,
632: },
633: {
634: .machine_id = 34,
635: .banner_name = "SPARCstation LX",
636: .model = "SUNW,501-2031",
637: .name = "SUNW,SPARCstation-LX",
638: .initfn = dummy_mach_init,
639: },
640: {
641: .machine_id = 35,
642: .banner_name = "SPARCstation 4",
643: .model = "SUNW,501-2572",
644: .name = "SUNW,SPARCstation-4",
645: .initfn = ss5_init,
646: },
647: {
648: .machine_id = 36,
649: .banner_name = "SPARCstation Classic",
650: .model = "SUNW,501-2326",
651: .name = "SUNW,SPARCstation-Classic",
652: .initfn = dummy_mach_init,
653: },
654: {
655: .machine_id = 37,
656: .banner_name = "Tadpole S3 GX",
657: .model = "S3",
658: .name = "Tadpole_S3GX",
659: .initfn = ss5_init,
660: },
661: {
662: .machine_id = 64,
663: .banner_name = "SPARCstation 10 (1 X 390Z55)",
664: .model = "SUNW,S10,501-2365",
665: .name = "SUNW,SPARCstation-10",
666: .initfn = ob_eccmemctl_init,
667: },
668: {
669: .machine_id = 65,
670: .banner_name = "SPARCstation 20 (1 X 390Z55)",
671: .model = "SUNW,S20,501-2324",
672: .name = "SUNW,SPARCstation-20",
673: .initfn = ob_eccmemctl_init,
674: },
675: {
676: .machine_id = 66,
677: .banner_name = "SPARCsystem 600(1 X 390Z55)",
678: .model = NULL,
679: .name = "SUNW,SPARCsystem-600",
680: .initfn = ob_eccmemctl_init,
681: },
682: };
683:
684: static const struct machdef *
685: id_machine(uint16_t machine_id)
686: {
687: unsigned int i;
688:
689: for (i = 0; i < sizeof(sun4m_defs)/sizeof(struct machdef); i++) {
690: if (machine_id == sun4m_defs[i].machine_id)
691: return &sun4m_defs[i];
692: }
693: printk("Unknown machine (ID %d), freezing!\n", machine_id);
694: for (;;);
695: }
696:
697: static void setup_machine(uint64_t base)
698: {
699: uint16_t machine_id;
700: const struct machdef *mach;
701:
702: machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
703: mach = id_machine(machine_id);
704:
705: push_str("/");
706: fword("find-device");
707: push_str(mach->banner_name);
708: fword("encode-string");
709: push_str("banner-name");
710: fword("property");
711:
712: if (mach->model) {
713: push_str(mach->model);
714: fword("encode-string");
715: push_str("model");
716: fword("property");
717: }
718: push_str(mach->name);
719: fword("encode-string");
720: push_str("name");
721: fword("property");
722:
723: mach->initfn(base);
724: }
725:
726: /* Add /uuid */
727: static void setup_uuid(void)
728: {
729: static uint8_t qemu_uuid[16];
730:
731: fw_cfg_read(FW_CFG_UUID, (char *)qemu_uuid, 16);
732:
733: printk("UUID: " UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
734: qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6],
735: qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
736: qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], qemu_uuid[14],
737: qemu_uuid[15]);
738:
739: push_str("/");
740: fword("find-device");
741:
742: PUSH((long)&qemu_uuid);
743: PUSH(16);
744: fword("encode-bytes");
745: push_str("uuid");
746: fword("property");
747: }
748:
749: static void setup_stdio(void)
750: {
751: char nographic;
752: const char *stdin, *stdout;
753: phandle_t chosen;
754:
755: fw_cfg_read(FW_CFG_NOGRAPHIC, &nographic, 1);
756: if (nographic) {
757: obp_stdin = PROMDEV_TTYA;
758: obp_stdout = PROMDEV_TTYA;
759: stdin = "ttya";
760: stdout = "ttya";
761: } else {
762: obp_stdin = PROMDEV_KBD;
763: obp_stdout = PROMDEV_SCREEN;
764: stdin = "keyboard";
765: stdout = "screen";
766: }
767:
768: push_str("/");
769: fword("find-device");
770:
771: push_str(stdin);
772: fword("pathres-resolve-aliases");
773: fword("encode-string");
774: push_str("stdin-path");
775: fword("property");
776:
777: push_str(stdout);
778: fword("pathres-resolve-aliases");
779: fword("encode-string");
780: push_str("stdout-path");
781: fword("property");
782:
783: chosen = find_dev("/chosen");
784: push_str(stdin);
785: fword("open-dev");
786: set_int_property(chosen, "stdin", POP());
787:
788: chosen = find_dev("/chosen");
789: push_str(stdout);
790: fword("open-dev");
791: set_int_property(chosen, "stdout", POP());
792:
793: push_str(stdin);
794: push_str("input-device");
795: fword("$setenv");
796:
797: push_str(stdout);
798: push_str("output-device");
799: fword("$setenv");
800:
801: push_str(stdin);
802: fword("input");
803:
804: obp_stdin_path = stdin;
805: obp_stdout_path = stdout;
806: }
807:
808: static void init_memory(void)
809: {
810: memory = malloc(MEMORY_SIZE);
811: if (!memory)
812: printk("panic: not enough memory on host system.\n");
813:
814: /* we push start and end of memory to the stack
815: * so that it can be used by the forth word QUIT
816: * to initialize the memory allocator
817: */
818:
819: PUSH((ucell)memory);
820: PUSH((ucell)memory + MEMORY_SIZE);
821: }
822:
823: static void
824: arch_init( void )
825: {
826: static char cmdline[128];
827: int size = 0;
828: const char *kernel_cmdline;
829: uint32_t temp;
830: uint16_t machine_id;
831: char buf[256];
832: unsigned long mem_size;
833:
834: fw_cfg_init();
835:
836: fw_cfg_read(FW_CFG_SIGNATURE, buf, 4);
837: buf[4] = '\0';
838:
839: printk("Configuration device id %s", buf);
840:
841: temp = fw_cfg_read_i32(FW_CFG_ID);
842: machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
843:
844: printk(" version %d machine id %d\n", temp, machine_id);
845:
846: if (temp != 1) {
847: printk("Incompatible configuration device version, freezing\n");
848: for(;;);
849: }
850:
851: graphic_depth = fw_cfg_read_i16(FW_CFG_SUN4M_DEPTH);
852:
853: openbios_init();
854: modules_init();
855: ob_init_mmu();
856: ob_init_iommu(hwdef->iommu_base);
857: #ifdef CONFIG_DRIVER_OBIO
858: mem_size = fw_cfg_read_i32(FW_CFG_RAM_SIZE);
859: ob_obio_init(hwdef->slavio_base, hwdef->fd_offset,
860: hwdef->counter_offset, hwdef->intr_offset,
861: hwdef->aux1_offset, hwdef->aux2_offset,
862: mem_size);
863:
864: setup_machine(hwdef->slavio_base);
865:
866: nvconf_init();
867: #endif
868: #ifdef CONFIG_DRIVER_SBUS
869: #ifdef CONFIG_DEBUG_CONSOLE_VIDEO
870: init_video((unsigned long)vmem, 1024, 768, 8, 1024);
871: #endif
872: ob_sbus_init(hwdef->iommu_base + 0x1000ULL, qemu_machine_type);
873: #endif
874: device_end();
875:
876: setup_cpu(hwdef->mid_offset);
877:
878: setup_stdio();
879: /* Initialiase openprom romvec */
880: romvec = init_openprom();
881:
882: kernel_size = fw_cfg_read_i32(FW_CFG_KERNEL_SIZE);
883: if (kernel_size)
884: kernel_image = fw_cfg_read_i32(FW_CFG_KERNEL_ADDR);
885:
886: kernel_cmdline = (const char *) fw_cfg_read_i32(FW_CFG_KERNEL_CMDLINE);
887: if (kernel_cmdline) {
888: size = strlen(kernel_cmdline);
889: memcpy(cmdline, kernel_cmdline, size);
890: obp_arg.argv[1] = cmdline;
891: }
892: cmdline[size] = '\0';
893: qemu_cmdline = (uint32_t)cmdline;
894:
895: /* Setup nvram variables */
896: push_str("/options");
897: fword("find-device");
898: push_str(cmdline);
899: fword("encode-string");
900: push_str("boot-file");
901: fword("property");
902:
903: boot_device = fw_cfg_read_i16(FW_CFG_BOOT_DEVICE);
904:
905: switch (boot_device) {
906: case 'a':
907: push_str("floppy");
908: break;
909: case 'c':
910: push_str("disk");
911: break;
912: default:
913: case 'd':
914: push_str("cdrom:d cdrom");
915: break;
916: case 'n':
917: push_str("net");
918: break;
919: }
920:
921: fword("encode-string");
922: push_str("boot-device");
923: fword("property");
924:
925: device_end();
926:
927: bind_func("platform-boot", boot );
928: bind_func("(go)", go );
929:
930: /* Set up other properties */
931: push_str("/chosen");
932: fword("find-device");
933:
934: setup_uuid();
935: }
936:
937: int openbios(void)
938: {
939: unsigned int i;
940:
941: for (i = 0; i < sizeof(hwdefs) / sizeof(struct hwdef); i++) {
942: if (hwdefs[i].machine_id_low <= qemu_machine_type &&
943: hwdefs[i].machine_id_high >= qemu_machine_type) {
944: hwdef = &hwdefs[i];
945: break;
946: }
947: }
948: if (!hwdef)
949: for(;;); // Internal inconsistency, hang
950:
951: /* Make sure we setup OFMEM before the MMU as we need malloc() to setup page tables */
952: ofmem_init();
953:
954: #ifdef CONFIG_DRIVER_SBUS
955: init_mmu_swift();
956: #endif
957: #ifdef CONFIG_DEBUG_CONSOLE
958: #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
959: uart_init(hwdef->serial_base | (CONFIG_SERIAL_PORT? 0ULL: 4ULL),
960: CONFIG_SERIAL_SPEED);
961: #endif
962: #ifdef CONFIG_DEBUG_CONSOLE_VIDEO
963: tcx_init(hwdef->tcx_base);
964: kbd_init(hwdef->ms_kb_base);
965: #endif
966: /* Clear the screen. */
967: cls();
968: #endif
969:
970: collect_sys_info(&sys_info);
971:
972: dict = (unsigned char *)sys_info.dict_start;
973: dicthead = (cell)sys_info.dict_end;
974: last = sys_info.dict_last;
975: dictlimit = sys_info.dict_limit;
976:
977: forth_init();
978:
979: #ifdef CONFIG_DEBUG_BOOT
980: printk("forth started.\n");
981: printk("initializing memory...");
982: #endif
983:
984: init_memory();
985:
986: #ifdef CONFIG_DEBUG_BOOT
987: printk("done\n");
988: #endif
989:
990: PUSH_xt( bind_noname_func(arch_init) );
991: fword("PREPOST-initializer");
992:
993: PC = (ucell)findword("initialize-of");
994:
995: if (!PC) {
996: printk("panic: no dictionary entry point.\n");
997: return -1;
998: }
999: #ifdef CONFIG_DEBUG_DICTIONARY
1000: printk("done (%d bytes).\n", dicthead);
1001: printk("Jumping to dictionary...\n");
1002: #endif
1003:
1004: enterforth((xt_t)PC);
1005:
1006: free(dict);
1007: return 0;
1008: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.