ia64/xen-unstable

view tools/ioemu/hw/pc.c @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
parents 3233e7ecfa9f
children 06d84bf87159
line source
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"
26 /* output Bochs bios info messages */
27 //#define DEBUG_BIOS
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"
34 #define KERNEL_LOAD_ADDR 0x00100000
35 #define INITRD_LOAD_ADDR 0x00400000
36 #define KERNEL_PARAMS_ADDR 0x00090000
37 #define KERNEL_CMDLINE_ADDR 0x00099000
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;
45 static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
46 {
47 }
49 /* MSDOS compatibility mode FPU exception support */
50 /* XXX: add IGNNE support */
51 void cpu_set_ferr(CPUX86State *s)
52 {
53 pic_set_irq(13, 1);
54 }
56 static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
57 {
58 pic_set_irq(13, 0);
59 }
61 /* TSC handling */
63 uint64_t cpu_get_tsc(CPUX86State *env)
64 {
65 return qemu_get_clock(vm_clock);
66 }
68 /* PC cmos mappings */
70 #define REG_EQUIPMENT_BYTE 0x14
71 #define REG_IBM_CENTURY_BYTE 0x32
72 #define REG_IBM_PS2_CENTURY_BYTE 0x37
75 static inline int to_bcd(RTCState *s, int a)
76 {
77 return ((a / 10) << 4) | (a % 10);
78 }
80 static int cmos_get_fd_drive_type(int fd0)
81 {
82 int val;
84 switch (fd0) {
85 case 0:
86 /* 1.44 Mb 3"5 drive */
87 val = 4;
88 break;
89 case 1:
90 /* 2.88 Mb 3"5 drive */
91 val = 5;
92 break;
93 case 2:
94 /* 1.2 Mb 5"5 drive */
95 val = 2;
96 break;
97 default:
98 val = 0;
99 break;
100 }
101 return val;
102 }
104 static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
105 {
106 RTCState *s = rtc_state;
107 int cylinders, heads, sectors;
108 bdrv_get_geometry_hint(hd, &cylinders, &heads, &sectors);
109 rtc_set_memory(s, type_ofs, 47);
110 rtc_set_memory(s, info_ofs, cylinders);
111 rtc_set_memory(s, info_ofs + 1, cylinders >> 8);
112 rtc_set_memory(s, info_ofs + 2, heads);
113 rtc_set_memory(s, info_ofs + 3, 0xff);
114 rtc_set_memory(s, info_ofs + 4, 0xff);
115 rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3));
116 rtc_set_memory(s, info_ofs + 6, cylinders);
117 rtc_set_memory(s, info_ofs + 7, cylinders >> 8);
118 rtc_set_memory(s, info_ofs + 8, sectors);
119 }
121 /* hd_table must contain 4 block drivers */
122 static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table)
123 {
124 RTCState *s = rtc_state;
125 int val;
126 int fd0, fd1, nb;
127 time_t ti;
128 struct tm *tm;
129 int i;
131 /* set the CMOS date */
132 time(&ti);
133 if (rtc_utc)
134 tm = gmtime(&ti);
135 else
136 tm = localtime(&ti);
137 rtc_set_date(s, tm);
139 val = to_bcd(s, (tm->tm_year / 100) + 19);
140 rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
141 rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
143 /* various important CMOS locations needed by PC/Bochs bios */
145 /* memory size */
146 val = 640; /* base memory in K */
147 rtc_set_memory(s, 0x15, val);
148 rtc_set_memory(s, 0x16, val >> 8);
150 val = (ram_size / 1024) - 1024;
151 if (val > 65535)
152 val = 65535;
153 rtc_set_memory(s, 0x17, val);
154 rtc_set_memory(s, 0x18, val >> 8);
155 rtc_set_memory(s, 0x30, val);
156 rtc_set_memory(s, 0x31, val >> 8);
158 if (ram_size > (16 * 1024 * 1024))
159 val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
160 else
161 val = 0;
162 if (val > 65535)
163 val = 65535;
164 rtc_set_memory(s, 0x34, val);
165 rtc_set_memory(s, 0x35, val >> 8);
167 switch(boot_device) {
168 case 'a':
169 case 'b':
170 rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
171 break;
172 default:
173 case 'c':
174 rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
175 break;
176 case 'd':
177 rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
178 break;
179 }
181 /* floppy type */
183 fd0 = fdctrl_get_drive_type(floppy_controller, 0);
184 fd1 = fdctrl_get_drive_type(floppy_controller, 1);
186 val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1);
187 rtc_set_memory(s, 0x10, val);
189 val = 0;
190 nb = 0;
191 if (fd0 < 3)
192 nb++;
193 if (fd1 < 3)
194 nb++;
195 switch (nb) {
196 case 0:
197 break;
198 case 1:
199 val |= 0x01; /* 1 drive, ready for boot */
200 break;
201 case 2:
202 val |= 0x41; /* 2 drives, ready for boot */
203 break;
204 }
205 val |= 0x02; /* FPU is there */
206 val |= 0x04; /* PS/2 mouse installed */
207 rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);
209 /* hard drives */
211 rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
212 if (hd_table[0])
213 cmos_init_hd(0x19, 0x1b, hd_table[0]);
214 if (hd_table[1])
215 cmos_init_hd(0x1a, 0x24, hd_table[1]);
217 val = 0;
218 for (i = 0; i < 4; i++) {
219 if (hd_table[i]) {
220 int cylinders, heads, sectors;
221 uint8_t translation;
222 /* NOTE: bdrv_get_geometry_hint() returns the geometry
223 that the hard disk returns. It is always such that: 1 <=
224 sects <= 63, 1 <= heads <= 16, 1 <= cylinders <=
225 16383. The BIOS geometry can be different. */
226 bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
227 if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
228 /* No translation. */
229 translation = 0;
230 } else {
231 /* LBA translation. */
232 translation = 1;
233 }
234 val |= translation << (i * 2);
235 }
236 }
237 rtc_set_memory(s, 0x39, val);
239 /* Disable check of 0x55AA signature on the last two bytes of
240 first sector of disk. XXX: make it the default ? */
241 // rtc_set_memory(s, 0x38, 1);
242 }
244 static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
245 {
246 speaker_data_on = (val >> 1) & 1;
247 pit_set_gate(pit, 2, val & 1);
248 }
250 static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
251 {
252 int out;
253 out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
254 dummy_refresh_clock ^= 1;
255 return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
256 (dummy_refresh_clock << 4);
257 }
259 static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
260 {
261 cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
262 /* XXX: bit 0 is fast reset */
263 }
265 static uint32_t ioport92_read(void *opaque, uint32_t addr)
266 {
267 return ((cpu_single_env->a20_mask >> 20) & 1) << 1;
268 }
270 /***********************************************************/
271 /* Bochs BIOS debug ports */
273 void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
274 {
275 static const char shutdown_str[8] = "Shutdown";
276 static int shutdown_index = 0;
278 switch(addr) {
279 /* Bochs BIOS messages */
280 case 0x400:
281 case 0x401:
282 fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
283 exit(1);
284 case 0x402:
285 case 0x403:
286 #ifdef DEBUG_BIOS
287 fprintf(stderr, "%c", val);
288 #endif
289 break;
290 case 0x8900:
291 /* same as Bochs power off */
292 if (val == shutdown_str[shutdown_index]) {
293 shutdown_index++;
294 if (shutdown_index == 8) {
295 shutdown_index = 0;
296 qemu_system_shutdown_request();
297 }
298 } else {
299 shutdown_index = 0;
300 }
301 break;
303 /* LGPL'ed VGA BIOS messages */
304 case 0x501:
305 case 0x502:
306 fprintf(stderr, "VGA BIOS panic, line %d\n", val);
307 exit(1);
308 case 0x500:
309 case 0x503:
310 #ifdef DEBUG_BIOS
311 fprintf(stderr, "%c", val);
312 #endif
313 break;
314 }
315 }
317 void bochs_bios_init(void)
318 {
319 register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL);
320 register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL);
321 register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL);
322 register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
323 register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
325 register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
326 register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
327 register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
328 register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
329 }
332 int load_kernel(const char *filename, uint8_t *addr,
333 uint8_t *real_addr)
334 {
335 int fd, size;
336 int setup_sects;
338 fd = open(filename, O_RDONLY | O_BINARY);
339 if (fd < 0)
340 return -1;
342 /* load 16 bit code */
343 if (read(fd, real_addr, 512) != 512)
344 goto fail;
345 setup_sects = real_addr[0x1F1];
346 if (!setup_sects)
347 setup_sects = 4;
348 if (read(fd, real_addr + 512, setup_sects * 512) !=
349 setup_sects * 512)
350 goto fail;
352 /* load 32 bit code */
353 size = read(fd, addr, 16 * 1024 * 1024);
354 if (size < 0)
355 goto fail;
356 close(fd);
357 return size;
358 fail:
359 close(fd);
360 return -1;
361 }
363 static const int ide_iobase[2] = { 0x1f0, 0x170 };
364 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
365 static const int ide_irq[2] = { 14, 15 };
367 #define NE2000_NB_MAX 6
369 static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
370 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
372 static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
373 static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
375 #define NOBIOS 1
377 /* PC hardware initialisation */
378 void pc_init(int ram_size, int vga_ram_size, int boot_device,
379 DisplayState *ds, const char **fd_filename, int snapshot,
380 const char *kernel_filename, const char *kernel_cmdline,
381 const char *initrd_filename)
382 {
383 char buf[1024];
384 int ret, linux_boot, initrd_size, i, nb_nics1;
385 unsigned long bios_offset, vga_bios_offset;
386 int bios_size, isa_bios_size;
387 PCIBus *pci_bus;
389 linux_boot = (kernel_filename != NULL);
391 /* allocate RAM */
392 // cpu_register_physical_memory(0, ram_size, 0);
394 #ifndef NOBIOS
395 /* BIOS load */
396 bios_offset = ram_size + vga_ram_size;
397 vga_bios_offset = bios_offset + 256 * 1024;
399 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
400 bios_size = get_image_size(buf);
401 if (bios_size <= 0 ||
402 (bios_size % 65536) != 0 ||
403 bios_size > (256 * 1024)) {
404 goto bios_error;
405 }
406 ret = load_image(buf, phys_ram_base + bios_offset);
407 if (ret != bios_size) {
408 bios_error:
409 fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
410 exit(1);
411 }
413 /* VGA BIOS load */
414 if (cirrus_vga_enabled) {
415 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
416 } else {
417 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
418 }
419 ret = load_image(buf, phys_ram_base + vga_bios_offset);
420 #endif
422 #ifndef NOBIOS
423 /* setup basic memory access */
424 cpu_register_physical_memory(0xc0000, 0x10000,
425 vga_bios_offset | IO_MEM_ROM);
427 /* map the last 128KB of the BIOS in ISA space */
428 isa_bios_size = bios_size;
429 if (isa_bios_size > (128 * 1024))
430 isa_bios_size = 128 * 1024;
431 cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size,
432 IO_MEM_UNASSIGNED);
433 cpu_register_physical_memory(0x100000 - isa_bios_size,
434 isa_bios_size,
435 (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
436 /* map all the bios at the top of memory */
437 cpu_register_physical_memory((uint32_t)(-bios_size),
438 bios_size, bios_offset | IO_MEM_ROM);
439 #endif
441 bochs_bios_init();
443 if (linux_boot) {
444 uint8_t bootsect[512];
445 uint8_t old_bootsect[512];
447 if (bs_table[0] == NULL) {
448 fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
449 exit(1);
450 }
451 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
452 ret = load_image(buf, bootsect);
453 if (ret != sizeof(bootsect)) {
454 fprintf(stderr, "qemu: could not load linux boot sector '%s'\n",
455 buf);
456 exit(1);
457 }
459 if (bdrv_read(bs_table[0], 0, old_bootsect, 1) >= 0) {
460 /* copy the MSDOS partition table */
461 memcpy(bootsect + 0x1be, old_bootsect + 0x1be, 0x40);
462 }
464 bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
466 /* now we can load the kernel */
467 ret = load_kernel(kernel_filename,
468 phys_ram_base + KERNEL_LOAD_ADDR,
469 phys_ram_base + KERNEL_PARAMS_ADDR);
470 if (ret < 0) {
471 fprintf(stderr, "qemu: could not load kernel '%s'\n",
472 kernel_filename);
473 exit(1);
474 }
476 /* load initrd */
477 initrd_size = 0;
478 if (initrd_filename) {
479 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
480 if (initrd_size < 0) {
481 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
482 initrd_filename);
483 exit(1);
484 }
485 }
486 if (initrd_size > 0) {
487 stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
488 stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
489 }
490 pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
491 kernel_cmdline);
492 stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
493 stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
494 KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
495 /* loader type */
496 stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
497 }
499 if (pci_enabled) {
500 pci_bus = i440fx_init();
501 piix3_init(pci_bus);
502 } else {
503 pci_bus = NULL;
504 }
506 /* init basic PC hardware */
507 register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
509 register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
511 if (cirrus_vga_enabled) {
512 if (pci_enabled) {
513 pci_cirrus_vga_init(pci_bus,
514 ds, phys_ram_base + ram_size, ram_size,
515 vga_ram_size);
516 } else {
517 isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size,
518 vga_ram_size);
519 }
520 } else {
521 vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
522 vga_ram_size);
523 }
525 rtc_state = rtc_init(0x70, 8);
526 register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
527 register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
529 register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
530 register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
532 pic_init();
533 pit = pit_init(0x40, 0);
535 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
536 if (serial_hds[i]) {
537 serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
538 }
539 }
541 if (pci_enabled) {
542 for(i = 0; i < nb_nics; i++) {
543 if (nic_pcnet)
544 pci_pcnet_init(pci_bus, &nd_table[i]);
545 else
546 pci_ne2000_init(pci_bus, &nd_table[i]);
547 }
548 pci_piix3_ide_init(pci_bus, bs_table);
549 #ifdef APIC_SUPPORT
550 IOAPICInit();
551 #endif
552 } else {
553 nb_nics1 = nb_nics;
554 if (nb_nics1 > NE2000_NB_MAX)
555 nb_nics1 = NE2000_NB_MAX;
556 for(i = 0; i < nb_nics1; i++) {
557 isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
558 }
560 for(i = 0; i < 2; i++) {
561 isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
562 bs_table[2 * i], bs_table[2 * i + 1]);
563 }
564 }
566 kbd_init();
567 DMA_init(0);
569 floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
571 cmos_init(ram_size, boot_device, bs_table);
573 /* must be done after all PCI devices are instanciated */
574 /* XXX: should be done in the Bochs BIOS */
575 if (pci_enabled) {
576 pci_bios_init();
577 }
578 port_e9_init();
579 }