ia64/xen-unstable

view tools/ioemu/hw/pc.c @ 10078:345464c2fd47

Allow to specify different time-of-day clock offsets for HVM guests.

There are some usage scenarios in which differing user domains want
to be using different base TOD clocks. This patch adds the ability
to specify the base TOD time difference. The patch also adds a
hook point to notify another entity when the domain changes this
offset. This might occur, for instance, on a Linux domain using
hwclock -w.

Signed-off-by: Ben Thomas <ben@virtualiron.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed May 17 23:43:32 2006 +0100 (2006-05-17)
parents f8d20c3e4225
children 61e2ea81bd65
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;
44 static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
45 {
46 }
48 /* MSDOS compatibility mode FPU exception support */
49 /* XXX: add IGNNE support */
50 void cpu_set_ferr(CPUX86State *s)
51 {
52 pic_set_irq(13, 1);
53 }
55 static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
56 {
57 pic_set_irq(13, 0);
58 }
60 /* TSC handling */
62 uint64_t cpu_get_tsc(CPUX86State *env)
63 {
64 return qemu_get_clock(vm_clock);
65 }
67 /* PC cmos mappings */
69 #define REG_EQUIPMENT_BYTE 0x14
70 #define REG_IBM_CENTURY_BYTE 0x32
71 #define REG_IBM_PS2_CENTURY_BYTE 0x37
74 static inline int to_bcd(RTCState *s, int a)
75 {
76 return ((a / 10) << 4) | (a % 10);
77 }
79 static int cmos_get_fd_drive_type(int fd0)
80 {
81 int val;
83 switch (fd0) {
84 case 0:
85 /* 1.44 Mb 3"5 drive */
86 val = 4;
87 break;
88 case 1:
89 /* 2.88 Mb 3"5 drive */
90 val = 5;
91 break;
92 case 2:
93 /* 1.2 Mb 5"5 drive */
94 val = 2;
95 break;
96 default:
97 val = 0;
98 break;
99 }
100 return val;
101 }
103 static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
104 {
105 RTCState *s = rtc_state;
106 int cylinders, heads, sectors;
107 bdrv_get_geometry_hint(hd, &cylinders, &heads, &sectors);
108 rtc_set_memory(s, type_ofs, 47);
109 rtc_set_memory(s, info_ofs, cylinders);
110 rtc_set_memory(s, info_ofs + 1, cylinders >> 8);
111 rtc_set_memory(s, info_ofs + 2, heads);
112 rtc_set_memory(s, info_ofs + 3, 0xff);
113 rtc_set_memory(s, info_ofs + 4, 0xff);
114 rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3));
115 rtc_set_memory(s, info_ofs + 6, cylinders);
116 rtc_set_memory(s, info_ofs + 7, cylinders >> 8);
117 rtc_set_memory(s, info_ofs + 8, sectors);
118 }
120 /* hd_table must contain 4 block drivers */
121 static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table, time_t timeoffset)
122 {
123 RTCState *s = rtc_state;
124 int val;
125 int fd0, fd1, nb;
126 time_t ti;
127 struct tm *tm;
128 int i;
130 /* set the CMOS date */
131 time(&ti);
132 ti += timeoffset;
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 rtc_set_memory(s, 0x3d, 0x21); /* a->c->d */
172 rtc_set_memory(s, 0x38, 0x30);
173 break;
174 default:
175 case 'c':
176 //rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
177 rtc_set_memory(s, 0x3d, 0x32); /* c->d->a */
178 rtc_set_memory(s, 0x38, 0x10);
179 break;
180 case 'd':
181 //rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
182 rtc_set_memory(s, 0x3d, 0x23); /* d->c->a */
183 rtc_set_memory(s, 0x38, 0x10);
184 break;
185 }
187 /* floppy type */
189 fd0 = fdctrl_get_drive_type(floppy_controller, 0);
190 fd1 = fdctrl_get_drive_type(floppy_controller, 1);
192 val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1);
193 rtc_set_memory(s, 0x10, val);
195 val = 0;
196 nb = 0;
197 if (fd0 < 3)
198 nb++;
199 if (fd1 < 3)
200 nb++;
201 switch (nb) {
202 case 0:
203 break;
204 case 1:
205 val |= 0x01; /* 1 drive, ready for boot */
206 break;
207 case 2:
208 val |= 0x41; /* 2 drives, ready for boot */
209 break;
210 }
211 val |= 0x02; /* FPU is there */
212 val |= 0x04; /* PS/2 mouse installed */
213 rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);
215 /* hard drives */
217 rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
218 if (hd_table[0])
219 cmos_init_hd(0x19, 0x1b, hd_table[0]);
220 if (hd_table[1])
221 cmos_init_hd(0x1a, 0x24, hd_table[1]);
223 val = 0;
224 for (i = 0; i < 4; i++) {
225 if (hd_table[i]) {
226 int cylinders, heads, sectors;
227 uint8_t translation;
228 /* NOTE: bdrv_get_geometry_hint() returns the geometry
229 that the hard disk returns. It is always such that: 1 <=
230 sects <= 63, 1 <= heads <= 16, 1 <= cylinders <=
231 16383. The BIOS geometry can be different. */
232 bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
233 if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
234 /* No translation. */
235 translation = 0;
236 } else {
237 /* LBA translation. */
238 translation = 1;
239 }
240 val |= translation << (i * 2);
241 }
242 }
243 rtc_set_memory(s, 0x39, val);
245 /* Disable check of 0x55AA signature on the last two bytes of
246 first sector of disk. XXX: make it the default ? */
247 // rtc_set_memory(s, 0x38, 1);
248 }
250 static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
251 {
252 fprintf(stderr, "speaker port should not be handled in DM!\n");
253 }
255 static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
256 {
257 fprintf(stderr, "speaker port should not be handled in DM!\n");
258 return 0;
259 }
261 static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
262 {
263 cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
264 /* XXX: bit 0 is fast reset */
265 }
267 static uint32_t ioport92_read(void *opaque, uint32_t addr)
268 {
269 return ((cpu_single_env->a20_mask >> 20) & 1) << 1;
270 }
272 /***********************************************************/
273 /* Bochs BIOS debug ports */
275 void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
276 {
277 static const char shutdown_str[8] = "Shutdown";
278 static int shutdown_index = 0;
280 switch(addr) {
281 /* Bochs BIOS messages */
282 case 0x400:
283 case 0x401:
284 fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
285 exit(1);
286 case 0x402:
287 case 0x403:
288 #ifdef DEBUG_BIOS
289 fprintf(stderr, "%c", val);
290 #endif
291 break;
292 case 0x8900:
293 /* same as Bochs power off */
294 if (val == shutdown_str[shutdown_index]) {
295 shutdown_index++;
296 if (shutdown_index == 8) {
297 shutdown_index = 0;
298 qemu_system_shutdown_request();
299 }
300 } else {
301 shutdown_index = 0;
302 }
303 break;
305 /* LGPL'ed VGA BIOS messages */
306 case 0x501:
307 case 0x502:
308 fprintf(stderr, "VGA BIOS panic, line %d\n", val);
309 exit(1);
310 case 0x500:
311 case 0x503:
312 #ifdef DEBUG_BIOS
313 fprintf(stderr, "%c", val);
314 #endif
315 break;
316 }
317 }
319 void bochs_bios_init(void)
320 {
321 register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL);
322 register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL);
323 register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL);
324 register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
325 register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
327 register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
328 register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
329 register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
330 register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
331 }
334 int load_kernel(const char *filename, uint8_t *addr,
335 uint8_t *real_addr)
336 {
337 int fd, size;
338 int setup_sects;
340 fd = open(filename, O_RDONLY | O_BINARY);
341 if (fd < 0)
342 return -1;
344 /* load 16 bit code */
345 if (read(fd, real_addr, 512) != 512)
346 goto fail;
347 setup_sects = real_addr[0x1F1];
348 if (!setup_sects)
349 setup_sects = 4;
350 if (read(fd, real_addr + 512, setup_sects * 512) !=
351 setup_sects * 512)
352 goto fail;
354 /* load 32 bit code */
355 size = read(fd, addr, 16 * 1024 * 1024);
356 if (size < 0)
357 goto fail;
358 close(fd);
359 return size;
360 fail:
361 close(fd);
362 return -1;
363 }
365 static const int ide_iobase[2] = { 0x1f0, 0x170 };
366 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
367 static const int ide_irq[2] = { 14, 15 };
369 #define NE2000_NB_MAX 6
371 static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
372 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
374 static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
375 static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
377 extern int acpi_init(unsigned int base);
379 #define NOBIOS 1
381 /* PC hardware initialisation */
382 void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
383 DisplayState *ds, const char **fd_filename, int snapshot,
384 const char *kernel_filename, const char *kernel_cmdline,
385 const char *initrd_filename, time_t timeoffset)
386 {
387 SerialState *sp;
388 char buf[1024];
389 int ret, linux_boot, initrd_size, i, nb_nics1;
390 PCIBus *pci_bus;
392 linux_boot = (kernel_filename != NULL);
394 /* allocate RAM */
395 // cpu_register_physical_memory(0, ram_size, 0);
397 #ifndef NOBIOS
398 /* BIOS load */
399 bios_offset = ram_size + vga_ram_size;
400 vga_bios_offset = bios_offset + 256 * 1024;
402 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
403 bios_size = get_image_size(buf);
404 if (bios_size <= 0 ||
405 (bios_size % 65536) != 0 ||
406 bios_size > (256 * 1024)) {
407 goto bios_error;
408 }
409 ret = load_image(buf, phys_ram_base + bios_offset);
410 if (ret != bios_size) {
411 bios_error:
412 fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
413 exit(1);
414 }
416 /* VGA BIOS load */
417 if (cirrus_vga_enabled) {
418 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
419 } else {
420 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
421 }
422 ret = load_image(buf, phys_ram_base + vga_bios_offset);
423 #endif
425 #ifndef NOBIOS
426 /* setup basic memory access */
427 cpu_register_physical_memory(0xc0000, 0x10000,
428 vga_bios_offset | IO_MEM_ROM);
430 /* map the last 128KB of the BIOS in ISA space */
431 isa_bios_size = bios_size;
432 if (isa_bios_size > (128 * 1024))
433 isa_bios_size = 128 * 1024;
434 cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size,
435 IO_MEM_UNASSIGNED);
436 cpu_register_physical_memory(0x100000 - isa_bios_size,
437 isa_bios_size,
438 (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
439 /* map all the bios at the top of memory */
440 cpu_register_physical_memory((uint32_t)(-bios_size),
441 bios_size, bios_offset | IO_MEM_ROM);
442 #endif
444 bochs_bios_init();
446 if (linux_boot) {
447 uint8_t bootsect[512];
448 uint8_t old_bootsect[512];
450 if (bs_table[0] == NULL) {
451 fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
452 exit(1);
453 }
454 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
455 ret = load_image(buf, bootsect);
456 if (ret != sizeof(bootsect)) {
457 fprintf(stderr, "qemu: could not load linux boot sector '%s'\n",
458 buf);
459 exit(1);
460 }
462 if (bdrv_read(bs_table[0], 0, old_bootsect, 1) >= 0) {
463 /* copy the MSDOS partition table */
464 memcpy(bootsect + 0x1be, old_bootsect + 0x1be, 0x40);
465 }
467 bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
469 /* now we can load the kernel */
470 ret = load_kernel(kernel_filename,
471 phys_ram_base + KERNEL_LOAD_ADDR,
472 phys_ram_base + KERNEL_PARAMS_ADDR);
473 if (ret < 0) {
474 fprintf(stderr, "qemu: could not load kernel '%s'\n",
475 kernel_filename);
476 exit(1);
477 }
479 /* load initrd */
480 initrd_size = 0;
481 if (initrd_filename) {
482 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
483 if (initrd_size < 0) {
484 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
485 initrd_filename);
486 exit(1);
487 }
488 }
489 if (initrd_size > 0) {
490 stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
491 stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
492 }
493 pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
494 kernel_cmdline);
495 stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
496 stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
497 KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
498 /* loader type */
499 stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
500 }
502 if (pci_enabled) {
503 pci_bus = i440fx_init();
504 piix3_init(pci_bus);
505 } else {
506 pci_bus = NULL;
507 }
509 /* init basic PC hardware */
510 register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
512 register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
514 if (cirrus_vga_enabled) {
515 if (pci_enabled) {
516 pci_cirrus_vga_init(pci_bus,
517 ds, NULL, ram_size,
518 vga_ram_size);
519 } else {
520 isa_cirrus_vga_init(ds, NULL, ram_size,
521 vga_ram_size);
522 }
523 } else {
524 vga_initialize(pci_bus, ds, NULL, ram_size,
525 vga_ram_size);
526 }
528 rtc_state = rtc_init(0x70, 8);
529 register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
530 register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
532 register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
533 register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
535 pic_init();
537 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
538 if (serial_hds[i]) {
539 sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
540 if (i == SUMMA_PORT)
541 summa_init(sp, serial_hds[i]);
542 }
543 }
545 if (pci_enabled) {
546 for(i = 0; i < nb_nics; i++) {
547 if (nic_ne2000)
548 pci_ne2000_init(pci_bus, &nd_table[i]);
549 else
550 pci_pcnet_init(pci_bus, &nd_table[i]);
551 }
552 pci_piix3_ide_init(pci_bus, bs_table);
553 } else {
554 nb_nics1 = nb_nics;
555 if (nb_nics1 > NE2000_NB_MAX)
556 nb_nics1 = NE2000_NB_MAX;
557 for(i = 0; i < nb_nics1; i++) {
558 isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
559 }
561 for(i = 0; i < 2; i++) {
562 isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
563 bs_table[2 * i], bs_table[2 * i + 1]);
564 }
565 }
567 kbd_init();
568 DMA_init(0);
570 if (audio_enabled) {
571 AUD_init();
572 #ifdef USE_SB16
573 if (sb16_enabled)
574 SB16_init();
575 #endif
576 }
579 floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
581 cmos_init(ram_size, boot_device, bs_table, timeoffset);
582 acpi_init(0x8000);
584 /* must be done after all PCI devices are instanciated */
585 /* XXX: should be done in the Bochs BIOS */
586 if (pci_enabled) {
587 pci_bios_init();
588 }
589 port_e9_init();
590 }