|
|
1.1 ! root 1: /* ! 2: * QEMU PC System Emulator ! 3: * ! 4: * Copyright (c) 2003-2004 Fabrice Bellard ! 5: * ! 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: */ ! 24: #include "vl.h" ! 25: ! 26: /* output Bochs bios info messages */ ! 27: //#define DEBUG_BIOS ! 28: ! 29: #define BIOS_FILENAME "bios.bin" ! 30: #define VGABIOS_FILENAME "vgabios.bin" ! 31: #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin" ! 32: #define LINUX_BOOT_FILENAME "linux_boot.bin" ! 33: ! 34: #define KERNEL_LOAD_ADDR 0x00100000 ! 35: #define INITRD_LOAD_ADDR 0x00400000 ! 36: #define KERNEL_PARAMS_ADDR 0x00090000 ! 37: #define KERNEL_CMDLINE_ADDR 0x00099000 ! 38: ! 39: int speaker_data_on; ! 40: int dummy_refresh_clock; ! 41: static fdctrl_t *floppy_controller; ! 42: static RTCState *rtc_state; ! 43: static PITState *pit; ! 44: static IOAPICState *ioapic; ! 45: ! 46: static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) ! 47: { ! 48: } ! 49: ! 50: /* MSDOS compatibility mode FPU exception support */ ! 51: /* XXX: add IGNNE support */ ! 52: void cpu_set_ferr(CPUX86State *s) ! 53: { ! 54: pic_set_irq(13, 1); ! 55: } ! 56: ! 57: static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data) ! 58: { ! 59: pic_set_irq(13, 0); ! 60: } ! 61: ! 62: /* TSC handling */ ! 63: ! 64: uint64_t cpu_get_tsc(CPUX86State *env) ! 65: { ! 66: return qemu_get_clock(vm_clock); ! 67: } ! 68: ! 69: /* IRQ handling */ ! 70: int cpu_get_pic_interrupt(CPUState *env) ! 71: { ! 72: int intno; ! 73: ! 74: intno = apic_get_interrupt(env); ! 75: if (intno >= 0) { ! 76: /* set irq request if a PIC irq is still pending */ ! 77: /* XXX: improve that */ ! 78: pic_update_irq(isa_pic); ! 79: return intno; ! 80: } ! 81: /* read the irq from the PIC */ ! 82: intno = pic_read_irq(isa_pic); ! 83: return intno; ! 84: } ! 85: ! 86: static void pic_irq_request(void *opaque, int level) ! 87: { ! 88: if (level) ! 89: cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); ! 90: else ! 91: cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); ! 92: } ! 93: ! 94: /* PC cmos mappings */ ! 95: ! 96: #define REG_EQUIPMENT_BYTE 0x14 ! 97: #define REG_IBM_CENTURY_BYTE 0x32 ! 98: #define REG_IBM_PS2_CENTURY_BYTE 0x37 ! 99: ! 100: ! 101: static inline int to_bcd(RTCState *s, int a) ! 102: { ! 103: return ((a / 10) << 4) | (a % 10); ! 104: } ! 105: ! 106: static int cmos_get_fd_drive_type(int fd0) ! 107: { ! 108: int val; ! 109: ! 110: switch (fd0) { ! 111: case 0: ! 112: /* 1.44 Mb 3"5 drive */ ! 113: val = 4; ! 114: break; ! 115: case 1: ! 116: /* 2.88 Mb 3"5 drive */ ! 117: val = 5; ! 118: break; ! 119: case 2: ! 120: /* 1.2 Mb 5"5 drive */ ! 121: val = 2; ! 122: break; ! 123: default: ! 124: val = 0; ! 125: break; ! 126: } ! 127: return val; ! 128: } ! 129: ! 130: static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd) ! 131: { ! 132: RTCState *s = rtc_state; ! 133: int cylinders, heads, sectors; ! 134: bdrv_get_geometry_hint(hd, &cylinders, &heads, §ors); ! 135: rtc_set_memory(s, type_ofs, 47); ! 136: rtc_set_memory(s, info_ofs, cylinders); ! 137: rtc_set_memory(s, info_ofs + 1, cylinders >> 8); ! 138: rtc_set_memory(s, info_ofs + 2, heads); ! 139: rtc_set_memory(s, info_ofs + 3, 0xff); ! 140: rtc_set_memory(s, info_ofs + 4, 0xff); ! 141: rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3)); ! 142: rtc_set_memory(s, info_ofs + 6, cylinders); ! 143: rtc_set_memory(s, info_ofs + 7, cylinders >> 8); ! 144: rtc_set_memory(s, info_ofs + 8, sectors); ! 145: } ! 146: ! 147: /* hd_table must contain 4 block drivers */ ! 148: static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table) ! 149: { ! 150: RTCState *s = rtc_state; ! 151: int val; ! 152: int fd0, fd1, nb; ! 153: time_t ti; ! 154: struct tm *tm; ! 155: int i; ! 156: ! 157: /* set the CMOS date */ ! 158: time(&ti); ! 159: if (rtc_utc) ! 160: tm = gmtime(&ti); ! 161: else ! 162: tm = localtime(&ti); ! 163: rtc_set_date(s, tm); ! 164: ! 165: val = to_bcd(s, (tm->tm_year / 100) + 19); ! 166: rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val); ! 167: rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val); ! 168: ! 169: /* various important CMOS locations needed by PC/Bochs bios */ ! 170: ! 171: /* memory size */ ! 172: val = 640; /* base memory in K */ ! 173: rtc_set_memory(s, 0x15, val); ! 174: rtc_set_memory(s, 0x16, val >> 8); ! 175: ! 176: val = (ram_size / 1024) - 1024; ! 177: if (val > 65535) ! 178: val = 65535; ! 179: rtc_set_memory(s, 0x17, val); ! 180: rtc_set_memory(s, 0x18, val >> 8); ! 181: rtc_set_memory(s, 0x30, val); ! 182: rtc_set_memory(s, 0x31, val >> 8); ! 183: ! 184: if (ram_size > (16 * 1024 * 1024)) ! 185: val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536); ! 186: else ! 187: val = 0; ! 188: if (val > 65535) ! 189: val = 65535; ! 190: rtc_set_memory(s, 0x34, val); ! 191: rtc_set_memory(s, 0x35, val >> 8); ! 192: ! 193: switch(boot_device) { ! 194: case 'a': ! 195: case 'b': ! 196: rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */ ! 197: break; ! 198: default: ! 199: case 'c': ! 200: rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */ ! 201: break; ! 202: case 'd': ! 203: rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */ ! 204: break; ! 205: } ! 206: ! 207: /* floppy type */ ! 208: ! 209: fd0 = fdctrl_get_drive_type(floppy_controller, 0); ! 210: fd1 = fdctrl_get_drive_type(floppy_controller, 1); ! 211: ! 212: val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1); ! 213: rtc_set_memory(s, 0x10, val); ! 214: ! 215: val = 0; ! 216: nb = 0; ! 217: if (fd0 < 3) ! 218: nb++; ! 219: if (fd1 < 3) ! 220: nb++; ! 221: switch (nb) { ! 222: case 0: ! 223: break; ! 224: case 1: ! 225: val |= 0x01; /* 1 drive, ready for boot */ ! 226: break; ! 227: case 2: ! 228: val |= 0x41; /* 2 drives, ready for boot */ ! 229: break; ! 230: } ! 231: val |= 0x02; /* FPU is there */ ! 232: val |= 0x04; /* PS/2 mouse installed */ ! 233: rtc_set_memory(s, REG_EQUIPMENT_BYTE, val); ! 234: ! 235: /* hard drives */ ! 236: ! 237: rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0)); ! 238: if (hd_table[0]) ! 239: cmos_init_hd(0x19, 0x1b, hd_table[0]); ! 240: if (hd_table[1]) ! 241: cmos_init_hd(0x1a, 0x24, hd_table[1]); ! 242: ! 243: val = 0; ! 244: for (i = 0; i < 4; i++) { ! 245: if (hd_table[i]) { ! 246: int cylinders, heads, sectors, translation; ! 247: /* NOTE: bdrv_get_geometry_hint() returns the physical ! 248: geometry. It is always such that: 1 <= sects <= 63, 1 ! 249: <= heads <= 16, 1 <= cylinders <= 16383. The BIOS ! 250: geometry can be different if a translation is done. */ ! 251: translation = bdrv_get_translation_hint(hd_table[i]); ! 252: if (translation == BIOS_ATA_TRANSLATION_AUTO) { ! 253: bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, §ors); ! 254: if (cylinders <= 1024 && heads <= 16 && sectors <= 63) { ! 255: /* No translation. */ ! 256: translation = 0; ! 257: } else { ! 258: /* LBA translation. */ ! 259: translation = 1; ! 260: } ! 261: } else { ! 262: translation--; ! 263: } ! 264: val |= translation << (i * 2); ! 265: } ! 266: } ! 267: rtc_set_memory(s, 0x39, val); ! 268: ! 269: /* Disable check of 0x55AA signature on the last two bytes of ! 270: first sector of disk. XXX: make it the default ? */ ! 271: // rtc_set_memory(s, 0x38, 1); ! 272: } ! 273: ! 274: static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val) ! 275: { ! 276: speaker_data_on = (val >> 1) & 1; ! 277: pit_set_gate(pit, 2, val & 1); ! 278: } ! 279: ! 280: static uint32_t speaker_ioport_read(void *opaque, uint32_t addr) ! 281: { ! 282: int out; ! 283: out = pit_get_out(pit, 2, qemu_get_clock(vm_clock)); ! 284: dummy_refresh_clock ^= 1; ! 285: return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) | ! 286: (dummy_refresh_clock << 4); ! 287: } ! 288: ! 289: static void ioport92_write(void *opaque, uint32_t addr, uint32_t val) ! 290: { ! 291: cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1); ! 292: /* XXX: bit 0 is fast reset */ ! 293: } ! 294: ! 295: static uint32_t ioport92_read(void *opaque, uint32_t addr) ! 296: { ! 297: return ((cpu_single_env->a20_mask >> 20) & 1) << 1; ! 298: } ! 299: ! 300: /***********************************************************/ ! 301: /* Bochs BIOS debug ports */ ! 302: ! 303: void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val) ! 304: { ! 305: static const char shutdown_str[8] = "Shutdown"; ! 306: static int shutdown_index = 0; ! 307: ! 308: switch(addr) { ! 309: /* Bochs BIOS messages */ ! 310: case 0x400: ! 311: case 0x401: ! 312: fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val); ! 313: exit(1); ! 314: case 0x402: ! 315: case 0x403: ! 316: #ifdef DEBUG_BIOS ! 317: fprintf(stderr, "%c", val); ! 318: #endif ! 319: break; ! 320: case 0x8900: ! 321: /* same as Bochs power off */ ! 322: if (val == shutdown_str[shutdown_index]) { ! 323: shutdown_index++; ! 324: if (shutdown_index == 8) { ! 325: shutdown_index = 0; ! 326: qemu_system_shutdown_request(); ! 327: } ! 328: } else { ! 329: shutdown_index = 0; ! 330: } ! 331: break; ! 332: ! 333: /* LGPL'ed VGA BIOS messages */ ! 334: case 0x501: ! 335: case 0x502: ! 336: fprintf(stderr, "VGA BIOS panic, line %d\n", val); ! 337: exit(1); ! 338: case 0x500: ! 339: case 0x503: ! 340: #ifdef DEBUG_BIOS ! 341: fprintf(stderr, "%c", val); ! 342: #endif ! 343: break; ! 344: } ! 345: } ! 346: ! 347: void bochs_bios_init(void) ! 348: { ! 349: register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL); ! 350: register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL); ! 351: register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL); ! 352: register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL); ! 353: register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL); ! 354: ! 355: register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL); ! 356: register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL); ! 357: register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL); ! 358: register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL); ! 359: } ! 360: ! 361: ! 362: int load_kernel(const char *filename, uint8_t *addr, ! 363: uint8_t *real_addr) ! 364: { ! 365: int fd, size; ! 366: int setup_sects; ! 367: ! 368: fd = open(filename, O_RDONLY | O_BINARY); ! 369: if (fd < 0) ! 370: return -1; ! 371: ! 372: /* load 16 bit code */ ! 373: if (read(fd, real_addr, 512) != 512) ! 374: goto fail; ! 375: setup_sects = real_addr[0x1F1]; ! 376: if (!setup_sects) ! 377: setup_sects = 4; ! 378: if (read(fd, real_addr + 512, setup_sects * 512) != ! 379: setup_sects * 512) ! 380: goto fail; ! 381: ! 382: /* load 32 bit code */ ! 383: size = read(fd, addr, 16 * 1024 * 1024); ! 384: if (size < 0) ! 385: goto fail; ! 386: close(fd); ! 387: return size; ! 388: fail: ! 389: close(fd); ! 390: return -1; ! 391: } ! 392: ! 393: static const int ide_iobase[2] = { 0x1f0, 0x170 }; ! 394: static const int ide_iobase2[2] = { 0x3f6, 0x376 }; ! 395: static const int ide_irq[2] = { 14, 15 }; ! 396: ! 397: #define NE2000_NB_MAX 6 ! 398: ! 399: static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 }; ! 400: static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; ! 401: ! 402: static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; ! 403: static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; ! 404: ! 405: static int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; ! 406: static int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; ! 407: ! 408: /* PC hardware initialisation */ ! 409: static void pc_init1(int ram_size, int vga_ram_size, int boot_device, ! 410: DisplayState *ds, const char **fd_filename, int snapshot, ! 411: const char *kernel_filename, const char *kernel_cmdline, ! 412: const char *initrd_filename) ! 413: { ! 414: char buf[1024]; ! 415: int ret, linux_boot, initrd_size, i, nb_nics1; ! 416: unsigned long bios_offset, vga_bios_offset; ! 417: int bios_size, isa_bios_size; ! 418: PCIBus *pci_bus; ! 419: ! 420: linux_boot = (kernel_filename != NULL); ! 421: ! 422: /* allocate RAM */ ! 423: cpu_register_physical_memory(0, ram_size, 0); ! 424: ! 425: /* BIOS load */ ! 426: bios_offset = ram_size + vga_ram_size; ! 427: vga_bios_offset = bios_offset + 256 * 1024; ! 428: ! 429: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME); ! 430: bios_size = get_image_size(buf); ! 431: if (bios_size <= 0 || ! 432: (bios_size % 65536) != 0 || ! 433: bios_size > (256 * 1024)) { ! 434: goto bios_error; ! 435: } ! 436: ret = load_image(buf, phys_ram_base + bios_offset); ! 437: if (ret != bios_size) { ! 438: bios_error: ! 439: fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf); ! 440: exit(1); ! 441: } ! 442: ! 443: /* VGA BIOS load */ ! 444: if (cirrus_vga_enabled) { ! 445: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME); ! 446: } else { ! 447: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME); ! 448: } ! 449: ret = load_image(buf, phys_ram_base + vga_bios_offset); ! 450: ! 451: /* setup basic memory access */ ! 452: cpu_register_physical_memory(0xc0000, 0x10000, ! 453: vga_bios_offset | IO_MEM_ROM); ! 454: ! 455: /* map the last 128KB of the BIOS in ISA space */ ! 456: isa_bios_size = bios_size; ! 457: if (isa_bios_size > (128 * 1024)) ! 458: isa_bios_size = 128 * 1024; ! 459: cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size, ! 460: IO_MEM_UNASSIGNED); ! 461: cpu_register_physical_memory(0x100000 - isa_bios_size, ! 462: isa_bios_size, ! 463: (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); ! 464: /* map all the bios at the top of memory */ ! 465: cpu_register_physical_memory((uint32_t)(-bios_size), ! 466: bios_size, bios_offset | IO_MEM_ROM); ! 467: ! 468: bochs_bios_init(); ! 469: ! 470: if (linux_boot) { ! 471: uint8_t bootsect[512]; ! 472: uint8_t old_bootsect[512]; ! 473: ! 474: if (bs_table[0] == NULL) { ! 475: fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n"); ! 476: exit(1); ! 477: } ! 478: snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME); ! 479: ret = load_image(buf, bootsect); ! 480: if (ret != sizeof(bootsect)) { ! 481: fprintf(stderr, "qemu: could not load linux boot sector '%s'\n", ! 482: buf); ! 483: exit(1); ! 484: } ! 485: ! 486: if (bdrv_read(bs_table[0], 0, old_bootsect, 1) >= 0) { ! 487: /* copy the MSDOS partition table */ ! 488: memcpy(bootsect + 0x1be, old_bootsect + 0x1be, 0x40); ! 489: } ! 490: ! 491: bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect)); ! 492: ! 493: /* now we can load the kernel */ ! 494: ret = load_kernel(kernel_filename, ! 495: phys_ram_base + KERNEL_LOAD_ADDR, ! 496: phys_ram_base + KERNEL_PARAMS_ADDR); ! 497: if (ret < 0) { ! 498: fprintf(stderr, "qemu: could not load kernel '%s'\n", ! 499: kernel_filename); ! 500: exit(1); ! 501: } ! 502: ! 503: /* load initrd */ ! 504: initrd_size = 0; ! 505: if (initrd_filename) { ! 506: initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR); ! 507: if (initrd_size < 0) { ! 508: fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", ! 509: initrd_filename); ! 510: exit(1); ! 511: } ! 512: } ! 513: if (initrd_size > 0) { ! 514: stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR); ! 515: stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size); ! 516: } ! 517: pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096, ! 518: kernel_cmdline); ! 519: stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F); ! 520: stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22, ! 521: KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR); ! 522: /* loader type */ ! 523: stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01); ! 524: } ! 525: ! 526: if (pci_enabled) { ! 527: pci_bus = i440fx_init(); ! 528: piix3_init(pci_bus); ! 529: } else { ! 530: pci_bus = NULL; ! 531: } ! 532: ! 533: /* init basic PC hardware */ ! 534: register_ioport_write(0x80, 1, 1, ioport80_write, NULL); ! 535: ! 536: register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); ! 537: ! 538: if (cirrus_vga_enabled) { ! 539: if (pci_enabled) { ! 540: pci_cirrus_vga_init(pci_bus, ! 541: ds, phys_ram_base + ram_size, ram_size, ! 542: vga_ram_size); ! 543: } else { ! 544: isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size, ! 545: vga_ram_size); ! 546: } ! 547: } else { ! 548: vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, ! 549: vga_ram_size, 0, 0); ! 550: } ! 551: ! 552: rtc_state = rtc_init(0x70, 8); ! 553: register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL); ! 554: register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL); ! 555: ! 556: register_ioport_read(0x92, 1, 1, ioport92_read, NULL); ! 557: register_ioport_write(0x92, 1, 1, ioport92_write, NULL); ! 558: ! 559: if (pci_enabled) { ! 560: apic_init(cpu_single_env); ! 561: ioapic = ioapic_init(); ! 562: } ! 563: isa_pic = pic_init(pic_irq_request, cpu_single_env); ! 564: pit = pit_init(0x40, 0); ! 565: if (pci_enabled) { ! 566: pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic); ! 567: } ! 568: ! 569: for(i = 0; i < MAX_SERIAL_PORTS; i++) { ! 570: if (serial_hds[i]) { ! 571: serial_init(serial_io[i], serial_irq[i], serial_hds[i]); ! 572: } ! 573: } ! 574: ! 575: for(i = 0; i < MAX_PARALLEL_PORTS; i++) { ! 576: if (parallel_hds[i]) { ! 577: parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]); ! 578: } ! 579: } ! 580: ! 581: if (pci_enabled) { ! 582: for(i = 0; i < nb_nics; i++) { ! 583: pci_ne2000_init(pci_bus, &nd_table[i]); ! 584: } ! 585: pci_piix3_ide_init(pci_bus, bs_table); ! 586: } else { ! 587: nb_nics1 = nb_nics; ! 588: if (nb_nics1 > NE2000_NB_MAX) ! 589: nb_nics1 = NE2000_NB_MAX; ! 590: for(i = 0; i < nb_nics1; i++) { ! 591: isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]); ! 592: } ! 593: ! 594: for(i = 0; i < 2; i++) { ! 595: isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], ! 596: bs_table[2 * i], bs_table[2 * i + 1]); ! 597: } ! 598: } ! 599: ! 600: kbd_init(); ! 601: DMA_init(0); ! 602: ! 603: if (audio_enabled) { ! 604: AUD_init(); ! 605: #ifdef USE_SB16 ! 606: if (sb16_enabled) ! 607: SB16_init (); ! 608: #endif ! 609: #ifdef CONFIG_ADLIB ! 610: if (adlib_enabled) ! 611: Adlib_init (); ! 612: #endif ! 613: #ifdef USE_GUS ! 614: if (gus_enabled) ! 615: GUS_init (); ! 616: #endif ! 617: } ! 618: ! 619: floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); ! 620: ! 621: cmos_init(ram_size, boot_device, bs_table); ! 622: ! 623: /* must be done after all PCI devices are instanciated */ ! 624: /* XXX: should be done in the Bochs BIOS */ ! 625: if (pci_enabled) { ! 626: pci_bios_init(); ! 627: } ! 628: } ! 629: ! 630: QEMUMachine pc_machine = { ! 631: "pc", ! 632: "Standard PC", ! 633: pc_init1, ! 634: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.