|
|
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.