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