|
|
1.1 root 1: /* 1.1.1.6 ! root 2: * QEMU Sun4m & Sun4d & Sun4c System Emulator ! 3: * 1.1 root 4: * Copyright (c) 2003-2005 Fabrice Bellard 1.1.1.6 ! root 5: * 1.1 root 6: * Permission is hereby granted, free of charge, to any person obtaining a copy 7: * of this software and associated documentation files (the "Software"), to deal 8: * in the Software without restriction, including without limitation the rights 9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10: * copies of the Software, and to permit persons to whom the Software is 11: * furnished to do so, subject to the following conditions: 12: * 13: * The above copyright notice and this permission notice shall be included in 14: * all copies or substantial portions of the Software. 15: * 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22: * THE SOFTWARE. 23: */ 1.1.1.6 ! root 24: #include "hw.h" ! 25: #include "qemu-timer.h" ! 26: #include "sun4m.h" ! 27: #include "nvram.h" ! 28: #include "sparc32_dma.h" ! 29: #include "fdc.h" ! 30: #include "sysemu.h" ! 31: #include "net.h" ! 32: #include "boards.h" ! 33: #include "firmware_abi.h" ! 34: ! 35: //#define DEBUG_IRQ ! 36: ! 37: /* ! 38: * Sun4m architecture was used in the following machines: ! 39: * ! 40: * SPARCserver 6xxMP/xx ! 41: * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10) ! 42: * SPARCstation LX/ZX (4/30) ! 43: * SPARCstation Voyager ! 44: * SPARCstation 10/xx, SPARCserver 10/xx ! 45: * SPARCstation 5, SPARCserver 5 ! 46: * SPARCstation 20/xx, SPARCserver 20 ! 47: * SPARCstation 4 ! 48: * ! 49: * Sun4d architecture was used in the following machines: ! 50: * ! 51: * SPARCcenter 2000 ! 52: * SPARCserver 1000 ! 53: * ! 54: * Sun4c architecture was used in the following machines: ! 55: * SPARCstation 1/1+, SPARCserver 1/1+ ! 56: * SPARCstation SLC ! 57: * SPARCstation IPC ! 58: * SPARCstation ELC ! 59: * SPARCstation IPX ! 60: * ! 61: * See for example: http://www.sunhelp.org/faq/sunref1.html ! 62: */ ! 63: ! 64: #ifdef DEBUG_IRQ ! 65: #define DPRINTF(fmt, args...) \ ! 66: do { printf("CPUIRQ: " fmt , ##args); } while (0) ! 67: #else ! 68: #define DPRINTF(fmt, args...) ! 69: #endif 1.1 root 70: 71: #define KERNEL_LOAD_ADDR 0x00004000 72: #define CMDLINE_ADDR 0x007ff000 73: #define INITRD_LOAD_ADDR 0x00800000 1.1.1.6 ! root 74: #define PROM_SIZE_MAX (512 * 1024) ! 75: #define PROM_VADDR 0xffd00000 ! 76: #define PROM_FILENAME "openbios-sparc32" 1.1.1.5 root 77: 1.1.1.2 root 78: #define MAX_CPUS 16 1.1.1.6 ! root 79: #define MAX_PILS 16 ! 80: ! 81: struct hwdef { ! 82: target_phys_addr_t iommu_base, slavio_base; ! 83: target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base; ! 84: target_phys_addr_t serial_base, fd_base; ! 85: target_phys_addr_t idreg_base, dma_base, esp_base, le_base; ! 86: target_phys_addr_t tcx_base, cs_base, power_base; ! 87: target_phys_addr_t ecc_base; ! 88: uint32_t ecc_version; ! 89: target_phys_addr_t sun4c_intctl_base, sun4c_counter_base; ! 90: long vram_size, nvram_size; ! 91: // IRQ numbers are not PIL ones, but master interrupt controller ! 92: // register bit numbers ! 93: int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq; ! 94: int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq; ! 95: int machine_id; // For NVRAM ! 96: uint32_t iommu_version; ! 97: uint32_t intbit_to_level[32]; ! 98: uint64_t max_mem; ! 99: const char * const default_cpu_model; ! 100: }; ! 101: ! 102: #define MAX_IOUNITS 5 ! 103: ! 104: struct sun4d_hwdef { ! 105: target_phys_addr_t iounit_bases[MAX_IOUNITS], slavio_base; ! 106: target_phys_addr_t counter_base, nvram_base, ms_kb_base; ! 107: target_phys_addr_t serial_base; ! 108: target_phys_addr_t espdma_base, esp_base; ! 109: target_phys_addr_t ledma_base, le_base; ! 110: target_phys_addr_t tcx_base; ! 111: target_phys_addr_t sbi_base; ! 112: unsigned long vram_size, nvram_size; ! 113: // IRQ numbers are not PIL ones, but SBI register bit numbers ! 114: int esp_irq, le_irq, clock_irq, clock1_irq; ! 115: int ser_irq, ms_kb_irq, me_irq; ! 116: int machine_id; // For NVRAM ! 117: uint32_t iounit_version; ! 118: uint64_t max_mem; ! 119: const char * const default_cpu_model; ! 120: }; 1.1 root 121: 122: /* TSC handling */ 123: 124: uint64_t cpu_get_tsc() 125: { 126: return qemu_get_clock(vm_clock); 127: } 128: 129: int DMA_get_channel_mode (int nchan) 130: { 131: return 0; 132: } 133: int DMA_read_memory (int nchan, void *buf, int pos, int size) 134: { 135: return 0; 136: } 137: int DMA_write_memory (int nchan, void *buf, int pos, int size) 138: { 139: return 0; 140: } 141: void DMA_hold_DREQ (int nchan) {} 142: void DMA_release_DREQ (int nchan) {} 143: void DMA_schedule(int nchan) {} 144: void DMA_run (void) {} 145: void DMA_init (int high_page_enable) {} 146: void DMA_register_channel (int nchan, 147: DMA_transfer_handler transfer_handler, 148: void *opaque) 149: { 150: } 151: 152: extern int nographic; 153: 1.1.1.2 root 154: static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, 1.1.1.6 ! root 155: const char *boot_devices, uint32_t RAM_size, ! 156: uint32_t kernel_size, ! 157: int width, int height, int depth, ! 158: int machine_id, const char *arch) 1.1 root 159: { 1.1.1.6 ! root 160: unsigned int i; ! 161: uint32_t start, end; ! 162: uint8_t image[0x1ff0]; ! 163: ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ ! 164: struct sparc_arch_cfg *sparc_header; ! 165: struct OpenBIOS_nvpart_v1 *part_header; ! 166: ! 167: memset(image, '\0', sizeof(image)); 1.1 root 168: 169: // Try to match PPC NVRAM 1.1.1.6 ! root 170: strcpy(header->struct_ident, "QEMU_BIOS"); ! 171: header->struct_version = cpu_to_be32(3); /* structure v3 */ ! 172: ! 173: header->nvram_size = cpu_to_be16(0x2000); ! 174: header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); ! 175: header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); ! 176: strcpy(header->arch, arch); ! 177: header->nb_cpus = smp_cpus & 0xff; ! 178: header->RAM0_base = 0; ! 179: header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); ! 180: strcpy(header->boot_devices, boot_devices); ! 181: header->nboot_devices = strlen(boot_devices) & 0xff; ! 182: header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR); ! 183: header->kernel_size = cpu_to_be64((uint64_t)kernel_size); 1.1 root 184: if (cmdline) { 1.1.1.6 ! root 185: strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); ! 186: header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); ! 187: header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); 1.1 root 188: } 1.1.1.6 ! root 189: // XXX add initrd_image, initrd_size ! 190: header->width = cpu_to_be16(width); ! 191: header->height = cpu_to_be16(height); ! 192: header->depth = cpu_to_be16(depth); ! 193: if (nographic) ! 194: header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS); ! 195: ! 196: header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); ! 197: ! 198: // Architecture specific header ! 199: start = sizeof(ohwcfg_v3_t); ! 200: sparc_header = (struct sparc_arch_cfg *)&image[start]; ! 201: sparc_header->valid = 0; ! 202: start += sizeof(struct sparc_arch_cfg); ! 203: ! 204: // OpenBIOS nvram variables ! 205: // Variable partition ! 206: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; ! 207: part_header->signature = OPENBIOS_PART_SYSTEM; ! 208: strcpy(part_header->name, "system"); ! 209: ! 210: end = start + sizeof(struct OpenBIOS_nvpart_v1); ! 211: for (i = 0; i < nb_prom_envs; i++) ! 212: end = OpenBIOS_set_var(image, end, prom_envs[i]); ! 213: ! 214: // End marker ! 215: image[end++] = '\0'; ! 216: ! 217: end = start + ((end - start + 15) & ~15); ! 218: OpenBIOS_finish_partition(part_header, end - start); ! 219: ! 220: // free partition ! 221: start = end; ! 222: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; ! 223: part_header->signature = OPENBIOS_PART_FREE; ! 224: strcpy(part_header->name, "free"); ! 225: ! 226: end = 0x1fd0; ! 227: OpenBIOS_finish_partition(part_header, end - start); ! 228: ! 229: Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, machine_id); ! 230: ! 231: for (i = 0; i < sizeof(image); i++) ! 232: m48t59_write(nvram, i, image[i]); 1.1 root 233: } 234: 235: static void *slavio_intctl; 236: 237: void pic_info() 238: { 1.1.1.6 ! root 239: if (slavio_intctl) ! 240: slavio_pic_info(slavio_intctl); 1.1 root 241: } 242: 243: void irq_info() 244: { 1.1.1.6 ! root 245: if (slavio_intctl) ! 246: slavio_irq_info(slavio_intctl); 1.1 root 247: } 248: 1.1.1.6 ! root 249: void cpu_check_irqs(CPUState *env) 1.1 root 250: { 1.1.1.6 ! root 251: if (env->pil_in && (env->interrupt_index == 0 || ! 252: (env->interrupt_index & ~15) == TT_EXTINT)) { ! 253: unsigned int i; ! 254: ! 255: for (i = 15; i > 0; i--) { ! 256: if (env->pil_in & (1 << i)) { ! 257: int old_interrupt = env->interrupt_index; ! 258: ! 259: env->interrupt_index = TT_EXTINT | i; ! 260: if (old_interrupt != env->interrupt_index) ! 261: cpu_interrupt(env, CPU_INTERRUPT_HARD); ! 262: break; ! 263: } ! 264: } ! 265: } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { ! 266: env->interrupt_index = 0; ! 267: cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); ! 268: } 1.1 root 269: } 270: 1.1.1.6 ! root 271: static void cpu_set_irq(void *opaque, int irq, int level) 1.1.1.4 root 272: { 1.1.1.6 ! root 273: CPUState *env = opaque; ! 274: ! 275: if (level) { ! 276: DPRINTF("Raise CPU IRQ %d\n", irq); ! 277: env->halted = 0; ! 278: env->pil_in |= 1 << irq; ! 279: cpu_check_irqs(env); ! 280: } else { ! 281: DPRINTF("Lower CPU IRQ %d\n", irq); ! 282: env->pil_in &= ~(1 << irq); ! 283: cpu_check_irqs(env); ! 284: } 1.1.1.4 root 285: } 286: 1.1.1.6 ! root 287: static void dummy_cpu_set_irq(void *opaque, int irq, int level) 1.1.1.2 root 288: { 289: } 290: 1.1 root 291: static void *slavio_misc; 292: 293: void qemu_system_powerdown(void) 294: { 295: slavio_set_power_fail(slavio_misc, 1); 296: } 297: 1.1.1.2 root 298: static void main_cpu_reset(void *opaque) 299: { 300: CPUState *env = opaque; 1.1.1.6 ! root 301: 1.1.1.2 root 302: cpu_reset(env); 1.1.1.6 ! root 303: env->halted = 0; 1.1.1.2 root 304: } 305: 1.1.1.6 ! root 306: static void secondary_cpu_reset(void *opaque) 1.1 root 307: { 1.1.1.6 ! root 308: CPUState *env = opaque; ! 309: ! 310: cpu_reset(env); ! 311: env->halted = 1; ! 312: } ! 313: ! 314: static unsigned long sun4m_load_kernel(const char *kernel_filename, ! 315: const char *kernel_cmdline, ! 316: const char *initrd_filename) ! 317: { ! 318: int linux_boot; 1.1 root 319: unsigned int i; 1.1.1.6 ! root 320: long initrd_size, kernel_size; 1.1 root 321: 322: linux_boot = (kernel_filename != NULL); 323: 1.1.1.6 ! root 324: kernel_size = 0; ! 325: if (linux_boot) { ! 326: kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL, ! 327: NULL); ! 328: if (kernel_size < 0) ! 329: kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); ! 330: if (kernel_size < 0) ! 331: kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); ! 332: if (kernel_size < 0) { ! 333: fprintf(stderr, "qemu: could not load kernel '%s'\n", ! 334: kernel_filename); ! 335: exit(1); ! 336: } ! 337: ! 338: /* load initrd */ ! 339: initrd_size = 0; ! 340: if (initrd_filename) { ! 341: initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR); ! 342: if (initrd_size < 0) { ! 343: fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", ! 344: initrd_filename); ! 345: exit(1); ! 346: } ! 347: } ! 348: if (initrd_size > 0) { ! 349: for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { ! 350: if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i) ! 351: == 0x48647253) { // HdrS ! 352: stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR); ! 353: stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size); ! 354: break; ! 355: } ! 356: } ! 357: } ! 358: } ! 359: return kernel_size; ! 360: } ! 361: ! 362: static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size, ! 363: const char *boot_device, ! 364: DisplayState *ds, const char *kernel_filename, ! 365: const char *kernel_cmdline, ! 366: const char *initrd_filename, const char *cpu_model) ! 367: ! 368: { ! 369: CPUState *env, *envs[MAX_CPUS]; ! 370: unsigned int i; ! 371: void *iommu, *espdma, *ledma, *main_esp, *nvram; ! 372: qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq, ! 373: *espdma_irq, *ledma_irq; ! 374: qemu_irq *esp_reset, *le_reset; ! 375: unsigned long prom_offset, kernel_size; ! 376: int ret; ! 377: char buf[1024]; ! 378: BlockDriverState *fd[MAX_FD]; ! 379: int index; ! 380: 1.1.1.2 root 381: /* init CPUs */ 1.1.1.6 ! root 382: if (!cpu_model) ! 383: cpu_model = hwdef->default_cpu_model; ! 384: 1.1.1.2 root 385: for(i = 0; i < smp_cpus; i++) { 1.1.1.6 ! root 386: env = cpu_init(cpu_model); ! 387: if (!env) { ! 388: fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); ! 389: exit(1); ! 390: } ! 391: cpu_sparc_set_id(env, i); 1.1.1.2 root 392: envs[i] = env; 1.1.1.6 ! root 393: if (i == 0) { ! 394: qemu_register_reset(main_cpu_reset, env); ! 395: } else { ! 396: qemu_register_reset(secondary_cpu_reset, env); 1.1.1.2 root 397: env->halted = 1; 1.1.1.6 ! root 398: } 1.1.1.2 root 399: register_savevm("cpu", i, 3, cpu_save, cpu_load, env); 1.1.1.6 ! root 400: cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); ! 401: env->prom_addr = hwdef->slavio_base; 1.1.1.2 root 402: } 1.1.1.6 ! root 403: ! 404: for (i = smp_cpus; i < MAX_CPUS; i++) ! 405: cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS); ! 406: ! 407: 1.1 root 408: /* allocate RAM */ 1.1.1.6 ! root 409: if ((uint64_t)RAM_size > hwdef->max_mem) { ! 410: fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n", ! 411: (unsigned int)RAM_size / (1024 * 1024), ! 412: (unsigned int)(hwdef->max_mem / (1024 * 1024))); ! 413: exit(1); ! 414: } ! 415: cpu_register_physical_memory(0, RAM_size, 0); 1.1 root 416: 1.1.1.6 ! root 417: /* load boot prom */ ! 418: prom_offset = RAM_size + hwdef->vram_size; ! 419: cpu_register_physical_memory(hwdef->slavio_base, ! 420: (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & ! 421: TARGET_PAGE_MASK, ! 422: prom_offset | IO_MEM_ROM); ! 423: ! 424: if (bios_name == NULL) ! 425: bios_name = PROM_FILENAME; ! 426: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); ! 427: ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); ! 428: if (ret < 0 || ret > PROM_SIZE_MAX) ! 429: ret = load_image(buf, phys_ram_base + prom_offset); ! 430: if (ret < 0 || ret > PROM_SIZE_MAX) { ! 431: fprintf(stderr, "qemu: could not load prom '%s'\n", ! 432: buf); ! 433: exit(1); 1.1.1.2 root 434: } 1.1.1.6 ! root 435: prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; 1.1.1.2 root 436: 1.1.1.6 ! root 437: /* set up devices */ ! 438: slavio_intctl = slavio_intctl_init(hwdef->intctl_base, ! 439: hwdef->intctl_base + 0x10000ULL, ! 440: &hwdef->intbit_to_level[0], ! 441: &slavio_irq, &slavio_cpu_irq, ! 442: cpu_irqs, ! 443: hwdef->clock_irq); ! 444: ! 445: if (hwdef->idreg_base != (target_phys_addr_t)-1) { ! 446: stl_raw(phys_ram_base + prom_offset, 0xfe810103); ! 447: ! 448: cpu_register_physical_memory(hwdef->idreg_base, sizeof(uint32_t), ! 449: prom_offset | IO_MEM_ROM); 1.1.1.3 root 450: } 1.1.1.6 ! root 451: ! 452: iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, ! 453: slavio_irq[hwdef->me_irq]); ! 454: ! 455: espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], ! 456: iommu, &espdma_irq, &esp_reset); ! 457: ! 458: ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, ! 459: slavio_irq[hwdef->le_irq], iommu, &ledma_irq, ! 460: &le_reset); ! 461: ! 462: if (graphic_depth != 8 && graphic_depth != 24) { ! 463: fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); ! 464: exit (1); ! 465: } ! 466: tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size, ! 467: hwdef->vram_size, graphic_width, graphic_height, graphic_depth); ! 468: ! 469: if (nd_table[0].model == NULL ! 470: || strcmp(nd_table[0].model, "lance") == 0) { ! 471: lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); ! 472: } else if (strcmp(nd_table[0].model, "?") == 0) { ! 473: fprintf(stderr, "qemu: Supported NICs: lance\n"); ! 474: exit (1); ! 475: } else { ! 476: fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); ! 477: exit (1); 1.1.1.2 root 478: } 1.1.1.6 ! root 479: ! 480: nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, ! 481: hwdef->nvram_size, 8); ! 482: ! 483: slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq], ! 484: slavio_cpu_irq, smp_cpus); ! 485: ! 486: slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], ! 487: nographic); 1.1 root 488: // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device 489: // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device 1.1.1.6 ! root 490: slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], ! 491: serial_hds[1], serial_hds[0]); ! 492: ! 493: if (hwdef->fd_base != (target_phys_addr_t)-1) { ! 494: /* there is zero or one floppy drive */ ! 495: fd[1] = fd[0] = NULL; ! 496: index = drive_get_index(IF_FLOPPY, 0, 0); ! 497: if (index != -1) ! 498: fd[0] = drives_table[index].bdrv; ! 499: ! 500: sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd); ! 501: } ! 502: ! 503: if (drive_get_max_bus(IF_SCSI) > 0) { ! 504: fprintf(stderr, "qemu: too many SCSI bus\n"); ! 505: exit(1); ! 506: } ! 507: ! 508: main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq, ! 509: esp_reset); ! 510: ! 511: for (i = 0; i < ESP_MAX_DEVS; i++) { ! 512: index = drive_get_index(IF_SCSI, 0, i); ! 513: if (index == -1) ! 514: continue; ! 515: esp_scsi_attach(main_esp, drives_table[index].bdrv, i); ! 516: } ! 517: ! 518: slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base, ! 519: slavio_irq[hwdef->me_irq]); ! 520: if (hwdef->cs_base != (target_phys_addr_t)-1) ! 521: cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl); ! 522: ! 523: kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline, ! 524: initrd_filename); ! 525: ! 526: nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, ! 527: boot_device, RAM_size, kernel_size, graphic_width, ! 528: graphic_height, graphic_depth, hwdef->machine_id, "Sun4m"); ! 529: ! 530: if (hwdef->ecc_base != (target_phys_addr_t)-1) ! 531: ecc_init(hwdef->ecc_base, hwdef->ecc_version); ! 532: } ! 533: ! 534: static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size, ! 535: const char *boot_device, ! 536: DisplayState *ds, const char *kernel_filename, ! 537: const char *kernel_cmdline, ! 538: const char *initrd_filename, const char *cpu_model) ! 539: { ! 540: CPUState *env; ! 541: unsigned int i; ! 542: void *iommu, *espdma, *ledma, *main_esp, *nvram; ! 543: qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq; ! 544: qemu_irq *esp_reset, *le_reset; ! 545: unsigned long prom_offset, kernel_size; ! 546: int ret; ! 547: char buf[1024]; ! 548: BlockDriverState *fd[MAX_FD]; ! 549: int index; ! 550: ! 551: /* init CPU */ ! 552: if (!cpu_model) ! 553: cpu_model = hwdef->default_cpu_model; ! 554: ! 555: env = cpu_init(cpu_model); ! 556: if (!env) { ! 557: fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); ! 558: exit(1); ! 559: } ! 560: ! 561: cpu_sparc_set_id(env, 0); ! 562: ! 563: qemu_register_reset(main_cpu_reset, env); ! 564: register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); ! 565: cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); ! 566: env->prom_addr = hwdef->slavio_base; ! 567: ! 568: /* allocate RAM */ ! 569: if ((uint64_t)RAM_size > hwdef->max_mem) { ! 570: fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n", ! 571: (unsigned int)RAM_size / (1024 * 1024), ! 572: (unsigned int)hwdef->max_mem / (1024 * 1024)); ! 573: exit(1); 1.1.1.5 root 574: } 1.1.1.6 ! root 575: cpu_register_physical_memory(0, RAM_size, 0); 1.1.1.5 root 576: 1.1.1.6 ! root 577: /* load boot prom */ ! 578: prom_offset = RAM_size + hwdef->vram_size; ! 579: cpu_register_physical_memory(hwdef->slavio_base, ! 580: (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & ! 581: TARGET_PAGE_MASK, 1.1.1.3 root 582: prom_offset | IO_MEM_ROM); 1.1 root 583: 1.1.1.6 ! root 584: if (bios_name == NULL) ! 585: bios_name = PROM_FILENAME; ! 586: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); ! 587: ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); ! 588: if (ret < 0 || ret > PROM_SIZE_MAX) ! 589: ret = load_image(buf, phys_ram_base + prom_offset); ! 590: if (ret < 0 || ret > PROM_SIZE_MAX) { ! 591: fprintf(stderr, "qemu: could not load prom '%s'\n", ! 592: buf); ! 593: exit(1); 1.1 root 594: } 1.1.1.6 ! root 595: prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; 1.1 root 596: 1.1.1.6 ! root 597: /* set up devices */ ! 598: slavio_intctl = sun4c_intctl_init(hwdef->sun4c_intctl_base, ! 599: &slavio_irq, cpu_irqs); 1.1 root 600: 1.1.1.6 ! root 601: iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, ! 602: slavio_irq[hwdef->me_irq]); ! 603: ! 604: espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], ! 605: iommu, &espdma_irq, &esp_reset); ! 606: ! 607: ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, ! 608: slavio_irq[hwdef->le_irq], iommu, &ledma_irq, ! 609: &le_reset); ! 610: ! 611: if (graphic_depth != 8 && graphic_depth != 24) { ! 612: fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); ! 613: exit (1); ! 614: } ! 615: tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size, ! 616: hwdef->vram_size, graphic_width, graphic_height, graphic_depth); ! 617: ! 618: if (nd_table[0].model == NULL ! 619: || strcmp(nd_table[0].model, "lance") == 0) { ! 620: lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); ! 621: } else if (strcmp(nd_table[0].model, "?") == 0) { ! 622: fprintf(stderr, "qemu: Supported NICs: lance\n"); ! 623: exit (1); ! 624: } else { ! 625: fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); ! 626: exit (1); ! 627: } ! 628: ! 629: nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, ! 630: hwdef->nvram_size, 2); ! 631: ! 632: slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], ! 633: nographic); ! 634: // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device ! 635: // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device ! 636: slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], ! 637: serial_hds[1], serial_hds[0]); ! 638: ! 639: if (hwdef->fd_base != (target_phys_addr_t)-1) { ! 640: /* there is zero or one floppy drive */ ! 641: fd[1] = fd[0] = NULL; ! 642: index = drive_get_index(IF_FLOPPY, 0, 0); ! 643: if (index != -1) ! 644: fd[0] = drives_table[index].bdrv; ! 645: ! 646: sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd); ! 647: } ! 648: ! 649: if (drive_get_max_bus(IF_SCSI) > 0) { ! 650: fprintf(stderr, "qemu: too many SCSI bus\n"); ! 651: exit(1); ! 652: } ! 653: ! 654: main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq, ! 655: esp_reset); ! 656: ! 657: for (i = 0; i < ESP_MAX_DEVS; i++) { ! 658: index = drive_get_index(IF_SCSI, 0, i); ! 659: if (index == -1) ! 660: continue; ! 661: esp_scsi_attach(main_esp, drives_table[index].bdrv, i); ! 662: } ! 663: ! 664: kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline, ! 665: initrd_filename); ! 666: ! 667: nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, ! 668: boot_device, RAM_size, kernel_size, graphic_width, ! 669: graphic_height, graphic_depth, hwdef->machine_id, "Sun4c"); ! 670: } ! 671: ! 672: static const struct hwdef hwdefs[] = { ! 673: /* SS-5 */ ! 674: { ! 675: .iommu_base = 0x10000000, ! 676: .tcx_base = 0x50000000, ! 677: .cs_base = 0x6c000000, ! 678: .slavio_base = 0x70000000, ! 679: .ms_kb_base = 0x71000000, ! 680: .serial_base = 0x71100000, ! 681: .nvram_base = 0x71200000, ! 682: .fd_base = 0x71400000, ! 683: .counter_base = 0x71d00000, ! 684: .intctl_base = 0x71e00000, ! 685: .idreg_base = 0x78000000, ! 686: .dma_base = 0x78400000, ! 687: .esp_base = 0x78800000, ! 688: .le_base = 0x78c00000, ! 689: .power_base = 0x7a000000, ! 690: .ecc_base = -1, ! 691: .sun4c_intctl_base = -1, ! 692: .sun4c_counter_base = -1, ! 693: .vram_size = 0x00100000, ! 694: .nvram_size = 0x2000, ! 695: .esp_irq = 18, ! 696: .le_irq = 16, ! 697: .clock_irq = 7, ! 698: .clock1_irq = 19, ! 699: .ms_kb_irq = 14, ! 700: .ser_irq = 15, ! 701: .fd_irq = 22, ! 702: .me_irq = 30, ! 703: .cs_irq = 5, ! 704: .machine_id = 0x80, ! 705: .iommu_version = 0x05000000, ! 706: .intbit_to_level = { ! 707: 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, ! 708: 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, ! 709: }, ! 710: .max_mem = 0x10000000, ! 711: .default_cpu_model = "Fujitsu MB86904", ! 712: }, ! 713: /* SS-10 */ ! 714: { ! 715: .iommu_base = 0xfe0000000ULL, ! 716: .tcx_base = 0xe20000000ULL, ! 717: .cs_base = -1, ! 718: .slavio_base = 0xff0000000ULL, ! 719: .ms_kb_base = 0xff1000000ULL, ! 720: .serial_base = 0xff1100000ULL, ! 721: .nvram_base = 0xff1200000ULL, ! 722: .fd_base = 0xff1700000ULL, ! 723: .counter_base = 0xff1300000ULL, ! 724: .intctl_base = 0xff1400000ULL, ! 725: .idreg_base = 0xef0000000ULL, ! 726: .dma_base = 0xef0400000ULL, ! 727: .esp_base = 0xef0800000ULL, ! 728: .le_base = 0xef0c00000ULL, ! 729: .power_base = 0xefa000000ULL, ! 730: .ecc_base = 0xf00000000ULL, ! 731: .ecc_version = 0x10000000, // version 0, implementation 1 ! 732: .sun4c_intctl_base = -1, ! 733: .sun4c_counter_base = -1, ! 734: .vram_size = 0x00100000, ! 735: .nvram_size = 0x2000, ! 736: .esp_irq = 18, ! 737: .le_irq = 16, ! 738: .clock_irq = 7, ! 739: .clock1_irq = 19, ! 740: .ms_kb_irq = 14, ! 741: .ser_irq = 15, ! 742: .fd_irq = 22, ! 743: .me_irq = 30, ! 744: .cs_irq = -1, ! 745: .machine_id = 0x72, ! 746: .iommu_version = 0x03000000, ! 747: .intbit_to_level = { ! 748: 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, ! 749: 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, ! 750: }, ! 751: .max_mem = 0xffffffff, // XXX actually first 62GB ok ! 752: .default_cpu_model = "TI SuperSparc II", ! 753: }, ! 754: /* SS-600MP */ ! 755: { ! 756: .iommu_base = 0xfe0000000ULL, ! 757: .tcx_base = 0xe20000000ULL, ! 758: .cs_base = -1, ! 759: .slavio_base = 0xff0000000ULL, ! 760: .ms_kb_base = 0xff1000000ULL, ! 761: .serial_base = 0xff1100000ULL, ! 762: .nvram_base = 0xff1200000ULL, ! 763: .fd_base = -1, ! 764: .counter_base = 0xff1300000ULL, ! 765: .intctl_base = 0xff1400000ULL, ! 766: .idreg_base = -1, ! 767: .dma_base = 0xef0081000ULL, ! 768: .esp_base = 0xef0080000ULL, ! 769: .le_base = 0xef0060000ULL, ! 770: .power_base = 0xefa000000ULL, ! 771: .ecc_base = 0xf00000000ULL, ! 772: .ecc_version = 0x00000000, // version 0, implementation 0 ! 773: .sun4c_intctl_base = -1, ! 774: .sun4c_counter_base = -1, ! 775: .vram_size = 0x00100000, ! 776: .nvram_size = 0x2000, ! 777: .esp_irq = 18, ! 778: .le_irq = 16, ! 779: .clock_irq = 7, ! 780: .clock1_irq = 19, ! 781: .ms_kb_irq = 14, ! 782: .ser_irq = 15, ! 783: .fd_irq = 22, ! 784: .me_irq = 30, ! 785: .cs_irq = -1, ! 786: .machine_id = 0x71, ! 787: .iommu_version = 0x01000000, ! 788: .intbit_to_level = { ! 789: 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, ! 790: 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, ! 791: }, ! 792: .max_mem = 0xffffffff, // XXX actually first 62GB ok ! 793: .default_cpu_model = "TI SuperSparc II", ! 794: }, ! 795: /* SS-20 */ ! 796: { ! 797: .iommu_base = 0xfe0000000ULL, ! 798: .tcx_base = 0xe20000000ULL, ! 799: .cs_base = -1, ! 800: .slavio_base = 0xff0000000ULL, ! 801: .ms_kb_base = 0xff1000000ULL, ! 802: .serial_base = 0xff1100000ULL, ! 803: .nvram_base = 0xff1200000ULL, ! 804: .fd_base = 0xff1700000ULL, ! 805: .counter_base = 0xff1300000ULL, ! 806: .intctl_base = 0xff1400000ULL, ! 807: .idreg_base = 0xef0000000ULL, ! 808: .dma_base = 0xef0400000ULL, ! 809: .esp_base = 0xef0800000ULL, ! 810: .le_base = 0xef0c00000ULL, ! 811: .power_base = 0xefa000000ULL, ! 812: .ecc_base = 0xf00000000ULL, ! 813: .ecc_version = 0x20000000, // version 0, implementation 2 ! 814: .sun4c_intctl_base = -1, ! 815: .sun4c_counter_base = -1, ! 816: .vram_size = 0x00100000, ! 817: .nvram_size = 0x2000, ! 818: .esp_irq = 18, ! 819: .le_irq = 16, ! 820: .clock_irq = 7, ! 821: .clock1_irq = 19, ! 822: .ms_kb_irq = 14, ! 823: .ser_irq = 15, ! 824: .fd_irq = 22, ! 825: .me_irq = 30, ! 826: .cs_irq = -1, ! 827: .machine_id = 0x72, ! 828: .iommu_version = 0x13000000, ! 829: .intbit_to_level = { ! 830: 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, ! 831: 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, ! 832: }, ! 833: .max_mem = 0xffffffff, // XXX actually first 62GB ok ! 834: .default_cpu_model = "TI SuperSparc II", ! 835: }, ! 836: /* SS-2 */ ! 837: { ! 838: .iommu_base = 0xf8000000, ! 839: .tcx_base = 0xfe000000, ! 840: .cs_base = -1, ! 841: .slavio_base = 0xf6000000, ! 842: .ms_kb_base = 0xf0000000, ! 843: .serial_base = 0xf1000000, ! 844: .nvram_base = 0xf2000000, ! 845: .fd_base = 0xf7200000, ! 846: .counter_base = -1, ! 847: .intctl_base = -1, ! 848: .dma_base = 0xf8400000, ! 849: .esp_base = 0xf8800000, ! 850: .le_base = 0xf8c00000, ! 851: .power_base = -1, ! 852: .sun4c_intctl_base = 0xf5000000, ! 853: .sun4c_counter_base = 0xf3000000, ! 854: .vram_size = 0x00100000, ! 855: .nvram_size = 0x800, ! 856: .esp_irq = 2, ! 857: .le_irq = 3, ! 858: .clock_irq = 5, ! 859: .clock1_irq = 7, ! 860: .ms_kb_irq = 1, ! 861: .ser_irq = 1, ! 862: .fd_irq = 1, ! 863: .me_irq = 1, ! 864: .cs_irq = -1, ! 865: .machine_id = 0x55, ! 866: .max_mem = 0x10000000, ! 867: .default_cpu_model = "Cypress CY7C601", ! 868: }, ! 869: }; ! 870: ! 871: /* SPARCstation 5 hardware initialisation */ ! 872: static void ss5_init(int RAM_size, int vga_ram_size, ! 873: const char *boot_device, DisplayState *ds, ! 874: const char *kernel_filename, const char *kernel_cmdline, ! 875: const char *initrd_filename, const char *cpu_model) ! 876: { ! 877: sun4m_hw_init(&hwdefs[0], RAM_size, boot_device, ds, kernel_filename, ! 878: kernel_cmdline, initrd_filename, cpu_model); ! 879: } ! 880: ! 881: /* SPARCstation 10 hardware initialisation */ ! 882: static void ss10_init(int RAM_size, int vga_ram_size, ! 883: const char *boot_device, DisplayState *ds, ! 884: const char *kernel_filename, const char *kernel_cmdline, ! 885: const char *initrd_filename, const char *cpu_model) ! 886: { ! 887: sun4m_hw_init(&hwdefs[1], RAM_size, boot_device, ds, kernel_filename, ! 888: kernel_cmdline, initrd_filename, cpu_model); ! 889: } ! 890: ! 891: /* SPARCserver 600MP hardware initialisation */ ! 892: static void ss600mp_init(int RAM_size, int vga_ram_size, ! 893: const char *boot_device, DisplayState *ds, ! 894: const char *kernel_filename, const char *kernel_cmdline, ! 895: const char *initrd_filename, const char *cpu_model) ! 896: { ! 897: sun4m_hw_init(&hwdefs[2], RAM_size, boot_device, ds, kernel_filename, ! 898: kernel_cmdline, initrd_filename, cpu_model); ! 899: } ! 900: ! 901: /* SPARCstation 20 hardware initialisation */ ! 902: static void ss20_init(int RAM_size, int vga_ram_size, ! 903: const char *boot_device, DisplayState *ds, ! 904: const char *kernel_filename, const char *kernel_cmdline, ! 905: const char *initrd_filename, const char *cpu_model) ! 906: { ! 907: sun4m_hw_init(&hwdefs[3], RAM_size, boot_device, ds, kernel_filename, ! 908: kernel_cmdline, initrd_filename, cpu_model); ! 909: } ! 910: ! 911: /* SPARCstation 2 hardware initialisation */ ! 912: static void ss2_init(int RAM_size, int vga_ram_size, ! 913: const char *boot_device, DisplayState *ds, ! 914: const char *kernel_filename, const char *kernel_cmdline, ! 915: const char *initrd_filename, const char *cpu_model) ! 916: { ! 917: sun4c_hw_init(&hwdefs[4], RAM_size, boot_device, ds, kernel_filename, ! 918: kernel_cmdline, initrd_filename, cpu_model); ! 919: } ! 920: ! 921: QEMUMachine ss5_machine = { ! 922: "SS-5", ! 923: "Sun4m platform, SPARCstation 5", ! 924: ss5_init, ! 925: }; ! 926: ! 927: QEMUMachine ss10_machine = { ! 928: "SS-10", ! 929: "Sun4m platform, SPARCstation 10", ! 930: ss10_init, ! 931: }; ! 932: ! 933: QEMUMachine ss600mp_machine = { ! 934: "SS-600MP", ! 935: "Sun4m platform, SPARCserver 600MP", ! 936: ss600mp_init, ! 937: }; ! 938: ! 939: QEMUMachine ss20_machine = { ! 940: "SS-20", ! 941: "Sun4m platform, SPARCstation 20", ! 942: ss20_init, ! 943: }; ! 944: ! 945: QEMUMachine ss2_machine = { ! 946: "SS-2", ! 947: "Sun4c platform, SPARCstation 2", ! 948: ss2_init, ! 949: }; ! 950: ! 951: static const struct sun4d_hwdef sun4d_hwdefs[] = { ! 952: /* SS-1000 */ ! 953: { ! 954: .iounit_bases = { ! 955: 0xfe0200000ULL, ! 956: 0xfe1200000ULL, ! 957: 0xfe2200000ULL, ! 958: 0xfe3200000ULL, ! 959: -1, ! 960: }, ! 961: .tcx_base = 0x820000000ULL, ! 962: .slavio_base = 0xf00000000ULL, ! 963: .ms_kb_base = 0xf00240000ULL, ! 964: .serial_base = 0xf00200000ULL, ! 965: .nvram_base = 0xf00280000ULL, ! 966: .counter_base = 0xf00300000ULL, ! 967: .espdma_base = 0x800081000ULL, ! 968: .esp_base = 0x800080000ULL, ! 969: .ledma_base = 0x800040000ULL, ! 970: .le_base = 0x800060000ULL, ! 971: .sbi_base = 0xf02800000ULL, ! 972: .vram_size = 0x00100000, ! 973: .nvram_size = 0x2000, ! 974: .esp_irq = 3, ! 975: .le_irq = 4, ! 976: .clock_irq = 14, ! 977: .clock1_irq = 10, ! 978: .ms_kb_irq = 12, ! 979: .ser_irq = 12, ! 980: .machine_id = 0x80, ! 981: .iounit_version = 0x03000000, ! 982: .max_mem = 0xffffffff, // XXX actually first 62GB ok ! 983: .default_cpu_model = "TI SuperSparc II", ! 984: }, ! 985: /* SS-2000 */ ! 986: { ! 987: .iounit_bases = { ! 988: 0xfe0200000ULL, ! 989: 0xfe1200000ULL, ! 990: 0xfe2200000ULL, ! 991: 0xfe3200000ULL, ! 992: 0xfe4200000ULL, ! 993: }, ! 994: .tcx_base = 0x820000000ULL, ! 995: .slavio_base = 0xf00000000ULL, ! 996: .ms_kb_base = 0xf00240000ULL, ! 997: .serial_base = 0xf00200000ULL, ! 998: .nvram_base = 0xf00280000ULL, ! 999: .counter_base = 0xf00300000ULL, ! 1000: .espdma_base = 0x800081000ULL, ! 1001: .esp_base = 0x800080000ULL, ! 1002: .ledma_base = 0x800040000ULL, ! 1003: .le_base = 0x800060000ULL, ! 1004: .sbi_base = 0xf02800000ULL, ! 1005: .vram_size = 0x00100000, ! 1006: .nvram_size = 0x2000, ! 1007: .esp_irq = 3, ! 1008: .le_irq = 4, ! 1009: .clock_irq = 14, ! 1010: .clock1_irq = 10, ! 1011: .ms_kb_irq = 12, ! 1012: .ser_irq = 12, ! 1013: .machine_id = 0x80, ! 1014: .iounit_version = 0x03000000, ! 1015: .max_mem = 0xffffffff, // XXX actually first 62GB ok ! 1016: .default_cpu_model = "TI SuperSparc II", ! 1017: }, ! 1018: }; ! 1019: ! 1020: static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, int RAM_size, ! 1021: const char *boot_device, ! 1022: DisplayState *ds, const char *kernel_filename, ! 1023: const char *kernel_cmdline, ! 1024: const char *initrd_filename, const char *cpu_model) ! 1025: { ! 1026: CPUState *env, *envs[MAX_CPUS]; ! 1027: unsigned int i; ! 1028: void *iounits[MAX_IOUNITS], *espdma, *ledma, *main_esp, *nvram, *sbi; ! 1029: qemu_irq *cpu_irqs[MAX_CPUS], *sbi_irq, *sbi_cpu_irq, ! 1030: *espdma_irq, *ledma_irq; ! 1031: qemu_irq *esp_reset, *le_reset; ! 1032: unsigned long prom_offset, kernel_size; ! 1033: int ret; ! 1034: char buf[1024]; ! 1035: int index; ! 1036: ! 1037: /* init CPUs */ ! 1038: if (!cpu_model) ! 1039: cpu_model = hwdef->default_cpu_model; ! 1040: ! 1041: for (i = 0; i < smp_cpus; i++) { ! 1042: env = cpu_init(cpu_model); ! 1043: if (!env) { ! 1044: fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); ! 1045: exit(1); 1.1 root 1046: } 1.1.1.6 ! root 1047: cpu_sparc_set_id(env, i); ! 1048: envs[i] = env; ! 1049: if (i == 0) { ! 1050: qemu_register_reset(main_cpu_reset, env); ! 1051: } else { ! 1052: qemu_register_reset(secondary_cpu_reset, env); ! 1053: env->halted = 1; 1.1 root 1054: } 1.1.1.6 ! root 1055: register_savevm("cpu", i, 3, cpu_save, cpu_load, env); ! 1056: cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); ! 1057: env->prom_addr = hwdef->slavio_base; ! 1058: } ! 1059: ! 1060: for (i = smp_cpus; i < MAX_CPUS; i++) ! 1061: cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS); ! 1062: ! 1063: /* allocate RAM */ ! 1064: if ((uint64_t)RAM_size > hwdef->max_mem) { ! 1065: fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n", ! 1066: (unsigned int)RAM_size / (1024 * 1024), ! 1067: (unsigned int)(hwdef->max_mem / (1024 * 1024))); ! 1068: exit(1); 1.1 root 1069: } 1.1.1.6 ! root 1070: cpu_register_physical_memory(0, RAM_size, 0); ! 1071: ! 1072: /* load boot prom */ ! 1073: prom_offset = RAM_size + hwdef->vram_size; ! 1074: cpu_register_physical_memory(hwdef->slavio_base, ! 1075: (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & ! 1076: TARGET_PAGE_MASK, ! 1077: prom_offset | IO_MEM_ROM); ! 1078: ! 1079: if (bios_name == NULL) ! 1080: bios_name = PROM_FILENAME; ! 1081: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); ! 1082: ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); ! 1083: if (ret < 0 || ret > PROM_SIZE_MAX) ! 1084: ret = load_image(buf, phys_ram_base + prom_offset); ! 1085: if (ret < 0 || ret > PROM_SIZE_MAX) { ! 1086: fprintf(stderr, "qemu: could not load prom '%s'\n", ! 1087: buf); ! 1088: exit(1); ! 1089: } ! 1090: ! 1091: /* set up devices */ ! 1092: sbi = sbi_init(hwdef->sbi_base, &sbi_irq, &sbi_cpu_irq, cpu_irqs); ! 1093: ! 1094: for (i = 0; i < MAX_IOUNITS; i++) ! 1095: if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1) ! 1096: iounits[i] = iommu_init(hwdef->iounit_bases[i], ! 1097: hwdef->iounit_version, ! 1098: sbi_irq[hwdef->me_irq]); ! 1099: ! 1100: espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[hwdef->esp_irq], ! 1101: iounits[0], &espdma_irq, &esp_reset); ! 1102: ! 1103: ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[hwdef->le_irq], ! 1104: iounits[0], &ledma_irq, &le_reset); ! 1105: ! 1106: if (graphic_depth != 8 && graphic_depth != 24) { ! 1107: fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); ! 1108: exit (1); ! 1109: } ! 1110: tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size, ! 1111: hwdef->vram_size, graphic_width, graphic_height, graphic_depth); ! 1112: ! 1113: if (nd_table[0].model == NULL ! 1114: || strcmp(nd_table[0].model, "lance") == 0) { ! 1115: lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); ! 1116: } else if (strcmp(nd_table[0].model, "?") == 0) { ! 1117: fprintf(stderr, "qemu: Supported NICs: lance\n"); ! 1118: exit (1); ! 1119: } else { ! 1120: fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); ! 1121: exit (1); ! 1122: } ! 1123: ! 1124: nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0, ! 1125: hwdef->nvram_size, 8); ! 1126: ! 1127: slavio_timer_init_all(hwdef->counter_base, sbi_irq[hwdef->clock1_irq], ! 1128: sbi_cpu_irq, smp_cpus); ! 1129: ! 1130: slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[hwdef->ms_kb_irq], ! 1131: nographic); ! 1132: // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device ! 1133: // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device ! 1134: slavio_serial_init(hwdef->serial_base, sbi_irq[hwdef->ser_irq], ! 1135: serial_hds[1], serial_hds[0]); ! 1136: ! 1137: if (drive_get_max_bus(IF_SCSI) > 0) { ! 1138: fprintf(stderr, "qemu: too many SCSI bus\n"); ! 1139: exit(1); ! 1140: } ! 1141: ! 1142: main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq, ! 1143: esp_reset); ! 1144: ! 1145: for (i = 0; i < ESP_MAX_DEVS; i++) { ! 1146: index = drive_get_index(IF_SCSI, 0, i); ! 1147: if (index == -1) ! 1148: continue; ! 1149: esp_scsi_attach(main_esp, drives_table[index].bdrv, i); ! 1150: } ! 1151: ! 1152: kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline, ! 1153: initrd_filename); ! 1154: ! 1155: nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, ! 1156: boot_device, RAM_size, kernel_size, graphic_width, ! 1157: graphic_height, graphic_depth, hwdef->machine_id, "Sun4d"); ! 1158: } ! 1159: ! 1160: /* SPARCserver 1000 hardware initialisation */ ! 1161: static void ss1000_init(int RAM_size, int vga_ram_size, ! 1162: const char *boot_device, DisplayState *ds, ! 1163: const char *kernel_filename, const char *kernel_cmdline, ! 1164: const char *initrd_filename, const char *cpu_model) ! 1165: { ! 1166: sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, ds, kernel_filename, ! 1167: kernel_cmdline, initrd_filename, cpu_model); 1.1 root 1168: } 1169: 1.1.1.6 ! root 1170: /* SPARCcenter 2000 hardware initialisation */ ! 1171: static void ss2000_init(int RAM_size, int vga_ram_size, ! 1172: const char *boot_device, DisplayState *ds, ! 1173: const char *kernel_filename, const char *kernel_cmdline, ! 1174: const char *initrd_filename, const char *cpu_model) ! 1175: { ! 1176: sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, ds, kernel_filename, ! 1177: kernel_cmdline, initrd_filename, cpu_model); ! 1178: } ! 1179: ! 1180: QEMUMachine ss1000_machine = { ! 1181: "SS-1000", ! 1182: "Sun4d platform, SPARCserver 1000", ! 1183: ss1000_init, ! 1184: }; ! 1185: ! 1186: QEMUMachine ss2000_machine = { ! 1187: "SS-2000", ! 1188: "Sun4d platform, SPARCcenter 2000", ! 1189: ss2000_init, 1.1 root 1190: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.