|
|
1.1 root 1: /* 1.1.1.7 ! root 2: * QEMU Sun4u/Sun4v System Emulator 1.1.1.6 root 3: * 1.1 root 4: * Copyright (c) 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 "pci.h" 26: #include "pc.h" 27: #include "nvram.h" 28: #include "fdc.h" 29: #include "net.h" 30: #include "qemu-timer.h" 31: #include "sysemu.h" 32: #include "boards.h" 33: #include "firmware_abi.h" 1.1.1.7 ! root 34: #include "fw_cfg.h" ! 35: ! 36: //#define DEBUG_IRQ ! 37: ! 38: #ifdef DEBUG_IRQ ! 39: #define DPRINTF(fmt, args...) \ ! 40: do { printf("CPUIRQ: " fmt , ##args); } while (0) ! 41: #else ! 42: #define DPRINTF(fmt, args...) ! 43: #endif 1.1 root 44: 45: #define KERNEL_LOAD_ADDR 0x00404000 46: #define CMDLINE_ADDR 0x003ff000 47: #define INITRD_LOAD_ADDR 0x00300000 1.1.1.7 ! root 48: #define PROM_SIZE_MAX (4 * 1024 * 1024) 1.1.1.6 root 49: #define PROM_VADDR 0x000ffd00000ULL 1.1 root 50: #define APB_SPECIAL_BASE 0x1fe00000000ULL 1.1.1.6 root 51: #define APB_MEM_BASE 0x1ff00000000ULL 52: #define VGA_BASE (APB_MEM_BASE + 0x400000ULL) 53: #define PROM_FILENAME "openbios-sparc64" 1.1 root 54: #define NVRAM_SIZE 0x2000 1.1.1.6 root 55: #define MAX_IDE_BUS 2 1.1.1.7 ! root 56: #define BIOS_CFG_IOPORT 0x510 1.1 root 57: 1.1.1.7 ! root 58: #define MAX_PILS 16 1.1 root 59: 1.1.1.7 ! root 60: #define TICK_INT_DIS 0x8000000000000000ULL ! 61: #define TICK_MAX 0x7fffffffffffffffULL ! 62: ! 63: struct hwdef { ! 64: const char * const default_cpu_model; ! 65: uint16_t machine_id; ! 66: uint64_t prom_addr; ! 67: uint64_t console_serial_base; ! 68: }; 1.1 root 69: 70: int DMA_get_channel_mode (int nchan) 71: { 72: return 0; 73: } 74: int DMA_read_memory (int nchan, void *buf, int pos, int size) 75: { 76: return 0; 77: } 78: int DMA_write_memory (int nchan, void *buf, int pos, int size) 79: { 80: return 0; 81: } 82: void DMA_hold_DREQ (int nchan) {} 83: void DMA_release_DREQ (int nchan) {} 84: void DMA_schedule(int nchan) {} 85: void DMA_init (int high_page_enable) {} 86: void DMA_register_channel (int nchan, 87: DMA_transfer_handler transfer_handler, 88: void *opaque) 89: { 90: } 91: 1.1.1.7 ! root 92: static int nvram_boot_set(void *opaque, const char *boot_device) ! 93: { ! 94: unsigned int i; ! 95: uint8_t image[sizeof(ohwcfg_v3_t)]; ! 96: ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ ! 97: m48t59_t *nvram = (m48t59_t *)opaque; ! 98: ! 99: for (i = 0; i < sizeof(image); i++) ! 100: image[i] = m48t59_read(nvram, i) & 0xff; ! 101: ! 102: pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices), ! 103: boot_device); ! 104: header->nboot_devices = strlen(boot_device) & 0xff; ! 105: header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); ! 106: ! 107: for (i = 0; i < sizeof(image); i++) ! 108: m48t59_write(nvram, i, image[i]); ! 109: ! 110: return 0; ! 111: } 1.1 root 112: 1.1.1.6 root 113: static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, 1.1.1.7 ! root 114: const char *arch, ! 115: ram_addr_t RAM_size, ! 116: const char *boot_devices, 1.1.1.6 root 117: uint32_t kernel_image, uint32_t kernel_size, 118: const char *cmdline, 119: uint32_t initrd_image, uint32_t initrd_size, 120: uint32_t NVRAM_image, 1.1.1.7 ! root 121: int width, int height, int depth, ! 122: const uint8_t *macaddr) 1.1 root 123: { 1.1.1.6 root 124: unsigned int i; 125: uint32_t start, end; 126: uint8_t image[0x1ff0]; 127: ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ 128: struct sparc_arch_cfg *sparc_header; 129: struct OpenBIOS_nvpart_v1 *part_header; 130: 131: memset(image, '\0', sizeof(image)); 132: 133: // Try to match PPC NVRAM 1.1.1.7 ! root 134: pstrcpy((char *)header->struct_ident, sizeof(header->struct_ident), ! 135: "QEMU_BIOS"); 1.1.1.6 root 136: header->struct_version = cpu_to_be32(3); /* structure v3 */ 137: 138: header->nvram_size = cpu_to_be16(NVRAM_size); 139: header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); 140: header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); 1.1.1.7 ! root 141: pstrcpy((char *)header->arch, sizeof(header->arch), arch); 1.1.1.6 root 142: header->nb_cpus = smp_cpus & 0xff; 143: header->RAM0_base = 0; 144: header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); 1.1.1.7 ! root 145: pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices), ! 146: boot_devices); 1.1.1.6 root 147: header->nboot_devices = strlen(boot_devices) & 0xff; 148: header->kernel_image = cpu_to_be64((uint64_t)kernel_image); 149: header->kernel_size = cpu_to_be64((uint64_t)kernel_size); 150: if (cmdline) { 1.1.1.7 ! root 151: pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline); 1.1.1.6 root 152: header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); 153: header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); 154: } 155: header->initrd_image = cpu_to_be64((uint64_t)initrd_image); 156: header->initrd_size = cpu_to_be64((uint64_t)initrd_size); 157: header->NVRAM_image = cpu_to_be64((uint64_t)NVRAM_image); 158: 159: header->width = cpu_to_be16(width); 160: header->height = cpu_to_be16(height); 161: header->depth = cpu_to_be16(depth); 162: if (nographic) 163: header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS); 164: 165: header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); 166: 167: // Architecture specific header 168: start = sizeof(ohwcfg_v3_t); 169: sparc_header = (struct sparc_arch_cfg *)&image[start]; 170: sparc_header->valid = 0; 171: start += sizeof(struct sparc_arch_cfg); 172: 173: // OpenBIOS nvram variables 174: // Variable partition 175: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; 176: part_header->signature = OPENBIOS_PART_SYSTEM; 1.1.1.7 ! root 177: pstrcpy(part_header->name, sizeof(part_header->name), "system"); 1.1.1.6 root 178: 179: end = start + sizeof(struct OpenBIOS_nvpart_v1); 180: for (i = 0; i < nb_prom_envs; i++) 181: end = OpenBIOS_set_var(image, end, prom_envs[i]); 182: 183: // End marker 184: image[end++] = '\0'; 185: 186: end = start + ((end - start + 15) & ~15); 187: OpenBIOS_finish_partition(part_header, end - start); 188: 189: // free partition 190: start = end; 191: part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; 192: part_header->signature = OPENBIOS_PART_FREE; 1.1.1.7 ! root 193: pstrcpy(part_header->name, sizeof(part_header->name), "free"); 1.1 root 194: 1.1.1.6 root 195: end = 0x1fd0; 196: OpenBIOS_finish_partition(part_header, end - start); 1.1 root 197: 1.1.1.7 ! root 198: Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80); ! 199: 1.1.1.6 root 200: for (i = 0; i < sizeof(image); i++) 201: m48t59_write(nvram, i, image[i]); 1.1 root 202: 1.1.1.7 ! root 203: qemu_register_boot_set(nvram_boot_set, nvram); ! 204: 1.1.1.6 root 205: return 0; 1.1 root 206: } 207: 1.1.1.7 ! root 208: void pic_info(void) 1.1 root 209: { 210: } 211: 1.1.1.7 ! root 212: void irq_info(void) 1.1 root 213: { 214: } 215: 1.1.1.7 ! root 216: void cpu_check_irqs(CPUState *env) ! 217: { ! 218: uint32_t pil = env->pil_in | (env->softint & ~SOFTINT_TIMER) | ! 219: ((env->softint & SOFTINT_TIMER) << 14); ! 220: ! 221: if (pil && (env->interrupt_index == 0 || ! 222: (env->interrupt_index & ~15) == TT_EXTINT)) { ! 223: unsigned int i; ! 224: ! 225: for (i = 15; i > 0; i--) { ! 226: if (pil & (1 << i)) { ! 227: int old_interrupt = env->interrupt_index; ! 228: ! 229: env->interrupt_index = TT_EXTINT | i; ! 230: if (old_interrupt != env->interrupt_index) { ! 231: DPRINTF("Set CPU IRQ %d\n", i); ! 232: cpu_interrupt(env, CPU_INTERRUPT_HARD); ! 233: } ! 234: break; ! 235: } ! 236: } ! 237: } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) { ! 238: DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15); ! 239: env->interrupt_index = 0; ! 240: cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); ! 241: } ! 242: } ! 243: ! 244: static void cpu_set_irq(void *opaque, int irq, int level) ! 245: { ! 246: CPUState *env = opaque; ! 247: ! 248: if (level) { ! 249: DPRINTF("Raise CPU IRQ %d\n", irq); ! 250: env->halted = 0; ! 251: env->pil_in |= 1 << irq; ! 252: cpu_check_irqs(env); ! 253: } else { ! 254: DPRINTF("Lower CPU IRQ %d\n", irq); ! 255: env->pil_in &= ~(1 << irq); ! 256: cpu_check_irqs(env); ! 257: } ! 258: } ! 259: 1.1.1.6 root 260: void qemu_system_powerdown(void) 1.1 root 261: { 262: } 263: 1.1.1.7 ! root 264: typedef struct ResetData { ! 265: CPUState *env; ! 266: uint64_t reset_addr; ! 267: } ResetData; ! 268: 1.1.1.6 root 269: static void main_cpu_reset(void *opaque) 1.1 root 270: { 1.1.1.7 ! root 271: ResetData *s = (ResetData *)opaque; ! 272: CPUState *env = s->env; 1.1 root 273: 1.1.1.6 root 274: cpu_reset(env); 1.1.1.7 ! root 275: env->tick_cmpr = TICK_INT_DIS | 0; ! 276: ptimer_set_limit(env->tick, TICK_MAX, 1); ! 277: ptimer_run(env->tick, 1); ! 278: env->stick_cmpr = TICK_INT_DIS | 0; ! 279: ptimer_set_limit(env->stick, TICK_MAX, 1); ! 280: ptimer_run(env->stick, 1); ! 281: env->hstick_cmpr = TICK_INT_DIS | 0; ! 282: ptimer_set_limit(env->hstick, TICK_MAX, 1); ! 283: ptimer_run(env->hstick, 1); ! 284: env->gregs[1] = 0; // Memory start ! 285: env->gregs[2] = ram_size; // Memory size ! 286: env->gregs[3] = 0; // Machine description XXX ! 287: env->pc = s->reset_addr; ! 288: env->npc = env->pc + 4; 1.1 root 289: } 290: 1.1.1.7 ! root 291: static void tick_irq(void *opaque) 1.1 root 292: { 1.1.1.6 root 293: CPUState *env = opaque; 1.1 root 294: 1.1.1.7 ! root 295: if (!(env->tick_cmpr & TICK_INT_DIS)) { ! 296: env->softint |= SOFTINT_TIMER; ! 297: cpu_interrupt(env, CPU_INTERRUPT_TIMER); ! 298: } 1.1 root 299: } 300: 1.1.1.7 ! root 301: static void stick_irq(void *opaque) 1.1 root 302: { 1.1.1.6 root 303: CPUState *env = opaque; 1.1 root 304: 1.1.1.7 ! root 305: if (!(env->stick_cmpr & TICK_INT_DIS)) { ! 306: env->softint |= SOFTINT_STIMER; ! 307: cpu_interrupt(env, CPU_INTERRUPT_TIMER); ! 308: } 1.1 root 309: } 310: 1.1.1.7 ! root 311: static void hstick_irq(void *opaque) 1.1 root 312: { 1.1.1.6 root 313: CPUState *env = opaque; 1.1 root 314: 1.1.1.7 ! root 315: if (!(env->hstick_cmpr & TICK_INT_DIS)) { ! 316: cpu_interrupt(env, CPU_INTERRUPT_TIMER); ! 317: } ! 318: } ! 319: ! 320: void cpu_tick_set_count(void *opaque, uint64_t count) ! 321: { ! 322: ptimer_set_count(opaque, -count); 1.1 root 323: } 324: 1.1.1.7 ! root 325: uint64_t cpu_tick_get_count(void *opaque) 1.1.1.2 root 326: { 1.1.1.7 ! root 327: return -ptimer_get_count(opaque); ! 328: } ! 329: ! 330: void cpu_tick_set_limit(void *opaque, uint64_t limit) ! 331: { ! 332: ptimer_set_limit(opaque, -limit, 0); 1.1.1.2 root 333: } 334: 1.1 root 335: static const int ide_iobase[2] = { 0x1f0, 0x170 }; 336: static const int ide_iobase2[2] = { 0x3f6, 0x376 }; 337: static const int ide_irq[2] = { 14, 15 }; 338: 339: static const int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; 340: static const int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; 341: 342: static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; 343: static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; 344: 345: static fdctrl_t *floppy_controller; 346: 1.1.1.7 ! root 347: static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num, ! 348: uint32_t addr, uint32_t size, int type) ! 349: { ! 350: DPRINTF("Mapping region %d registers at %08x\n", region_num, addr); ! 351: switch (region_num) { ! 352: case 0: ! 353: isa_mmio_init(addr, 0x1000000); ! 354: break; ! 355: case 1: ! 356: isa_mmio_init(addr, 0x800000); ! 357: break; ! 358: } ! 359: } ! 360: ! 361: /* EBUS (Eight bit bus) bridge */ ! 362: static void ! 363: pci_ebus_init(PCIBus *bus, int devfn) ! 364: { ! 365: PCIDevice *s; ! 366: ! 367: s = pci_register_device(bus, "EBUS", sizeof(*s), devfn, NULL, NULL); ! 368: pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN); ! 369: pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS); ! 370: s->config[0x04] = 0x06; // command = bus master, pci mem ! 371: s->config[0x05] = 0x00; ! 372: s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error ! 373: s->config[0x07] = 0x03; // status = medium devsel ! 374: s->config[0x08] = 0x01; // revision ! 375: s->config[0x09] = 0x00; // programming i/f ! 376: pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER); ! 377: s->config[0x0D] = 0x0a; // latency_timer ! 378: s->config[0x0E] = 0x00; // header_type ! 379: ! 380: pci_register_io_region(s, 0, 0x1000000, PCI_ADDRESS_SPACE_MEM, ! 381: ebus_mmio_mapfunc); ! 382: pci_register_io_region(s, 1, 0x800000, PCI_ADDRESS_SPACE_MEM, ! 383: ebus_mmio_mapfunc); ! 384: } ! 385: ! 386: static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, ! 387: const char *boot_devices, ! 388: const char *kernel_filename, const char *kernel_cmdline, ! 389: const char *initrd_filename, const char *cpu_model, ! 390: const struct hwdef *hwdef) 1.1 root 391: { 1.1.1.2 root 392: CPUState *env; 1.1 root 393: char buf[1024]; 394: m48t59_t *nvram; 395: int ret, linux_boot; 396: unsigned int i; 1.1.1.7 ! root 397: ram_addr_t ram_offset, prom_offset, vga_ram_offset; ! 398: long initrd_size, kernel_size; ! 399: PCIBus *pci_bus, *pci_bus2, *pci_bus3; 1.1.1.6 root 400: QEMUBH *bh; 401: qemu_irq *irq; 1.1.1.7 ! root 402: int drive_index; 1.1.1.6 root 403: BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; 404: BlockDriverState *fd[MAX_FD]; 1.1.1.7 ! root 405: void *fw_cfg; ! 406: ResetData *reset_info; 1.1 root 407: 408: linux_boot = (kernel_filename != NULL); 409: 1.1.1.6 root 410: /* init CPUs */ 1.1.1.7 ! root 411: if (!cpu_model) ! 412: cpu_model = hwdef->default_cpu_model; ! 413: 1.1.1.6 root 414: env = cpu_init(cpu_model); 415: if (!env) { 416: fprintf(stderr, "Unable to find Sparc CPU definition\n"); 417: exit(1); 418: } 419: bh = qemu_bh_new(tick_irq, env); 420: env->tick = ptimer_init(bh); 421: ptimer_set_period(env->tick, 1ULL); 422: 423: bh = qemu_bh_new(stick_irq, env); 424: env->stick = ptimer_init(bh); 425: ptimer_set_period(env->stick, 1ULL); 426: 427: bh = qemu_bh_new(hstick_irq, env); 428: env->hstick = ptimer_init(bh); 429: ptimer_set_period(env->hstick, 1ULL); 1.1.1.7 ! root 430: ! 431: reset_info = qemu_mallocz(sizeof(ResetData)); ! 432: reset_info->env = env; ! 433: reset_info->reset_addr = hwdef->prom_addr + 0x40ULL; ! 434: qemu_register_reset(main_cpu_reset, reset_info); ! 435: main_cpu_reset(reset_info); ! 436: // Override warm reset address with cold start address ! 437: env->pc = hwdef->prom_addr + 0x20ULL; ! 438: env->npc = env->pc + 4; 1.1.1.2 root 439: 1.1 root 440: /* allocate RAM */ 1.1.1.7 ! root 441: ram_offset = qemu_ram_alloc(RAM_size); ! 442: cpu_register_physical_memory(0, RAM_size, ram_offset); 1.1 root 443: 1.1.1.7 ! root 444: prom_offset = qemu_ram_alloc(PROM_SIZE_MAX); ! 445: cpu_register_physical_memory(hwdef->prom_addr, ! 446: (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & ! 447: TARGET_PAGE_MASK, 1.1.1.3 root 448: prom_offset | IO_MEM_ROM); 1.1 root 449: 1.1.1.6 root 450: if (bios_name == NULL) 451: bios_name = PROM_FILENAME; 452: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); 1.1.1.7 ! root 453: ret = load_elf(buf, hwdef->prom_addr - PROM_VADDR, NULL, NULL, NULL); 1.1 root 454: if (ret < 0) { 1.1.1.7 ! root 455: ret = load_image_targphys(buf, hwdef->prom_addr, ! 456: (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & ! 457: TARGET_PAGE_MASK); ! 458: if (ret < 0) { ! 459: fprintf(stderr, "qemu: could not load prom '%s'\n", ! 460: buf); ! 461: exit(1); ! 462: } 1.1 root 463: } 464: 465: kernel_size = 0; 466: initrd_size = 0; 467: if (linux_boot) { 1.1.1.3 root 468: /* XXX: put correct offset */ 1.1.1.6 root 469: kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL); 1.1 root 470: if (kernel_size < 0) 1.1.1.7 ! root 471: kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, ! 472: ram_size - KERNEL_LOAD_ADDR); 1.1.1.6 root 473: if (kernel_size < 0) 1.1.1.7 ! root 474: kernel_size = load_image_targphys(kernel_filename, ! 475: KERNEL_LOAD_ADDR, ! 476: ram_size - KERNEL_LOAD_ADDR); 1.1 root 477: if (kernel_size < 0) { 1.1.1.6 root 478: fprintf(stderr, "qemu: could not load kernel '%s'\n", 1.1 root 479: kernel_filename); 1.1.1.6 root 480: exit(1); 1.1 root 481: } 482: 483: /* load initrd */ 484: if (initrd_filename) { 1.1.1.7 ! root 485: initrd_size = load_image_targphys(initrd_filename, ! 486: INITRD_LOAD_ADDR, ! 487: ram_size - INITRD_LOAD_ADDR); 1.1 root 488: if (initrd_size < 0) { 1.1.1.6 root 489: fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 1.1 root 490: initrd_filename); 491: exit(1); 492: } 493: } 494: if (initrd_size > 0) { 1.1.1.6 root 495: for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { 1.1.1.7 ! root 496: if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS ! 497: stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR); ! 498: stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size); 1.1.1.6 root 499: break; 500: } 501: } 1.1 root 502: } 503: } 1.1.1.7 ! root 504: pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL, &pci_bus2, ! 505: &pci_bus3); 1.1 root 506: isa_mem_base = VGA_BASE; 1.1.1.7 ! root 507: vga_ram_offset = qemu_ram_alloc(vga_ram_size); ! 508: pci_vga_init(pci_bus, phys_ram_base + vga_ram_offset, ! 509: vga_ram_offset, vga_ram_size, ! 510: 0, 0); ! 511: ! 512: // XXX Should be pci_bus3 ! 513: pci_ebus_init(pci_bus, -1); ! 514: ! 515: i = 0; ! 516: if (hwdef->console_serial_base) { ! 517: serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200, ! 518: serial_hds[i], 1); ! 519: i++; ! 520: } ! 521: for(; i < MAX_SERIAL_PORTS; i++) { 1.1 root 522: if (serial_hds[i]) { 1.1.1.7 ! root 523: serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200, ! 524: serial_hds[i]); 1.1 root 525: } 526: } 527: 528: for(i = 0; i < MAX_PARALLEL_PORTS; i++) { 529: if (parallel_hds[i]) { 1.1.1.7 ! root 530: parallel_init(parallel_io[i], NULL/*parallel_irq[i]*/, ! 531: parallel_hds[i]); 1.1 root 532: } 533: } 534: 1.1.1.7 ! root 535: for(i = 0; i < nb_nics; i++) ! 536: pci_nic_init(pci_bus, &nd_table[i], -1, "ne2k_pci"); 1.1 root 537: 1.1.1.7 ! root 538: irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); 1.1.1.6 root 539: if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { 540: fprintf(stderr, "qemu: too many IDE bus\n"); 541: exit(1); 542: } 543: for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { 1.1.1.7 ! root 544: drive_index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, ! 545: i % MAX_IDE_DEVS); ! 546: if (drive_index != -1) ! 547: hd[i] = drives_table[drive_index].bdrv; 1.1.1.6 root 548: else 549: hd[i] = NULL; 550: } 551: 1.1.1.7 ! root 552: pci_cmd646_ide_init(pci_bus, hd, 1); ! 553: 1.1.1.6 root 554: /* FIXME: wire up interrupts. */ 555: i8042_init(NULL/*1*/, NULL/*12*/, 0x60); 556: for(i = 0; i < MAX_FD; i++) { 1.1.1.7 ! root 557: drive_index = drive_get_index(IF_FLOPPY, 0, i); ! 558: if (drive_index != -1) ! 559: fd[i] = drives_table[drive_index].bdrv; 1.1.1.6 root 560: else 561: fd[i] = NULL; 562: } 563: floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd); 564: nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); 1.1.1.7 ! root 565: sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices, ! 566: KERNEL_LOAD_ADDR, kernel_size, ! 567: kernel_cmdline, ! 568: INITRD_LOAD_ADDR, initrd_size, ! 569: /* XXX: need an option to load a NVRAM image */ ! 570: 0, ! 571: graphic_width, graphic_height, graphic_depth, ! 572: (uint8_t *)&nd_table[0].macaddr); ! 573: ! 574: fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0); ! 575: fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); ! 576: fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); ! 577: fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); ! 578: } ! 579: ! 580: enum { ! 581: sun4u_id = 0, ! 582: sun4v_id = 64, ! 583: niagara_id, ! 584: }; 1.1 root 585: 1.1.1.7 ! root 586: static const struct hwdef hwdefs[] = { ! 587: /* Sun4u generic PC-like machine */ ! 588: { ! 589: .default_cpu_model = "TI UltraSparc II", ! 590: .machine_id = sun4u_id, ! 591: .prom_addr = 0x1fff0000000ULL, ! 592: .console_serial_base = 0, ! 593: }, ! 594: /* Sun4v generic PC-like machine */ ! 595: { ! 596: .default_cpu_model = "Sun UltraSparc T1", ! 597: .machine_id = sun4v_id, ! 598: .prom_addr = 0x1fff0000000ULL, ! 599: .console_serial_base = 0, ! 600: }, ! 601: /* Sun4v generic Niagara machine */ ! 602: { ! 603: .default_cpu_model = "Sun UltraSparc T1", ! 604: .machine_id = niagara_id, ! 605: .prom_addr = 0xfff0000000ULL, ! 606: .console_serial_base = 0xfff0c2c000ULL, ! 607: }, ! 608: }; ! 609: ! 610: /* Sun4u hardware initialisation */ ! 611: static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size, ! 612: const char *boot_devices, ! 613: const char *kernel_filename, const char *kernel_cmdline, ! 614: const char *initrd_filename, const char *cpu_model) ! 615: { ! 616: sun4uv_init(RAM_size, vga_ram_size, boot_devices, kernel_filename, ! 617: kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]); ! 618: } ! 619: ! 620: /* Sun4v hardware initialisation */ ! 621: static void sun4v_init(ram_addr_t RAM_size, int vga_ram_size, ! 622: const char *boot_devices, ! 623: const char *kernel_filename, const char *kernel_cmdline, ! 624: const char *initrd_filename, const char *cpu_model) ! 625: { ! 626: sun4uv_init(RAM_size, vga_ram_size, boot_devices, kernel_filename, ! 627: kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]); ! 628: } ! 629: ! 630: /* Niagara hardware initialisation */ ! 631: static void niagara_init(ram_addr_t RAM_size, int vga_ram_size, ! 632: const char *boot_devices, ! 633: const char *kernel_filename, const char *kernel_cmdline, ! 634: const char *initrd_filename, const char *cpu_model) ! 635: { ! 636: sun4uv_init(RAM_size, vga_ram_size, boot_devices, kernel_filename, ! 637: kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]); 1.1 root 638: } 639: 640: QEMUMachine sun4u_machine = { 1.1.1.7 ! root 641: .name = "sun4u", ! 642: .desc = "Sun4u platform", ! 643: .init = sun4u_init, ! 644: .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, ! 645: .nodisk_ok = 1, ! 646: .max_cpus = 1, // XXX for now ! 647: }; ! 648: ! 649: QEMUMachine sun4v_machine = { ! 650: .name = "sun4v", ! 651: .desc = "Sun4v platform", ! 652: .init = sun4v_init, ! 653: .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, ! 654: .nodisk_ok = 1, ! 655: .max_cpus = 1, // XXX for now ! 656: }; ! 657: ! 658: QEMUMachine niagara_machine = { ! 659: .name = "Niagara", ! 660: .desc = "Sun4v platform, Niagara", ! 661: .init = niagara_init, ! 662: .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, ! 663: .nodisk_ok = 1, ! 664: .max_cpus = 1, // XXX for now 1.1 root 665: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.