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