[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxxx # Node ID 8cddaee4a51cb0c905a87e2ef85d1a8c54e4d963 # Parent 1cfd862e5254fa7c9614035035586a3f182a530f # Parent 1ad7dff99968ae1d801900854e1a418630f06c21 Merge with xen-ia64-unstable.hg --- tools/ioemu/patches/acpi-support | 41 -- tools/ioemu/patches/acpi-timer-support | 8 tools/ioemu/patches/domain-destroy | 12 tools/ioemu/patches/domain-reset | 8 tools/ioemu/patches/domain-timeoffset | 12 tools/ioemu/patches/fix-interrupt-routing | 55 +++ tools/ioemu/patches/hypervisor-pit | 8 tools/ioemu/patches/hypervisor-rtc | 12 tools/ioemu/patches/ide-error-reporting | 85 +++++ tools/ioemu/patches/ioemu-ia64 | 72 ---- tools/ioemu/patches/limit-fdc-sector-size-to-16K | 30 + tools/ioemu/patches/ne2000-bounds-checks | 79 +++++ tools/ioemu/patches/nodelay-serial-over-tcp | 25 + tools/ioemu/patches/qemu-bootorder | 14 tools/ioemu/patches/qemu-daemonize | 4 tools/ioemu/patches/qemu-dm | 20 - tools/ioemu/patches/qemu-no-apic | 6 tools/ioemu/patches/qemu-pci | 18 - tools/ioemu/patches/qemu-serial-fixes | 79 +++++ tools/ioemu/patches/qemu-target-i386-dm | 149 --------- tools/ioemu/patches/remove-pci-bridge-setup | 287 +++++++++++++++++++ tools/ioemu/patches/rtl8139-bound-chaining | 31 ++ tools/ioemu/patches/series | 16 + tools/ioemu/patches/shared-vram | 30 - tools/ioemu/patches/tpm-tis-device | 56 +++ tools/ioemu/patches/usb-mouse-tablet-status-check | 124 ++++++++ tools/ioemu/patches/usb-uhci-buffer-size | 23 + tools/ioemu/patches/vnc-access-monitor-vt | 4 tools/ioemu/patches/vnc-backoff-screen-scan | 22 - tools/ioemu/patches/vnc-display-find-unused | 20 - tools/ioemu/patches/vnc-fixes | 46 +-- tools/ioemu/patches/vnc-japan-keymap | 24 + tools/ioemu/patches/vnc-listen-specific-interface | 18 - tools/ioemu/patches/vnc-monitor-shift-key-processing | 41 ++ tools/ioemu/patches/vnc-numpad-handling | 126 ++++++++ tools/ioemu/patches/vnc-password | 68 ++-- tools/ioemu/patches/vnc-protocol-fixes | 8 tools/ioemu/patches/vnc-start-vncviewer | 14 tools/ioemu/patches/vnc-title-domain-name | 6 tools/ioemu/patches/xen-build | 18 - tools/ioemu/patches/xen-mapcache | 145 +++++++++ tools/ioemu/patches/xen-mm | 18 - tools/ioemu/patches/xen-platform-device | 9 tools/ioemu/patches/xen-support-buffered-ioreqs | 28 - tools/ioemu/patches/xenstore-block-device-config | 40 +- tools/ioemu/patches/xenstore-device-info-functions | 32 ++ tools/ioemu/patches/xenstore-write-vnc-port | 8 tools/libxc/Makefile | 4 tools/libxc/xc_private.c | 22 - tools/python/xen/xend/XendConfig.py | 18 - tools/python/xen/xend/server/netif.py | 4 tools/python/xen/xm/main.py | 4 52 files changed, 1557 insertions(+), 494 deletions(-) diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/acpi-support --- a/tools/ioemu/patches/acpi-support Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/acpi-support Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-08-17 19:49:50.228216099 +0100 -+++ ioemu/Makefile.target 2006-08-17 19:50:02.405870095 +0100 -@@ -357,6 +357,7 @@ +--- ioemu.orig/Makefile.target 2006-12-08 02:00:40.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 02:00:40.000000000 +0000 +@@ -358,6 +358,7 @@ VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o VL_OBJS+= usb-uhci.o @@ -12,8 +12,8 @@ Index: ioemu/Makefile.target ifeq ($(TARGET_BASE_ARCH), ppc) Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-17 19:49:59.312212039 +0100 -+++ ioemu/hw/pc.c 2006-08-17 19:50:02.406869984 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 02:00:40.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 02:00:40.000000000 +0000 @@ -874,13 +874,19 @@ cmos_init(ram_size, boot_device, bs_table, timeoffset); @@ -49,8 +49,8 @@ Index: ioemu/hw/piix4acpi.c Index: ioemu/hw/piix4acpi.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/hw/piix4acpi.c 2006-08-17 19:50:02.407869874 +0100 -@@ -0,0 +1,388 @@ ++++ ioemu/hw/piix4acpi.c 2006-12-08 02:00:40.000000000 +0000 +@@ -0,0 +1,396 @@ +/* + * PIIX4 ACPI controller emulation + * @@ -434,15 +434,23 @@ Index: ioemu/hw/piix4acpi.c + pci_conf[0x0e] = 0x00; + pci_conf[0x3d] = 0x01; /* Hardwired to PIRQA is used */ + -+ pci_register_io_region((PCIDevice *)d, 4, 0x10, -+ PCI_ADDRESS_SPACE_IO, acpi_map); -+ -+ acpi_reset (d); ++ ++ /* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40 ++ * to make shutdown work for IPF, due to IPF Guest Firmware ++ * will enumerate pci devices. ++ * ++ * TODO: if Guest Firmware or Guest OS will change this PMBA, ++ * More logic will be added. ++ */ ++ pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */ ++ pci_conf[0x41] = 0x1f; ++ acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO); ++ acpi_reset(d); +} Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:49:59.315211708 +0100 -+++ ioemu/vl.c 2006-08-17 19:50:02.410869542 +0100 +--- ioemu.orig/vl.c 2006-12-08 02:00:40.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:00:40.000000000 +0000 @@ -156,7 +156,7 @@ #else #define MAX_CPUS 1 @@ -476,7 +484,7 @@ Index: ioemu/vl.c { NULL }, }; -@@ -6256,6 +6259,9 @@ +@@ -6240,6 +6243,9 @@ case QEMU_OPTION_timeoffset: timeoffset = strtol(optarg, NULL, 0); break; @@ -488,8 +496,8 @@ Index: ioemu/vl.c } Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:49:59.316211597 +0100 -+++ ioemu/vl.h 2006-08-17 19:50:02.411869432 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:00:40.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:00:40.000000000 +0000 @@ -168,6 +168,7 @@ extern int kqemu_allowed; extern int win2k_install_hack; @@ -510,8 +518,8 @@ Index: ioemu/vl.h extern QEMUMachine isapc_machine; Index: ioemu/hw/piix_pci.c =================================================================== ---- ioemu.orig/hw/piix_pci.c 2006-08-17 19:38:05.806252180 +0100 -+++ ioemu/hw/piix_pci.c 2006-08-17 19:50:02.411869432 +0100 +--- ioemu.orig/hw/piix_pci.c 2006-12-08 02:00:39.000000000 +0000 ++++ ioemu/hw/piix_pci.c 2006-12-08 02:00:40.000000000 +0000 @@ -241,7 +241,7 @@ static uint32_t pci_bios_io_addr; static uint32_t pci_bios_mem_addr; @@ -521,33 +529,22 @@ Index: ioemu/hw/piix_pci.c static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) { -@@ -336,6 +336,14 @@ +@@ -336,6 +336,18 @@ pci_set_io_region_addr(d, 3, 0x374); } break; + case 0x0680: + if (vendor_id == 0x8086 && device_id == 0x7113) { -+ /* PIIX4 ACPI PM */ -+ pci_config_writew(d, 0x20, 0x0000); /* NO smb bus IO enable in PIIX4 */ ++ /* ++ * PIIX4 ACPI PM. ++ * Special device with special PCI config space. No ordinary BARs. ++ */ ++ pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable + pci_config_writew(d, 0x22, 0x0000); -+ goto default_map; ++ pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9 ++ pci_config_writew(d, 0x3d, 0x0001); + } + break; case 0x0300: if (vendor_id != 0x1234) goto default_map; -@@ -386,6 +394,14 @@ - pic_irq = pci_irqs[pin]; - pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq); - } -+ -+ if (class== 0x0680&& vendor_id == 0x8086 && device_id == 0x7113) { -+ // PIIX4 ACPI PM -+ pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4 -+ pci_config_writew(d, 0x22, 0x0000); -+ pci_config_writew(d, 0x3c, 0x0009); // Hardcodeed IRQ9 -+ pci_config_writew(d, 0x3d, 0x0001); -+ } - } - - /* diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/acpi-timer-support --- a/tools/ioemu/patches/acpi-timer-support Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/acpi-timer-support Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/hw/piix4acpi.c Index: ioemu/hw/piix4acpi.c =================================================================== ---- ioemu.orig/hw/piix4acpi.c 2006-08-17 19:50:02.407869874 +0100 -+++ ioemu/hw/piix4acpi.c 2006-08-17 19:50:05.060576667 +0100 +--- ioemu.orig/hw/piix4acpi.c 2006-12-08 01:35:52.000000000 +0000 ++++ ioemu/hw/piix4acpi.c 2006-12-08 01:35:59.000000000 +0000 @@ -24,31 +24,30 @@ */ @@ -186,10 +186,3 @@ Index: ioemu/hw/piix4acpi.c /* PIIX4 acpi pci configuration space, func 2 */ void pci_piix4_acpi_init(PCIBus *bus, int devfn) -@@ -384,5 +383,5 @@ - pci_register_io_region((PCIDevice *)d, 4, 0x10, - PCI_ADDRESS_SPACE_IO, acpi_map); - -- acpi_reset (d); -+ acpi_reset(d); - } diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/domain-destroy --- a/tools/ioemu/patches/domain-destroy Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/domain-destroy Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/monitor.c Index: ioemu/monitor.c =================================================================== ---- ioemu.orig/monitor.c 2006-08-17 19:37:36.489509621 +0100 -+++ ioemu/monitor.c 2006-08-17 19:49:44.491850141 +0100 +--- ioemu.orig/monitor.c 2006-12-08 01:26:07.000000000 +0000 ++++ ioemu/monitor.c 2006-12-08 01:26:08.000000000 +0000 @@ -308,6 +308,7 @@ static void do_quit(void) @@ -12,11 +12,11 @@ Index: ioemu/monitor.c Index: ioemu/target-i386-dm/helper2.c =================================================================== ---- ioemu.orig/target-i386-dm/helper2.c 2006-08-17 19:49:40.116333768 +0100 -+++ ioemu/target-i386-dm/helper2.c 2006-08-17 19:49:44.491850141 +0100 -@@ -488,5 +488,25 @@ - xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]); - } +--- ioemu.orig/target-i386-dm/helper2.c 2006-12-08 01:26:08.000000000 +0000 ++++ ioemu/target-i386-dm/helper2.c 2006-12-08 01:26:08.000000000 +0000 +@@ -507,5 +507,25 @@ + /* Wait up to 10 msec. */ + main_loop_wait(10); } + destroy_hvm_domain(); return 0; @@ -42,8 +42,8 @@ Index: ioemu/target-i386-dm/helper2.c +} Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:49:40.120333326 +0100 -+++ ioemu/vl.h 2006-08-17 19:49:44.492850031 +0100 +--- ioemu.orig/vl.h 2006-12-08 01:26:08.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 01:26:08.000000000 +0000 @@ -1190,4 +1190,7 @@ void kqemu_record_dump(void); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/domain-reset --- a/tools/ioemu/patches/domain-reset Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/domain-reset Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/target-i386-dm/helper2.c Index: ioemu/target-i386-dm/helper2.c =================================================================== ---- ioemu.orig/target-i386-dm/helper2.c 2006-08-17 19:37:36.530505066 +0100 -+++ ioemu/target-i386-dm/helper2.c 2006-08-17 19:49:40.116333768 +0100 +--- ioemu.orig/target-i386-dm/helper2.c 2006-12-08 01:26:06.000000000 +0000 ++++ ioemu/target-i386-dm/helper2.c 2006-12-08 01:26:08.000000000 +0000 @@ -127,6 +127,25 @@ /* called from main_cpu_reset */ void cpu_reset(CPUX86State *env) @@ -28,7 +28,7 @@ Index: ioemu/target-i386-dm/helper2.c } void cpu_x86_close(CPUX86State *env) -@@ -455,6 +474,10 @@ +@@ -479,6 +498,10 @@ if (vm_running) { if (shutdown_requested) break; @@ -41,8 +41,8 @@ Index: ioemu/target-i386-dm/helper2.c /* Wait up to 10 msec. */ Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:49:39.442408257 +0100 -+++ ioemu/vl.c 2006-08-17 19:49:40.119333436 +0100 +--- ioemu.orig/vl.c 2006-12-08 01:26:08.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 01:26:08.000000000 +0000 @@ -4948,7 +4948,7 @@ } QEMUResetEntry; @@ -54,8 +54,8 @@ Index: ioemu/vl.c Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:47:32.680418959 +0100 -+++ ioemu/vl.h 2006-08-17 19:49:40.120333326 +0100 +--- ioemu.orig/vl.h 2006-12-08 01:26:07.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 01:26:08.000000000 +0000 @@ -131,6 +131,7 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/domain-timeoffset --- a/tools/ioemu/patches/domain-timeoffset Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/domain-timeoffset Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/hw/mc146818rtc.c Index: ioemu/hw/mc146818rtc.c =================================================================== ---- ioemu.orig/hw/mc146818rtc.c 2006-10-24 14:45:21.000000000 +0100 -+++ ioemu/hw/mc146818rtc.c 2006-10-24 14:45:39.000000000 +0100 +--- ioemu.orig/hw/mc146818rtc.c 2006-12-08 18:36:31.000000000 +0000 ++++ ioemu/hw/mc146818rtc.c 2006-12-08 18:36:36.000000000 +0000 @@ -178,10 +178,27 @@ } } @@ -46,8 +46,8 @@ Index: ioemu/hw/mc146818rtc.c static void rtc_copy_date(RTCState *s) Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-10-24 14:45:38.000000000 +0100 -+++ ioemu/hw/pc.c 2006-10-24 14:45:39.000000000 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 18:36:35.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 18:36:36.000000000 +0000 @@ -159,7 +159,7 @@ } @@ -117,8 +117,8 @@ Index: ioemu/hw/pc.c QEMUMachine pc_machine = { Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:45:38.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:45:39.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-08 18:36:35.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 18:36:36.000000000 +0000 @@ -163,6 +163,8 @@ int xc_handle; @@ -152,7 +152,7 @@ Index: ioemu/vl.c { NULL }, }; -@@ -6248,6 +6253,9 @@ +@@ -6232,6 +6237,9 @@ vcpus = atoi(optarg); fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus); break; @@ -162,7 +162,7 @@ Index: ioemu/vl.c } } } -@@ -6507,7 +6515,8 @@ +@@ -6492,7 +6500,8 @@ machine->init(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, @@ -174,8 +174,8 @@ Index: ioemu/vl.c if (usb_enabled) { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:45:38.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:45:39.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 18:36:35.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 18:36:36.000000000 +0000 @@ -576,7 +576,7 @@ int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/hypervisor-pit --- a/tools/ioemu/patches/hypervisor-pit Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/hypervisor-pit Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-08-17 19:49:33.813030472 +0100 -+++ ioemu/Makefile.target 2006-08-17 19:49:50.228216099 +0100 -@@ -354,7 +354,7 @@ +--- ioemu.orig/Makefile.target 2006-12-08 01:41:12.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 01:41:12.000000000 +0000 +@@ -355,7 +355,7 @@ ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) @@ -13,8 +13,8 @@ Index: ioemu/Makefile.target DEFINES += -DHAS_AUDIO Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-17 19:49:35.507843144 +0100 -+++ ioemu/hw/pc.c 2006-08-17 19:49:50.229215988 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 01:41:12.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 01:41:12.000000000 +0000 @@ -38,7 +38,9 @@ static fdctrl_t *floppy_controller; @@ -38,8 +38,8 @@ Index: ioemu/hw/pc.c pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic); Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:49:48.566399780 +0100 -+++ ioemu/vl.c 2006-08-17 19:49:50.231215767 +0100 +--- ioemu.orig/vl.c 2006-12-08 01:41:12.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 01:41:12.000000000 +0000 @@ -5570,6 +5570,7 @@ #ifdef HAS_AUDIO diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/hypervisor-rtc --- a/tools/ioemu/patches/hypervisor-rtc Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/hypervisor-rtc Sat Dec 09 14:34:53 2006 +0000 @@ -5,9 +5,11 @@ [HVM] Move RTC emulation into the hypervisor. Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx> ---- ioemu/Makefile.target Wed Oct 18 18:13:57 2006 +0100 -+++ ioemu/Makefile.target Wed Oct 18 18:35:21 2006 +0100 -@@ -294,7 +294,11 @@ endif +Index: ioemu/Makefile.target +=================================================================== +--- ioemu.orig/Makefile.target 2006-12-08 01:41:15.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 01:41:15.000000000 +0000 +@@ -295,7 +295,11 @@ endif # qemu-dm objects @@ -19,7 +21,7 @@ Signed-off-by: Xiaowei Yang <xiaowei.yan all: $(PROGS) -@@ -354,7 +358,11 @@ ifeq ($(TARGET_BASE_ARCH), i386) +@@ -355,7 +359,11 @@ ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) @@ -31,8 +33,10 @@ Signed-off-by: Xiaowei Yang <xiaowei.yan VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o VL_OBJS+= usb-uhci.o VL_OBJS+= piix4acpi.o ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ioemu/target-i386-dm/rtc-dm.c Wed Oct 18 18:35:21 2006 +0100 +Index: ioemu/target-i386-dm/rtc-dm.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ ioemu/target-i386-dm/rtc-dm.c 2006-12-08 01:41:15.000000000 +0000 @@ -0,0 +1,107 @@ +/* + * QEMU MC146818 RTC emulation diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/ioemu-ia64 --- a/tools/ioemu/patches/ioemu-ia64 Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/ioemu-ia64 Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/hw/iommu.c Index: ioemu/hw/iommu.c =================================================================== ---- ioemu.orig/hw/iommu.c 2006-08-17 19:37:36.791476068 +0100 -+++ ioemu/hw/iommu.c 2006-08-17 19:48:27.357375720 +0100 +--- ioemu.orig/hw/iommu.c 2006-12-08 02:02:07.000000000 +0000 ++++ ioemu/hw/iommu.c 2006-12-08 02:02:34.000000000 +0000 @@ -82,7 +82,11 @@ #define IOPTE_VALID 0x00000002 /* IOPTE is valid */ #define IOPTE_WAZ 0x00000001 /* Write as zeros */ @@ -16,8 +16,8 @@ Index: ioemu/hw/iommu.c Index: ioemu/cpu-all.h =================================================================== ---- ioemu.orig/cpu-all.h 2006-08-17 19:37:36.791476068 +0100 -+++ ioemu/cpu-all.h 2006-08-17 19:48:27.358375609 +0100 +--- ioemu.orig/cpu-all.h 2006-12-08 02:02:07.000000000 +0000 ++++ ioemu/cpu-all.h 2006-12-08 02:02:34.000000000 +0000 @@ -835,6 +835,31 @@ :"=m" (*(volatile long *)addr) :"dIr" (nr)); @@ -52,36 +52,36 @@ Index: ioemu/cpu-all.h /* memory API */ Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:47:08.538087284 +0100 -+++ ioemu/vl.c 2006-08-17 19:57:50.666108706 +0100 -@@ -6144,6 +6144,11 @@ - - xc_handle = xc_interface_open(); +--- ioemu.orig/vl.c 2006-12-08 02:02:28.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:34.000000000 +0000 +@@ -6137,6 +6137,11 @@ + exit(1); + } +#if defined (__ia64__) + if (ram_size > MMIO_START) + ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */ +#endif + - nr_pages = ram_size/PAGE_SIZE; - tmp_nr_pages = nr_pages; + /* init the memory */ + phys_ram_size = ram_size + vga_ram_size + bios_size; @@ -6161,6 +6166,7 @@ exit(-1); } +#if defined(__i386__) || defined(__x86_64__) - if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) { - fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno); - exit(-1); -@@ -6191,6 +6197,41 @@ + for ( i = 0; i < tmp_nr_pages; i++) + page_array[i] = i; + +@@ -6185,6 +6191,48 @@ free(page_array); +#elif defined(__ia64__) + + if (xc_ia64_get_pfn_list(xc_handle, domid, page_array, -+ IO_PAGE_START >> PAGE_SHIFT, 1) != 1) { ++ IO_PAGE_START >> PAGE_SHIFT, 3) != 3) { + fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno); + exit(-1); + } @@ -92,6 +92,12 @@ Index: ioemu/vl.c + + fprintf(logfile, "shared page at pfn:%lx, mfn: %016lx\n", + IO_PAGE_START >> PAGE_SHIFT, page_array[0]); ++ ++ buffered_io_page =xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, ++ PROT_READ|PROT_WRITE, ++ page_array[2]); ++ fprintf(logfile, "Buffered IO page at pfn:%lx, mfn: %016lx\n", ++ BUFFER_IO_PAGE_START >> PAGE_SHIFT, page_array[2]); + + if (xc_ia64_get_pfn_list(xc_handle, domid, + page_array, 0, nr_pages) != nr_pages) { @@ -100,9 +106,9 @@ Index: ioemu/vl.c + } + + if (ram_size > MMIO_START) { -+ for (i = 0 ; i < MEM_G >> PAGE_SHIFT; i++) -+ page_array[MMIO_START >> PAGE_SHIFT + i] = -+ page_array[IO_PAGE_START >> PAGE_SHIFT + 1]; ++ for (i = 0 ; i < (MEM_G >> PAGE_SHIFT); i++) ++ page_array[(MMIO_START >> PAGE_SHIFT) + i] = ++ page_array[(IO_PAGE_START >> PAGE_SHIFT) + 1]; + } + + phys_ram_base = xc_map_foreign_batch(xc_handle, domid, @@ -112,52 +118,15 @@ Index: ioemu/vl.c + fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno); + exit(-1); + } ++ free(page_array); +#endif #else /* !CONFIG_DM */ phys_ram_base = qemu_vmalloc(phys_ram_size); -Index: ioemu/target-i386-dm/exec-dm.c -=================================================================== ---- ioemu.orig/target-i386-dm/exec-dm.c 2006-08-17 19:37:36.792475957 +0100 -+++ ioemu/target-i386-dm/exec-dm.c 2006-08-17 19:48:27.361375278 +0100 -@@ -341,6 +341,23 @@ - return io_mem_read[io_index >> IO_MEM_SHIFT]; - } - -+#ifdef __ia64__ -+/* IA64 has seperate I/D cache, with coherence maintained by DMA controller. -+ * So to emulate right behavior that guest OS is assumed, we need to flush -+ * I/D cache here. -+ */ -+static void sync_icache(unsigned long address, int len) -+{ -+ int l; -+ -+ for(l = 0; l < (len + 32); l += 32) -+ __ia64_fc(address + l); -+ -+ ia64_sync_i(); -+ ia64_srlz_i(); -+} -+#endif -+ - /* physical memory access (slow version, mainly for debug) */ - #if defined(CONFIG_USER_ONLY) - void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, -@@ -432,6 +449,9 @@ - /* RAM case */ - ptr = phys_ram_base + addr1; - memcpy(ptr, buf, l); -+#ifdef __ia64__ -+ sync_icache((unsigned long)ptr, l); -+#endif - } - } else { - if (io_index) { Index: ioemu/exec-all.h =================================================================== ---- ioemu.orig/exec-all.h 2006-08-17 19:37:36.791476068 +0100 -+++ ioemu/exec-all.h 2006-08-17 19:48:27.362375167 +0100 +--- ioemu.orig/exec-all.h 2006-12-08 02:02:07.000000000 +0000 ++++ ioemu/exec-all.h 2006-12-08 02:02:34.000000000 +0000 @@ -462,12 +462,13 @@ } #endif @@ -177,9 +146,9 @@ Index: ioemu/exec-all.h Index: ioemu/target-i386-dm/cpu.h =================================================================== ---- ioemu.orig/target-i386-dm/cpu.h 2006-08-17 19:37:36.792475957 +0100 -+++ ioemu/target-i386-dm/cpu.h 2006-08-17 19:48:27.362375167 +0100 -@@ -80,7 +80,11 @@ +--- ioemu.orig/target-i386-dm/cpu.h 2006-12-08 02:02:07.000000000 +0000 ++++ ioemu/target-i386-dm/cpu.h 2006-12-08 02:02:34.000000000 +0000 +@@ -78,7 +78,11 @@ /* helper2.c */ int main_loop(void); @@ -194,7 +163,7 @@ Index: ioemu/ia64_intrinsic.h Index: ioemu/ia64_intrinsic.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/ia64_intrinsic.h 2006-08-17 19:48:27.363375057 +0100 ++++ ioemu/ia64_intrinsic.h 2006-12-08 02:02:34.000000000 +0000 @@ -0,0 +1,276 @@ +#ifndef IA64_INTRINSIC_H +#define IA64_INTRINSIC_H diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-bootorder --- a/tools/ioemu/patches/qemu-bootorder Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/qemu-bootorder Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/vl.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-08 02:02:38.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:38.000000000 +0000 @@ -125,7 +125,7 @@ struct sockaddr_in vnclisten_addr; const char* keyboard_layout = NULL; @@ -11,7 +11,7 @@ Index: ioemu/vl.c uint64_t ram_size; int pit_min_timer_count = 0; int nb_nics; -@@ -6075,14 +6075,14 @@ +@@ -6059,14 +6059,14 @@ break; #endif /* !CONFIG_DM */ case QEMU_OPTION_boot: @@ -32,7 +32,7 @@ Index: ioemu/vl.c exit(1); } break; -@@ -6349,6 +6349,7 @@ +@@ -6333,6 +6333,7 @@ fd_filename[0] == '\0') help(); @@ -40,7 +40,7 @@ Index: ioemu/vl.c /* boot to cd by default if no hard disk */ if (hd_filename[0] == '\0' && boot_device == 'c') { if (fd_filename[0] != '\0') -@@ -6356,6 +6357,7 @@ +@@ -6340,6 +6341,7 @@ else boot_device = 'd'; } @@ -48,7 +48,7 @@ Index: ioemu/vl.c #endif /* !CONFIG_DM */ setvbuf(stdout, NULL, _IOLBF, 0); -@@ -6614,6 +6616,7 @@ +@@ -6598,6 +6600,7 @@ ds, fd_filename, snapshot, kernel_filename, kernel_cmdline, initrd_filename, timeoffset); @@ -58,8 +58,8 @@ Index: ioemu/vl.c if (usb_enabled) { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:33:47.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:02:38.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:38.000000000 +0000 @@ -578,7 +578,7 @@ #ifndef QEMU_TOOL @@ -80,8 +80,8 @@ Index: ioemu/vl.h uint32_t initrd_image, uint32_t initrd_size, Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/hw/pc.c 2006-10-24 14:33:47.000000000 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 02:02:38.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 02:02:38.000000000 +0000 @@ -158,8 +158,23 @@ rtc_set_memory(s, info_ofs + 8, sectors); } diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-daemonize --- a/tools/ioemu/patches/qemu-daemonize Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/qemu-daemonize Sat Dec 09 14:34:53 2006 +0000 @@ -2,9 +2,9 @@ Changes required because qemu-dm runs da Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100 -@@ -6054,10 +6054,11 @@ +--- ioemu.orig/vl.c 2006-12-08 02:00:42.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:00:42.000000000 +0000 +@@ -6038,10 +6038,11 @@ } break; case QEMU_OPTION_nographic: diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-dm --- a/tools/ioemu/patches/qemu-dm Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/qemu-dm Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-08-06 02:14:04.797460093 +0100 -+++ ioemu/Makefile.target 2006-08-06 02:14:09.794902973 +0100 -@@ -302,7 +302,7 @@ +--- ioemu.orig/Makefile.target 2006-12-08 01:41:05.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 01:41:10.000000000 +0000 +@@ -303,7 +303,7 @@ endif # must use static linking to avoid leaving stuff in virtual address space @@ -13,8 +13,8 @@ Index: ioemu/Makefile.target VL_OBJS+=tap-win32.o Index: ioemu/configure =================================================================== ---- ioemu.orig/configure 2006-08-06 02:14:04.797460093 +0100 -+++ ioemu/configure 2006-08-06 02:14:09.795902861 +0100 +--- ioemu.orig/configure 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/configure 2006-12-08 01:41:10.000000000 +0000 @@ -75,8 +75,8 @@ bigendian="no" mingw32="no" @@ -37,8 +37,8 @@ Index: ioemu/configure target_user_only="yes" Index: ioemu/cpu-all.h =================================================================== ---- ioemu.orig/cpu-all.h 2006-08-06 02:14:04.797460093 +0100 -+++ ioemu/cpu-all.h 2006-08-06 02:14:09.796902750 +0100 +--- ioemu.orig/cpu-all.h 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/cpu-all.h 2006-12-08 01:41:10.000000000 +0000 @@ -690,7 +690,9 @@ void page_set_flags(target_ulong start, target_ulong end, int flags); void page_unprotect_range(target_ulong data, target_ulong data_size); @@ -64,8 +64,8 @@ Index: ioemu/cpu-all.h void cpu_dump_state(CPUState *env, FILE *f, Index: ioemu/disas.h =================================================================== ---- ioemu.orig/disas.h 2006-08-06 02:14:04.797460093 +0100 -+++ ioemu/disas.h 2006-08-06 02:14:09.796902750 +0100 +--- ioemu.orig/disas.h 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/disas.h 2006-12-08 01:41:10.000000000 +0000 @@ -1,6 +1,7 @@ #ifndef _QEMU_DISAS_H #define _QEMU_DISAS_H @@ -83,8 +83,8 @@ Index: ioemu/disas.h #endif /* _QEMU_DISAS_H */ Index: ioemu/exec-all.h =================================================================== ---- ioemu.orig/exec-all.h 2006-08-06 02:14:04.798459982 +0100 -+++ ioemu/exec-all.h 2006-08-06 02:14:09.796902750 +0100 +--- ioemu.orig/exec-all.h 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/exec-all.h 2006-12-08 01:41:10.000000000 +0000 @@ -509,7 +509,7 @@ extern int tb_invalidated_flag; @@ -105,8 +105,8 @@ Index: ioemu/exec-all.h return addr; Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-06 02:14:04.797460093 +0100 -+++ ioemu/hw/pc.c 2006-08-06 02:14:09.797902638 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 01:41:10.000000000 +0000 @@ -73,6 +73,7 @@ } } @@ -184,8 +184,8 @@ Index: ioemu/hw/pc.c if (serial_hds[i]) { Index: ioemu/hw/vga_int.h =================================================================== ---- ioemu.orig/hw/vga_int.h 2006-08-06 02:14:04.797460093 +0100 -+++ ioemu/hw/vga_int.h 2006-08-06 02:14:09.797902638 +0100 +--- ioemu.orig/hw/vga_int.h 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/hw/vga_int.h 2006-12-08 01:41:10.000000000 +0000 @@ -28,7 +28,7 @@ #define ST01_DISP_ENABLE 0x01 @@ -197,8 +197,8 @@ Index: ioemu/hw/vga_int.h #define VBE_DISPI_MAX_YRES 1200 Index: ioemu/monitor.c =================================================================== ---- ioemu.orig/monitor.c 2006-08-06 02:14:04.798459982 +0100 -+++ ioemu/monitor.c 2006-08-06 02:14:49.574468309 +0100 +--- ioemu.orig/monitor.c 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/monitor.c 2006-12-08 01:41:10.000000000 +0000 @@ -68,6 +68,12 @@ void term_flush(void) @@ -429,8 +429,8 @@ Index: ioemu/monitor.c { Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-06 02:14:04.797460093 +0100 -+++ ioemu/vl.c 2006-08-06 02:14:09.802902081 +0100 +--- ioemu.orig/vl.c 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 01:41:10.000000000 +0000 @@ -422,12 +422,15 @@ void hw_error(const char *fmt, ...) { diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-no-apic --- a/tools/ioemu/patches/qemu-no-apic Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/qemu-no-apic Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-08-06 02:21:42.270461924 +0100 -+++ ioemu/Makefile.target 2006-08-06 02:22:26.380544784 +0100 -@@ -355,7 +355,7 @@ +--- ioemu.orig/Makefile.target 2006-12-08 01:41:11.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 01:41:12.000000000 +0000 +@@ -356,7 +356,7 @@ # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) VL_OBJS+= fdc.o mc146818rtc.o serial.o i8254.o pcspk.o pc.o @@ -13,8 +13,8 @@ Index: ioemu/Makefile.target endif Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-06 02:22:01.524315611 +0100 -+++ ioemu/hw/pc.c 2006-08-06 02:22:11.875161758 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 01:41:12.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 01:41:12.000000000 +0000 @@ -39,7 +39,9 @@ static fdctrl_t *floppy_controller; static RTCState *rtc_state; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-pci --- a/tools/ioemu/patches/qemu-pci Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/qemu-pci Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/hw/pci.c Index: ioemu/hw/pci.c =================================================================== ---- ioemu.orig/hw/pci.c 2006-09-21 11:31:14.000000000 +0100 -+++ ioemu/hw/pci.c 2006-09-21 11:31:32.000000000 +0100 +--- ioemu.orig/hw/pci.c 2006-12-08 02:02:05.000000000 +0000 ++++ ioemu/hw/pci.c 2006-12-08 18:16:55.000000000 +0000 @@ -286,6 +286,7 @@ case 0x0b: case 0x0e: @@ -31,8 +31,8 @@ Index: ioemu/hw/pci.c addr++; Index: ioemu/hw/rtl8139.c =================================================================== ---- ioemu.orig/hw/rtl8139.c 2006-09-21 11:31:14.000000000 +0100 -+++ ioemu/hw/rtl8139.c 2006-09-21 11:31:32.000000000 +0100 +--- ioemu.orig/hw/rtl8139.c 2006-12-08 02:02:05.000000000 +0000 ++++ ioemu/hw/rtl8139.c 2006-12-08 18:16:47.000000000 +0000 @@ -3423,6 +3423,8 @@ pci_conf[0x0e] = 0x00; /* header_type */ pci_conf[0x3d] = 1; /* interrupt pin 0 */ @@ -44,8 +44,8 @@ Index: ioemu/hw/rtl8139.c Index: ioemu/hw/usb-uhci.c =================================================================== ---- ioemu.orig/hw/usb-uhci.c 2006-09-21 11:31:14.000000000 +0100 -+++ ioemu/hw/usb-uhci.c 2006-09-21 11:31:32.000000000 +0100 +--- ioemu.orig/hw/usb-uhci.c 2006-12-08 02:02:05.000000000 +0000 ++++ ioemu/hw/usb-uhci.c 2006-12-08 02:02:38.000000000 +0000 @@ -659,6 +659,8 @@ pci_conf[0x0e] = 0x00; // header_type pci_conf[0x3d] = 4; // interrupt pin 3 @@ -55,3 +55,21 @@ Index: ioemu/hw/usb-uhci.c for(i = 0; i < NB_PORTS; i++) { qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach); +Index: ioemu/vl.h +=================================================================== +--- ioemu.orig/vl.h 2006-12-08 18:16:47.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 18:16:55.000000000 +0000 +@@ -650,8 +650,11 @@ + #define PCI_MAX_LAT 0x3f /* 8 bits */ + + struct PCIDevice { +- /* PCI config space */ +- uint8_t config[256]; ++ /* ++ * PCI config space. The 4 extra bytes are a safety buffer for guest ++ * word/dword writes that can extend past byte 0xff. ++ */ ++ uint8_t config[256+4]; + + /* the following fields are read only */ + PCIBus *bus; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-target-i386-dm --- a/tools/ioemu/patches/qemu-target-i386-dm Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/qemu-target-i386-dm Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/Makefile.target 2006-10-24 14:30:56.000000000 +0100 +--- ioemu.orig/Makefile.target 2006-12-08 01:41:10.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 01:41:11.000000000 +0000 @@ -62,6 +62,8 @@ QEMU_SYSTEM=qemu-fast endif @@ -11,7 +11,7 @@ Index: ioemu/Makefile.target ifdef CONFIG_USER_ONLY PROGS=$(QEMU_USER) else -@@ -291,6 +293,9 @@ +@@ -292,6 +294,9 @@ OBJS+=gdbstub.o endif @@ -21,7 +21,7 @@ Index: ioemu/Makefile.target all: $(PROGS) $(QEMU_USER): $(OBJS) -@@ -349,7 +354,7 @@ +@@ -350,7 +355,7 @@ ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) @@ -32,8 +32,8 @@ Index: ioemu/Makefile.target DEFINES += -DHAS_AUDIO Index: ioemu/configure =================================================================== ---- ioemu.orig/configure 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/configure 2006-10-24 14:29:34.000000000 +0100 +--- ioemu.orig/configure 2006-12-08 01:41:10.000000000 +0000 ++++ ioemu/configure 2006-12-08 01:41:11.000000000 +0000 @@ -373,6 +373,8 @@ if [ "$user" = "yes" ] ; then target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user $target_list" @@ -45,8 +45,8 @@ Index: ioemu/configure fi Index: ioemu/monitor.c =================================================================== ---- ioemu.orig/monitor.c 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/monitor.c 2006-10-24 14:30:56.000000000 +0100 +--- ioemu.orig/monitor.c 2006-12-08 01:41:10.000000000 +0000 ++++ ioemu/monitor.c 2006-12-08 01:41:11.000000000 +0000 @@ -1262,6 +1262,10 @@ "", "show profiling information", }, { "capture", "", do_info_capture, @@ -60,8 +60,8 @@ Index: ioemu/monitor.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:30:56.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-08 01:41:10.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 01:41:11.000000000 +0000 @@ -87,7 +87,7 @@ #include "exec-all.h" @@ -98,8 +98,8 @@ Index: ioemu/vl.c { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:30:56.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 01:40:58.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 01:41:11.000000000 +0000 @@ -37,6 +37,8 @@ #include <unistd.h> #include <fcntl.h> @@ -132,8 +132,8 @@ Index: ioemu/target-i386-dm/cpu.h Index: ioemu/target-i386-dm/cpu.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/cpu.h 2006-10-24 14:30:56.000000000 +0100 -@@ -0,0 +1,86 @@ ++++ ioemu/target-i386-dm/cpu.h 2006-12-08 01:41:11.000000000 +0000 +@@ -0,0 +1,84 @@ +/* + * i386 virtual CPU header + * @@ -191,8 +191,6 @@ Index: ioemu/target-i386-dm/cpu.h + int interrupt_request; + + CPU_COMMON -+ -+ int send_event; +} CPUX86State; + +CPUX86State *cpu_x86_init(void); @@ -223,8 +221,8 @@ Index: ioemu/target-i386-dm/exec-dm.c Index: ioemu/target-i386-dm/exec-dm.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/exec-dm.c 2006-10-24 14:30:56.000000000 +0100 -@@ -0,0 +1,516 @@ ++++ ioemu/target-i386-dm/exec-dm.c 2006-12-08 01:41:11.000000000 +0000 +@@ -0,0 +1,546 @@ +/* + * virtual page mapping and translated block handling + * @@ -258,6 +256,8 @@ Index: ioemu/target-i386-dm/exec-dm.c +#include <errno.h> +#include <unistd.h> +#include <inttypes.h> ++ ++#include <xen/hvm/e820.h> + +#include "cpu.h" +#include "exec-all.h" @@ -567,6 +567,23 @@ Index: ioemu/target-i386-dm/exec-dm.c +{ + return io_mem_read[io_index >> IO_MEM_SHIFT]; +} ++ ++#ifdef __ia64__ ++/* IA64 has seperate I/D cache, with coherence maintained by DMA controller. ++ * So to emulate right behavior that guest OS is assumed, we need to flush ++ * I/D cache here. ++ */ ++static void sync_icache(unsigned long address, int len) ++{ ++ int l; ++ ++ for(l = 0; l < (len + 32); l += 32) ++ __ia64_fc(address + l); ++ ++ ia64_sync_i(); ++ ia64_srlz_i(); ++} ++#endif + +/* physical memory access (slow version, mainly for debug) */ +#if defined(CONFIG_USER_ONLY) @@ -617,22 +634,36 @@ Index: ioemu/target-i386-dm/exec-dm.c + return 0; +} + ++static inline int paddr_is_ram(target_phys_addr_t addr) ++{ ++ /* Is this guest physical address RAM-backed? */ ++#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__)) ++ if (ram_size <= HVM_BELOW_4G_RAM_END) ++ /* RAM is contiguous */ ++ return (addr < ram_size); ++ else ++ /* There is RAM below and above the MMIO hole */ ++ return ((addr < HVM_BELOW_4G_MMIO_START) || ++ ((addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH) ++ && (addr < ram_size + HVM_BELOW_4G_MMIO_LENGTH))); ++#else ++ return (addr < ram_size); ++#endif ++} ++ +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write) +{ + int l, io_index; + uint8_t *ptr; + uint32_t val; -+ target_phys_addr_t page; -+ unsigned long pd; + + while (len > 0) { -+ page = addr & TARGET_PAGE_MASK; -+ l = (page + TARGET_PAGE_SIZE) - addr; ++ /* How much can we copy before the next page boundary? */ ++ l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); + if (l > len) + l = len; + -+ pd = page; + io_index = iomem_index(addr); + if (is_write) { + if (io_index) { @@ -652,13 +683,12 @@ Index: ioemu/target-i386-dm/exec-dm.c + io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val); + l = 1; + } -+ } else { -+ unsigned long addr1; -+ -+ addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); -+ /* RAM case */ -+ ptr = phys_ram_base + addr1; -+ memcpy(ptr, buf, l); ++ } else if (paddr_is_ram(addr)) { ++ /* Reading from RAM */ ++ memcpy(phys_ram_base + addr, buf, l); ++#ifdef __ia64__ ++ sync_icache((unsigned long)(phys_ram_base + addr), l); ++#endif + } + } else { + if (io_index) { @@ -678,14 +708,12 @@ Index: ioemu/target-i386-dm/exec-dm.c + stb_raw(buf, val); + l = 1; + } -+ } else if (addr < ram_size) { -+ /* RAM case */ -+ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + -+ (addr & ~TARGET_PAGE_MASK); -+ memcpy(buf, ptr, l); ++ } else if (paddr_is_ram(addr)) { ++ /* Reading from RAM */ ++ memcpy(buf, phys_ram_base + addr, l); + } else { -+ /* unreported MMIO space */ -+ memset(buf, 0xff, len); ++ /* Neither RAM nor known MMIO space */ ++ memset(buf, 0xff, len); + } + } + len -= l; @@ -744,8 +772,8 @@ Index: ioemu/target-i386-dm/helper2.c Index: ioemu/target-i386-dm/helper2.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/helper2.c 2006-10-24 14:31:01.000000000 +0100 -@@ -0,0 +1,469 @@ ++++ ioemu/target-i386-dm/helper2.c 2006-12-08 01:41:11.000000000 +0000 +@@ -0,0 +1,488 @@ +/* + * i386 helpers (without register variable usage) + * @@ -918,10 +946,10 @@ Index: ioemu/target-i386-dm/helper2.c + for (i = 0; i < vcpus; i++) { + req = &(shared_page->vcpu_iodata[i].vp_ioreq); + term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]); -+ term_printf(" req state: %x, pvalid: %x, addr: %"PRIx64", " ++ term_printf(" req state: %x, ptr: %x, addr: %"PRIx64", " + "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n", -+ req->state, req->pdata_valid, req->addr, -+ req->u.data, req->count, req->size); ++ req->state, req->data_is_ptr, req->addr, ++ req->data, req->count, req->size); + term_printf(" IO totally occurred on this vcpu: %"PRIx64"\n", + req->io_count); + } @@ -934,18 +962,19 @@ Index: ioemu/target-i386-dm/helper2.c + + req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq); + -+ if (req->state == STATE_IOREQ_READY) { -+ req->state = STATE_IOREQ_INPROCESS; -+ rmb(); -+ return req; -+ } -+ -+ fprintf(logfile, "False I/O request ... in-service already: " -+ "%x, pvalid: %x, port: %"PRIx64", " -+ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n", -+ req->state, req->pdata_valid, req->addr, -+ req->u.data, req->count, req->size); -+ return NULL; ++ if (req->state != STATE_IOREQ_READY) { ++ fprintf(logfile, "I/O request not ready: " ++ "%x, ptr: %x, port: %"PRIx64", " ++ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n", ++ req->state, req->data_is_ptr, req->addr, ++ req->data, req->count, req->size); ++ return NULL; ++ } ++ ++ rmb(); /* see IOREQ_READY /then/ read contents of ioreq */ ++ ++ req->state = STATE_IOREQ_INPROCESS; ++ return req; +} + +//use poll to get the port notification @@ -1030,26 +1059,26 @@ Index: ioemu/target-i386-dm/helper2.c + sign = req->df ? -1 : 1; + + if (req->dir == IOREQ_READ) { -+ if (!req->pdata_valid) { -+ req->u.data = do_inp(env, req->addr, req->size); ++ if (!req->data_is_ptr) { ++ req->data = do_inp(env, req->addr, req->size); + } else { + unsigned long tmp; + + for (i = 0; i < req->count; i++) { + tmp = do_inp(env, req->addr, req->size); -+ write_physical((target_phys_addr_t) req->u.pdata ++ write_physical((target_phys_addr_t) req->data + + (sign * i * req->size), + req->size, &tmp); + } + } + } else if (req->dir == IOREQ_WRITE) { -+ if (!req->pdata_valid) { -+ do_outp(env, req->addr, req->size, req->u.data); ++ if (!req->data_is_ptr) { ++ do_outp(env, req->addr, req->size, req->data); + } else { + for (i = 0; i < req->count; i++) { + unsigned long tmp; + -+ read_physical((target_phys_addr_t) req->u.pdata ++ read_physical((target_phys_addr_t) req->data + + (sign * i * req->size), + req->size, &tmp); + do_outp(env, req->addr, req->size, tmp); @@ -1064,18 +1093,18 @@ Index: ioemu/target-i386-dm/helper2.c + + sign = req->df ? -1 : 1; + -+ if (!req->pdata_valid) { ++ if (!req->data_is_ptr) { + if (req->dir == IOREQ_READ) { + for (i = 0; i < req->count; i++) { + read_physical(req->addr + + (sign * i * req->size), -+ req->size, &req->u.data); ++ req->size, &req->data); + } + } else if (req->dir == IOREQ_WRITE) { + for (i = 0; i < req->count; i++) { + write_physical(req->addr + + (sign * i * req->size), -+ req->size, &req->u.data); ++ req->size, &req->data); + } + } + } else { @@ -1086,13 +1115,13 @@ Index: ioemu/target-i386-dm/helper2.c + read_physical(req->addr + + (sign * i * req->size), + req->size, &tmp); -+ write_physical((target_phys_addr_t )req->u.pdata ++ write_physical((target_phys_addr_t )req->data + + (sign * i * req->size), + req->size, &tmp); + } + } else if (req->dir == IOREQ_WRITE) { + for (i = 0; i < req->count; i++) { -+ read_physical((target_phys_addr_t) req->u.pdata ++ read_physical((target_phys_addr_t) req->data + + (sign * i * req->size), + req->size, &tmp); + write_physical(req->addr @@ -1107,45 +1136,60 @@ Index: ioemu/target-i386-dm/helper2.c +{ + unsigned long tmp1, tmp2; + -+ if (req->pdata_valid != 0) ++ if (req->data_is_ptr != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { -+ tmp2 = tmp1 & (unsigned long) req->u.data; ++ tmp2 = tmp1 & (unsigned long) req->data; + write_physical(req->addr, req->size, &tmp2); + } -+ req->u.data = tmp1; -+} -+ -+void cpu_ioreq_or(CPUState *env, ioreq_t *req) ++ req->data = tmp1; ++} ++ ++void cpu_ioreq_add(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1, tmp2; + -+ if (req->pdata_valid != 0) ++ if (req->data_is_ptr != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { -+ tmp2 = tmp1 | (unsigned long) req->u.data; ++ tmp2 = tmp1 + (unsigned long) req->data; + write_physical(req->addr, req->size, &tmp2); + } -+ req->u.data = tmp1; -+} -+ -+void cpu_ioreq_xor(CPUState *env, ioreq_t *req) ++ req->data = tmp1; ++} ++ ++void cpu_ioreq_or(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1, tmp2; + -+ if (req->pdata_valid != 0) ++ if (req->data_is_ptr != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { -+ tmp2 = tmp1 ^ (unsigned long) req->u.data; ++ tmp2 = tmp1 | (unsigned long) req->data; + write_physical(req->addr, req->size, &tmp2); + } -+ req->u.data = tmp1; ++ req->data = tmp1; ++} ++ ++void cpu_ioreq_xor(CPUState *env, ioreq_t *req) ++{ ++ unsigned long tmp1, tmp2; ++ ++ if (req->data_is_ptr != 0) ++ hw_error("expected scalar value"); ++ ++ read_physical(req->addr, req->size, &tmp1); ++ if (req->dir == IOREQ_WRITE) { ++ tmp2 = tmp1 ^ (unsigned long) req->data; ++ write_physical(req->addr, req->size, &tmp2); ++ } ++ req->data = tmp1; +} + +void cpu_handle_ioreq(void *opaque) @@ -1154,9 +1198,9 @@ Index: ioemu/target-i386-dm/helper2.c + ioreq_t *req = cpu_get_ioreq(); + + if (req) { -+ if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) { ++ if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) { + if (req->size != 4) -+ req->u.data &= (1UL << (8 * req->size))-1; ++ req->data &= (1UL << (8 * req->size))-1; + } + + switch (req->type) { @@ -1169,6 +1213,9 @@ Index: ioemu/target-i386-dm/helper2.c + case IOREQ_TYPE_AND: + cpu_ioreq_and(env, req); + break; ++ case IOREQ_TYPE_ADD: ++ cpu_ioreq_add(env, req); ++ break; + case IOREQ_TYPE_OR: + cpu_ioreq_or(env, req); + break; @@ -1179,12 +1226,19 @@ Index: ioemu/target-i386-dm/helper2.c + hw_error("Invalid ioreq type 0x%x\n", req->type); + } + -+ /* No state change if state = STATE_IORESP_HOOK */ -+ if (req->state == STATE_IOREQ_INPROCESS) { -+ mb(); -+ req->state = STATE_IORESP_READY; -+ } -+ env->send_event = 1; ++ if (req->state != STATE_IOREQ_INPROCESS) { ++ fprintf(logfile, "Badness in I/O request ... not in service?!: " ++ "%x, ptr: %x, port: %"PRIx64", " ++ "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n", ++ req->state, req->data_is_ptr, req->addr, ++ req->data, req->count, req->size); ++ destroy_hvm_domain(); ++ return; ++ } ++ ++ wmb(); /* Update ioreq contents /then/ update state. */ ++ req->state = STATE_IORESP_READY; ++ xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]); + } +} + @@ -1197,8 +1251,6 @@ Index: ioemu/target-i386-dm/helper2.c + + qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env); + -+ env->send_event = 0; -+ + while (1) { + if (vm_running) { + if (shutdown_requested) @@ -1207,19 +1259,14 @@ Index: ioemu/target-i386-dm/helper2.c + + /* Wait up to 10 msec. */ + main_loop_wait(10); -+ -+ if (env->send_event) { -+ env->send_event = 0; -+ xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]); -+ } + } + return 0; +} Index: ioemu/target-i386-dm/i8259-dm.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/i8259-dm.c 2006-10-24 13:47:23.000000000 +0100 -@@ -0,0 +1,107 @@ ++++ ioemu/target-i386-dm/i8259-dm.c 2006-12-08 01:41:11.000000000 +0000 +@@ -0,0 +1,67 @@ +/* Xen 8259 stub for interrupt controller emulation + * + * Copyright (c) 2003-2004 Fabrice Bellard @@ -1244,58 +1291,18 @@ Index: ioemu/target-i386-dm/i8259-dm.c + * THE SOFTWARE. + */ +#include "vl.h" -+ -+/* debug PIC */ -+//#define DEBUG_PIC -+ -+//#define DEBUG_IRQ_LATENCY -+//#define DEBUG_IRQ_COUNT -+ +#include "xenctrl.h" +#include <xen/hvm/ioreq.h> +#include <stdio.h> +#include "cpu.h" +#include "cpu-all.h" + -+extern shared_iopage_t *shared_page; -+ +struct PicState2 { +}; + +void pic_set_irq_new(void *opaque, int irq, int level) +{ -+ /* PicState2 *s = opaque; */ -+ global_iodata_t *gio; -+ int mask; -+ -+ gio = &shared_page->sp_global; -+ mask = 1 << irq; -+ if ( gio->pic_elcr & mask ) { -+ /* level */ -+ if ( level ) { -+ atomic_clear_bit(irq, &gio->pic_clear_irr); -+ atomic_set_bit(irq, &gio->pic_irr); -+ cpu_single_env->send_event = 1; -+ } -+ else { -+ atomic_clear_bit(irq, &gio->pic_irr); -+ atomic_set_bit(irq, &gio->pic_clear_irr); -+ cpu_single_env->send_event = 1; -+ } -+ } -+ else { -+ /* edge */ -+ if ( level ) { -+ if ( (mask & gio->pic_last_irr) == 0 ) { -+ atomic_set_bit(irq, &gio->pic_irr); -+ atomic_set_bit(irq, &gio->pic_last_irr); -+ cpu_single_env->send_event = 1; -+ } -+ } -+ else { -+ atomic_clear_bit(irq, &gio->pic_last_irr); -+ } -+ } ++ xc_hvm_set_irq_level(xc_handle, domid, irq, level); +} + +/* obsolete function */ @@ -1330,17 +1337,22 @@ Index: ioemu/target-i386-dm/qemu-dm.debu Index: ioemu/target-i386-dm/qemu-dm.debug =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/qemu-dm.debug 2006-10-24 13:47:23.000000000 +0100 -@@ -0,0 +1,5 @@ ++++ ioemu/target-i386-dm/qemu-dm.debug 2006-12-08 01:41:11.000000000 +0000 +@@ -0,0 +1,10 @@ +#!/bin/sh + ++if [ "`arch`" = "x86_64" ]; then ++ LIBDIR="lib64" ++else ++ LIBDIR="lib" ++fi +echo $* > /tmp/args +echo $DISPLAY >> /tmp/args -+exec /usr/lib/xen/bin/qemu-dm $* ++exec /usr/$LIBDIR/xen/bin/qemu-dm $* Index: ioemu/target-i386-dm/qemu-ifup =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/target-i386-dm/qemu-ifup 2006-10-24 13:47:23.000000000 +0100 ++++ ioemu/target-i386-dm/qemu-ifup 2006-12-08 01:41:11.000000000 +0000 @@ -0,0 +1,10 @@ +#!/bin/sh + diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/series --- a/tools/ioemu/patches/series Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/series Sat Dec 09 14:34:53 2006 +0000 @@ -53,3 +53,19 @@ hypervisor-rtc hypervisor-rtc ide-cd-dma vnc-password +ne2000-bounds-checks +xenstore-device-info-functions +tpm-tis-device +qemu-serial-fixes +vnc-japan-keymap +rtl8139-bound-chaining +fix-interrupt-routing +nodelay-serial-over-tcp +remove-pci-bridge-setup +limit-fdc-sector-size-to-16K +usb-uhci-buffer-size +vnc-monitor-shift-key-processing +ide-error-reporting +vnc-numpad-handling +xen-mapcache -p3 +usb-mouse-tablet-status-check -p3 diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/shared-vram --- a/tools/ioemu/patches/shared-vram Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/shared-vram Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/hw/cirrus_vga.c Index: ioemu/hw/cirrus_vga.c =================================================================== ---- ioemu.orig/hw/cirrus_vga.c 2006-08-17 19:37:36.372522620 +0100 -+++ ioemu/hw/cirrus_vga.c 2006-08-17 19:49:52.157002909 +0100 +--- ioemu.orig/hw/cirrus_vga.c 2006-12-08 01:57:54.000000000 +0000 ++++ ioemu/hw/cirrus_vga.c 2006-12-08 02:00:04.000000000 +0000 @@ -28,6 +28,9 @@ */ #include "vl.h" @@ -176,8 +176,8 @@ Index: ioemu/hw/cirrus_vga.c } Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-17 19:49:50.229215988 +0100 -+++ ioemu/hw/pc.c 2006-08-17 19:49:52.158002799 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 02:00:04.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 02:00:04.000000000 +0000 @@ -790,14 +790,14 @@ if (cirrus_vga_enabled) { if (pci_enabled) { @@ -198,8 +198,8 @@ Index: ioemu/hw/pc.c Index: ioemu/hw/vga.c =================================================================== ---- ioemu.orig/hw/vga.c 2006-08-17 19:49:37.764593706 +0100 -+++ ioemu/hw/vga.c 2006-08-17 19:49:52.159002688 +0100 +--- ioemu.orig/hw/vga.c 2006-12-08 02:00:04.000000000 +0000 ++++ ioemu/hw/vga.c 2006-12-08 02:00:04.000000000 +0000 @@ -1858,6 +1858,7 @@ /* TODO: add vbe support if enabled */ } @@ -251,8 +251,8 @@ Index: ioemu/hw/vga.c Index: ioemu/hw/vga_int.h =================================================================== ---- ioemu.orig/hw/vga_int.h 2006-08-17 19:37:36.372522620 +0100 -+++ ioemu/hw/vga_int.h 2006-08-17 19:49:52.159002688 +0100 +--- ioemu.orig/hw/vga_int.h 2006-12-08 01:57:54.000000000 +0000 ++++ ioemu/hw/vga_int.h 2006-12-08 02:00:04.000000000 +0000 @@ -169,5 +169,6 @@ unsigned int color0, unsigned int color1, unsigned int color_xor); @@ -262,9 +262,9 @@ Index: ioemu/hw/vga_int.h extern const uint8_t gr_mask[16]; Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:49:50.231215767 +0100 -+++ ioemu/vl.c 2006-08-17 19:49:52.162002356 +0100 -@@ -5693,6 +5693,78 @@ +--- ioemu.orig/vl.c 2006-12-08 02:00:04.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:00:27.000000000 +0000 +@@ -5693,6 +5693,62 @@ #define MAX_NET_CLIENTS 32 @@ -303,9 +303,6 @@ Index: ioemu/vl.c + unsigned long nr_pages, unsigned int address_bits, + xen_pfn_t *extent_start) +{ -+#if 0 -+ int i; -+#endif + xc_dominfo_t info; + int err = 0; + @@ -324,19 +321,6 @@ Index: ioemu/vl.c + return -1; + } + -+ err = xc_domain_translate_gpfn_list(xc_handle, domid, nr_pages, -+ extent_start, extent_start); -+ if (err) { -+ fprintf(stderr, "Failed to translate gpfn list\n"); -+ return -1; -+ } -+ -+#if 0 /* Generates lots of log file output - turn on for debugging */ -+ for (i = 0; i < nr_pages; i++) -+ fprintf(stderr, "set_map result i %x result %lx\n", i, -+ extent_start[i]); -+#endif -+ + return 0; +} + @@ -345,8 +329,8 @@ Index: ioemu/vl.c #ifdef CONFIG_GDBSTUB Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:49:44.492850031 +0100 -+++ ioemu/vl.h 2006-08-17 19:49:52.163002246 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:00:04.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:00:04.000000000 +0000 @@ -145,6 +145,13 @@ void main_loop_wait(int timeout); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-access-monitor-vt --- a/tools/ioemu/patches/vnc-access-monitor-vt Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-access-monitor-vt Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:33:46.000000000 +0100 +--- ioemu.orig/vnc.c 2006-12-06 23:46:11.000000000 +0000 ++++ ioemu/vnc.c 2006-12-06 23:46:11.000000000 +0000 @@ -33,6 +33,10 @@ #include "vnc_keysym.h" #include "keymaps.c" @@ -22,7 +22,7 @@ Index: ioemu/vnc.c }; #define DIRTY_PIXEL_BITS 64 -@@ -794,16 +800,80 @@ +@@ -796,16 +802,80 @@ static void do_key_event(VncState *vs, int down, uint32_t sym) { diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-backoff-screen-scan --- a/tools/ioemu/patches/vnc-backoff-screen-scan Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-backoff-screen-scan Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 14:33:17.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:33:24.000000000 +0100 +--- ioemu.orig/vnc.c 2006-12-06 23:46:12.000000000 +0000 ++++ ioemu/vnc.c 2006-12-06 23:46:12.000000000 +0000 @@ -28,7 +28,19 @@ #include "qemu_socket.h" #include <assert.h> @@ -45,7 +45,7 @@ Index: ioemu/vnc.c int ctl_keys; /* Ctrl+Alt starts calibration */ }; -@@ -381,7 +392,7 @@ +@@ -383,7 +394,7 @@ int y = 0; int pitch = ds->linesize; VncState *vs = ds->opaque; @@ -54,7 +54,7 @@ Index: ioemu/vnc.c if (src_x < vs->visible_x || src_y < vs->visible_y || dst_x < vs->visible_x || dst_y < vs->visible_y || -@@ -391,10 +402,8 @@ +@@ -393,10 +404,8 @@ (dst_y + h) > (vs->visible_y + vs->visible_h)) updating_client = 0; @@ -66,7 +66,7 @@ Index: ioemu/vnc.c if (dst_y > src_y) { y = h - 1; -@@ -446,110 +455,149 @@ +@@ -448,110 +457,149 @@ static void _vnc_update_client(void *opaque) { VncState *vs = opaque; @@ -299,7 +299,7 @@ Index: ioemu/vnc.c } static void vnc_update_client(void *opaque) -@@ -562,8 +610,10 @@ +@@ -564,8 +612,10 @@ static void vnc_timer_init(VncState *vs) { @@ -311,7 +311,7 @@ Index: ioemu/vnc.c } static void vnc_dpy_refresh(DisplayState *ds) -@@ -623,7 +673,6 @@ +@@ -625,7 +675,6 @@ vs->csock = -1; buffer_reset(&vs->input); buffer_reset(&vs->output); @@ -319,7 +319,7 @@ Index: ioemu/vnc.c return 0; } return ret; -@@ -895,7 +944,6 @@ +@@ -897,7 +946,6 @@ int x_position, int y_position, int w, int h) { @@ -327,7 +327,7 @@ Index: ioemu/vnc.c if (!incremental) framebuffer_set_updated(vs, x_position, y_position, w, h); vs->visible_x = x_position; -@@ -1018,6 +1066,7 @@ +@@ -1020,6 +1068,7 @@ { int i; uint16_t limit; @@ -335,7 +335,7 @@ Index: ioemu/vnc.c switch (data[0]) { case 0: -@@ -1061,12 +1110,18 @@ +@@ -1063,12 +1112,18 @@ if (len == 1) return 8; @@ -356,8 +356,8 @@ Index: ioemu/vnc.c case 6: Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:17.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:33:24.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-06 23:46:12.000000000 +0000 ++++ ioemu/vl.c 2006-12-06 23:46:12.000000000 +0000 @@ -726,6 +726,12 @@ } } @@ -373,8 +373,8 @@ Index: ioemu/vl.c void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:33:17.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:33:24.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-06 23:46:12.000000000 +0000 ++++ ioemu/vl.h 2006-12-06 23:46:12.000000000 +0000 @@ -407,6 +407,7 @@ void qemu_free_timer(QEMUTimer *ts); void qemu_del_timer(QEMUTimer *ts); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-display-find-unused --- a/tools/ioemu/patches/vnc-display-find-unused Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-display-find-unused Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 14:31:09.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:31:36.000000000 +0100 -@@ -1195,7 +1195,7 @@ +--- ioemu.orig/vnc.c 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vnc.c 2006-12-08 02:02:37.000000000 +0000 +@@ -1197,7 +1197,7 @@ } } @@ -11,7 +11,7 @@ Index: ioemu/vnc.c { struct sockaddr_in addr; int reuse_addr, ret; -@@ -1226,10 +1226,6 @@ +@@ -1228,10 +1228,6 @@ exit(1); } @@ -22,7 +22,7 @@ Index: ioemu/vnc.c reuse_addr = 1; ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse_addr, sizeof(reuse_addr)); -@@ -1238,7 +1234,16 @@ +@@ -1240,7 +1236,16 @@ exit(1); } @@ -39,7 +39,7 @@ Index: ioemu/vnc.c fprintf(stderr, "bind() failed\n"); exit(1); } -@@ -1259,6 +1264,8 @@ +@@ -1261,6 +1266,8 @@ vs->ds->dpy_refresh = vnc_dpy_refresh; vnc_dpy_resize(vs->ds, 640, 400); @@ -50,8 +50,8 @@ Index: ioemu/vnc.c int vnc_start_viewer(int port) Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:31:09.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:31:41.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000 @@ -121,6 +121,7 @@ static DisplayState display_state; int nographic; @@ -84,7 +84,7 @@ Index: ioemu/vl.c /* temporary options */ { "usb", 0, QEMU_OPTION_usb }, -@@ -5873,6 +5877,7 @@ +@@ -5857,6 +5861,7 @@ snapshot = 0; nographic = 0; vncviewer = 0; @@ -92,7 +92,7 @@ Index: ioemu/vl.c kernel_filename = NULL; kernel_cmdline = ""; #ifdef TARGET_PPC -@@ -6270,6 +6275,11 @@ +@@ -6254,6 +6259,11 @@ case QEMU_OPTION_vncviewer: vncviewer++; break; @@ -104,7 +104,7 @@ Index: ioemu/vl.c } } } -@@ -6483,7 +6493,7 @@ +@@ -6468,7 +6478,7 @@ if (nographic) { dumb_display_init(ds); } else if (vnc_display != -1) { @@ -115,8 +115,8 @@ Index: ioemu/vl.c } else { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:31:09.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:31:36.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000 @@ -785,7 +785,7 @@ void cocoa_display_init(DisplayState *ds, int full_screen); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-fixes --- a/tools/ioemu/patches/vnc-fixes Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-fixes Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/vl.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:19:36.000000000 +0100 -@@ -6534,8 +6534,10 @@ +--- ioemu.orig/vl.c 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:36.000000000 +0000 +@@ -6519,8 +6519,10 @@ } } @@ -17,8 +17,8 @@ Index: ioemu/vl.c if (use_gdbstub) { Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:20:00.000000000 +0100 +--- ioemu.orig/vnc.c 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vnc.c 2006-12-08 02:02:36.000000000 +0000 @@ -3,6 +3,7 @@ * * Copyright (C) 2006 Anthony Liguori <anthony@xxxxxxxxxxxxx> @@ -92,7 +92,7 @@ Index: ioemu/vnc.c static inline void vnc_set_bit(uint32_t *d, int k) { d[k >> 5] |= 1 << (k & 0x1f); -@@ -139,20 +161,35 @@ +@@ -139,20 +161,37 @@ } return 0; } @@ -121,6 +121,8 @@ Index: ioemu/vnc.c mask = ~(0ULL); + h += y; ++ if (h > vs->ds->height) ++ h = vs->ds->height; for (; y < h; y++) - vs->dirty_row[y] |= mask; + row[y] |= mask; @@ -134,7 +136,7 @@ Index: ioemu/vnc.c } static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, -@@ -169,16 +206,23 @@ +@@ -169,16 +208,23 @@ static void vnc_dpy_resize(DisplayState *ds, int w, int h) { VncState *vs = ds->opaque; @@ -160,7 +162,7 @@ Index: ioemu/vnc.c ds->width = w; ds->height = h; ds->linesize = w * vs->depth; -@@ -191,6 +235,10 @@ +@@ -191,6 +237,10 @@ vs->width = ds->width; vs->height = ds->height; } @@ -171,7 +173,7 @@ Index: ioemu/vnc.c } /* fastest code */ -@@ -326,8 +374,20 @@ +@@ -326,8 +376,20 @@ int y = 0; int pitch = ds->linesize; VncState *vs = ds->opaque; @@ -193,7 +195,7 @@ Index: ioemu/vnc.c if (dst_y > src_y) { y = h - 1; -@@ -349,31 +409,34 @@ +@@ -349,31 +411,34 @@ old_row += pitch; } @@ -240,7 +242,7 @@ Index: ioemu/vnc.c { VncState *vs = opaque; int64_t now = qemu_get_clock(rt_clock); -@@ -382,14 +445,18 @@ +@@ -382,14 +447,18 @@ int y; char *row; char *old_row; @@ -262,7 +264,7 @@ Index: ioemu/vnc.c /* Walk through the dirty map and eliminate tiles that really aren't dirty */ -@@ -397,23 +464,25 @@ +@@ -397,23 +466,25 @@ old_row = vs->old_data; for (y = 0; y < vs->ds->height; y++) { @@ -297,7 +299,7 @@ Index: ioemu/vnc.c } } -@@ -421,7 +490,8 @@ +@@ -421,7 +492,8 @@ old_row += vs->ds->linesize; } @@ -307,7 +309,7 @@ Index: ioemu/vnc.c return; /* Count rectangles */ -@@ -431,34 +501,56 @@ +@@ -431,34 +503,56 @@ saved_offset = vs->output.offset; vnc_write_u16(vs, 0); @@ -375,7 +377,7 @@ Index: ioemu/vnc.c } static void vnc_timer_init(VncState *vs) -@@ -469,8 +561,6 @@ +@@ -469,8 +563,6 @@ static void vnc_dpy_refresh(DisplayState *ds) { @@ -384,7 +386,7 @@ Index: ioemu/vnc.c vga_hw_update(); } -@@ -506,7 +596,7 @@ +@@ -506,7 +598,7 @@ static void buffer_reset(Buffer *buffer) { @@ -393,7 +395,7 @@ Index: ioemu/vnc.c } static void buffer_append(Buffer *buffer, const void *data, size_t len) -@@ -547,12 +637,12 @@ +@@ -547,12 +639,12 @@ if (!ret) return; @@ -409,7 +411,7 @@ Index: ioemu/vnc.c } static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting) -@@ -584,11 +674,11 @@ +@@ -584,11 +676,11 @@ return; if (!ret) { @@ -424,7 +426,7 @@ Index: ioemu/vnc.c } } -@@ -596,9 +686,9 @@ +@@ -596,9 +688,9 @@ { buffer_reserve(&vs->output, len); @@ -437,7 +439,7 @@ Index: ioemu/vnc.c buffer_append(&vs->output, data, len); } -@@ -720,22 +810,25 @@ +@@ -720,22 +812,25 @@ do_key_event(vs, down, sym); } @@ -474,7 +476,7 @@ Index: ioemu/vnc.c qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock)); } -@@ -843,8 +936,6 @@ +@@ -843,8 +938,6 @@ } vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height); @@ -483,7 +485,7 @@ Index: ioemu/vnc.c vga_hw_invalidate(); vga_hw_update(); -@@ -924,6 +1015,8 @@ +@@ -924,6 +1017,8 @@ { char pad[3] = { 0, 0, 0 }; @@ -492,7 +494,7 @@ Index: ioemu/vnc.c vs->width = vs->ds->width; vs->height = vs->ds->height; vnc_write_u16(vs, vs->ds->width); -@@ -1010,11 +1103,11 @@ +@@ -1010,11 +1105,11 @@ vnc_write(vs, "RFB 003.003\n", 12); vnc_flush(vs); vnc_read_when(vs, protocol_version, 12); @@ -506,7 +508,7 @@ Index: ioemu/vnc.c } } -@@ -1071,17 +1164,15 @@ +@@ -1071,17 +1166,15 @@ exit(1); } @@ -529,8 +531,8 @@ Index: ioemu/vnc.c } Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 13:47:23.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:19:36.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:36.000000000 +0000 @@ -319,6 +319,7 @@ int is_graphic_console(void); CharDriverState *text_console_init(DisplayState *ds); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-listen-specific-interface --- a/tools/ioemu/patches/vnc-listen-specific-interface Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-listen-specific-interface Sat Dec 09 14:34:53 2006 +0000 @@ -20,8 +20,8 @@ Signed-off-by: Daniel P. Berrange <berr Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:34:28.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000 @@ -122,6 +122,7 @@ int nographic; int vncviewer; @@ -95,7 +95,7 @@ Index: ioemu/vl.c /* temporary options */ { "usb", 0, QEMU_OPTION_usb }, -@@ -5905,6 +5915,8 @@ +@@ -5889,6 +5899,8 @@ nb_nics = 0; /* default mac address of the first network interface */ @@ -103,8 +103,8 @@ Index: ioemu/vl.c + memset(&vnclisten_addr.sin_addr, 0, sizeof(vnclisten_addr.sin_addr)); /* init debug */ - sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%d.log", getpid()); -@@ -6280,6 +6292,9 @@ + sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%ld.log", (long)getpid()); +@@ -6264,6 +6276,9 @@ if (vnc_display == -1) vnc_display = 0; break; @@ -114,7 +114,7 @@ Index: ioemu/vl.c } } } -@@ -6493,7 +6508,7 @@ +@@ -6478,7 +6493,7 @@ if (nographic) { dumb_display_init(ds); } else if (vnc_display != -1) { @@ -125,8 +125,8 @@ Index: ioemu/vl.c } else { Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:34:22.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000 @@ -37,6 +37,8 @@ #include <unistd.h> #include <fcntl.h> @@ -147,9 +147,9 @@ Index: ioemu/vl.h /* ide.c */ Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:34:22.000000000 +0100 -@@ -1195,9 +1195,8 @@ +--- ioemu.orig/vnc.c 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vnc.c 2006-12-08 02:02:37.000000000 +0000 +@@ -1197,9 +1197,8 @@ } } @@ -160,7 +160,7 @@ Index: ioemu/vnc.c int reuse_addr, ret; VncState *vs; -@@ -1235,11 +1234,10 @@ +@@ -1237,11 +1236,10 @@ } retry: diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-password --- a/tools/ioemu/patches/vnc-password Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-password Sat Dec 09 14:34:53 2006 +0000 @@ -15,9 +15,11 @@ The difference is follows. Signed-off-by: Masami Watanabe <masami.watanabe@xxxxxxxxxxxxxx> ---- ioemu/Makefile.target Fri Oct 20 09:32:16 2006 +0100 -+++ ioemu/Makefile.target Fri Oct 20 09:50:09 2006 +0100 -@@ -406,6 +406,7 @@ VL_OBJS+=sdl.o +Index: ioemu/Makefile.target +=================================================================== +--- ioemu.orig/Makefile.target 2006-12-08 18:20:53.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 18:20:53.000000000 +0000 +@@ -407,6 +407,7 @@ VL_OBJS+=sdl.o endif VL_OBJS+=vnc.o @@ -25,29 +27,31 @@ Signed-off-by: Masami Watanabe <masami.w ifdef CONFIG_COCOA VL_OBJS+=cocoa.o COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit -@@ -464,6 +465,9 @@ sdl.o: sdl.c keymaps.c sdl_keysym.h +@@ -467,6 +468,9 @@ + vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h + $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< + ++d3des.o: d3des.c d3des.h ++ $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< ++ + sdlaudio.o: sdlaudio.c $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $< - vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h -+ $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< -+ -+d3des.o: d3des.c d3des.h - $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< - - sdlaudio.o: sdlaudio.c ---- ioemu/vl.c Fri Oct 20 09:32:16 2006 +0100 -+++ ioemu/vl.c Fri Oct 20 09:50:09 2006 +0100 -@@ -170,6 +170,9 @@ time_t timeoffset = 0; - +Index: ioemu/vl.c +=================================================================== +--- ioemu.orig/vl.c 2006-12-08 18:20:52.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 18:20:53.000000000 +0000 +@@ -171,6 +171,9 @@ char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'}; extern int domid; -+ + +char vncpasswd[64]; +unsigned char challenge[AUTHCHALLENGESIZE]; - ++ /***********************************************************/ /* x86 ISA bus support */ -@@ -5911,6 +5914,7 @@ int main(int argc, char **argv) + +@@ -5895,6 +5898,7 @@ vncunused = 0; kernel_filename = NULL; kernel_cmdline = ""; @@ -55,7 +59,7 @@ Signed-off-by: Masami Watanabe <masami.w #ifndef CONFIG_DM #ifdef TARGET_PPC cdrom_index = 1; -@@ -6559,6 +6563,10 @@ int main(int argc, char **argv) +@@ -6543,6 +6547,10 @@ init_ioports(); @@ -66,9 +70,11 @@ Signed-off-by: Masami Watanabe <masami.w /* terminal init */ if (nographic) { dumb_display_init(ds); ---- ioemu/vl.h Fri Oct 20 09:32:16 2006 +0100 -+++ ioemu/vl.h Fri Oct 20 09:50:09 2006 +0100 -@@ -1211,6 +1211,7 @@ void xenstore_process_event(void *opaque +Index: ioemu/vl.h +=================================================================== +--- ioemu.orig/vl.h 2006-12-08 18:20:52.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 18:20:53.000000000 +0000 +@@ -1214,6 +1214,7 @@ void xenstore_process_event(void *opaque); void xenstore_check_new_media_present(int timeout); void xenstore_write_vncport(int vnc_display); @@ -76,7 +82,7 @@ Signed-off-by: Masami Watanabe <masami.w /* xen_platform.c */ void pci_xen_platform_init(PCIBus *bus); -@@ -1222,4 +1223,7 @@ extern char domain_name[]; +@@ -1225,4 +1226,7 @@ void destroy_hvm_domain(void); @@ -84,8 +90,10 @@ Signed-off-by: Masami Watanabe <masami.w +#define AUTHCHALLENGESIZE 16 + #endif /* VL_H */ ---- ioemu/vnc.c Fri Oct 20 09:32:16 2006 +0100 -+++ ioemu/vnc.c Fri Oct 20 09:50:09 2006 +0100 +Index: ioemu/vnc.c +=================================================================== +--- ioemu.orig/vnc.c 2006-12-08 18:20:52.000000000 +0000 ++++ ioemu/vnc.c 2006-12-08 18:20:53.000000000 +0000 @@ -44,6 +44,7 @@ #include "vnc_keysym.h" @@ -94,7 +102,7 @@ Signed-off-by: Masami Watanabe <masami.w #define XK_MISCELLANY #define XK_LATIN1 -@@ -137,6 +138,9 @@ static void vnc_update_client(void *opaq +@@ -137,6 +138,9 @@ static void vnc_update_client(void *opaque); static void vnc_client_read(void *opaque); static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h); @@ -104,7 +112,7 @@ Signed-off-by: Masami Watanabe <masami.w #if 0 static inline void vnc_set_bit(uint32_t *d, int k) -@@ -1208,23 +1212,92 @@ static int protocol_client_init(VncState +@@ -1210,23 +1214,92 @@ return 0; } @@ -166,9 +174,8 @@ Signed-off-by: Masami Watanabe <masami.w - vnc_write_u32(vs, 1); /* None */ - vnc_flush(vs); -- + - vnc_read_when(vs, protocol_client_init, 1); -+ + support = 0; + if (maj = 3) { + if (min == 3 || min ==4) { @@ -202,7 +209,7 @@ Signed-off-by: Masami Watanabe <masami.w return 0; } -@@ -1342,3 +1415,32 @@ int vnc_start_viewer(int port) +@@ -1344,3 +1417,32 @@ return pid; } } @@ -235,9 +242,11 @@ Signed-off-by: Masami Watanabe <masami.w + + return; +} ---- ioemu/xenstore.c Fri Oct 20 09:32:16 2006 +0100 -+++ ioemu/xenstore.c Fri Oct 20 09:50:09 2006 +0100 -@@ -213,3 +213,54 @@ void xenstore_write_vncport(int display) +Index: ioemu/xenstore.c +=================================================================== +--- ioemu.orig/xenstore.c 2006-12-08 18:20:52.000000000 +0000 ++++ ioemu/xenstore.c 2006-12-08 18:20:53.000000000 +0000 +@@ -213,3 +213,54 @@ free(portstr); free(buf); } @@ -292,8 +301,10 @@ Signed-off-by: Masami Watanabe <masami.w + + return rc; +} ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ioemu/d3des.c Fri Oct 20 09:50:09 2006 +0100 +Index: ioemu/d3des.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ ioemu/d3des.c 2006-12-08 18:20:53.000000000 +0000 @@ -0,0 +1,434 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and @@ -729,8 +740,10 @@ Signed-off-by: Masami Watanabe <masami.w + * + * d3des V5.0a rwo 9208.07 18:44 Graven Imagery + **********************************************************************/ ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ioemu/d3des.h Fri Oct 20 09:50:09 2006 +0100 +Index: ioemu/d3des.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ ioemu/d3des.h 2006-12-08 18:20:53.000000000 +0000 @@ -0,0 +1,51 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-protocol-fixes --- a/tools/ioemu/patches/vnc-protocol-fixes Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-protocol-fixes Sat Dec 09 14:34:53 2006 +0000 @@ -9,8 +9,8 @@ Signed-off-by: Steven Smith <sos22@xxxxx Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 14:28:05.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:30:11.000000000 +0100 +--- ioemu.orig/vnc.c 2006-12-06 23:46:11.000000000 +0000 ++++ ioemu/vnc.c 2006-12-06 23:46:11.000000000 +0000 @@ -26,6 +26,7 @@ #include "vl.h" @@ -19,7 +19,7 @@ Index: ioemu/vnc.c #define VNC_REFRESH_INTERVAL (1000 / 30) -@@ -677,8 +678,10 @@ +@@ -679,8 +680,10 @@ memmove(vs->input.buffer, vs->input.buffer + len, vs->input.offset - len); vs->input.offset -= len; @@ -31,7 +31,7 @@ Index: ioemu/vnc.c } } -@@ -961,8 +964,12 @@ +@@ -963,8 +966,12 @@ if (len == 1) return 4; @@ -46,7 +46,7 @@ Index: ioemu/vnc.c limit = read_u16(data, 2); for (i = 0; i < limit; i++) { -@@ -996,8 +1003,12 @@ +@@ -998,8 +1005,12 @@ if (len == 1) return 8; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-start-vncviewer --- a/tools/ioemu/patches/vnc-start-vncviewer Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-start-vncviewer Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:33:46.000000000 +0100 -@@ -1187,3 +1187,25 @@ +--- ioemu.orig/vnc.c 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vnc.c 2006-12-08 02:02:36.000000000 +0000 +@@ -1189,3 +1189,25 @@ vnc_dpy_resize(vs->ds, 640, 400); } @@ -30,8 +30,8 @@ Index: ioemu/vnc.c +} Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:33:46.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:36.000000000 +0000 @@ -120,6 +120,7 @@ int bios_size; static DisplayState display_state; @@ -64,7 +64,7 @@ Index: ioemu/vl.c /* temporary options */ { "usb", 0, QEMU_OPTION_usb }, -@@ -5868,6 +5872,7 @@ +@@ -5852,6 +5856,7 @@ #endif snapshot = 0; nographic = 0; @@ -72,7 +72,7 @@ Index: ioemu/vl.c kernel_filename = NULL; kernel_cmdline = ""; #ifdef TARGET_PPC -@@ -6262,6 +6267,9 @@ +@@ -6246,6 +6251,9 @@ case QEMU_OPTION_acpi: acpi_enabled = 1; break; @@ -82,7 +82,7 @@ Index: ioemu/vl.c } } } -@@ -6476,6 +6484,8 @@ +@@ -6461,6 +6469,8 @@ dumb_display_init(ds); } else if (vnc_display != -1) { vnc_display_init(ds, vnc_display); @@ -93,8 +93,8 @@ Index: ioemu/vl.c sdl_display_init(ds, full_screen); Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:33:46.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:36.000000000 +0000 @@ -786,6 +786,7 @@ /* vnc.c */ diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-title-domain-name --- a/tools/ioemu/patches/vnc-title-domain-name Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/vnc-title-domain-name Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/vnc.c Index: ioemu/vnc.c =================================================================== ---- ioemu.orig/vnc.c 2006-10-24 14:33:46.000000000 +0100 -+++ ioemu/vnc.c 2006-10-24 14:33:46.000000000 +0100 -@@ -1024,6 +1024,7 @@ +--- ioemu.orig/vnc.c 2006-12-06 23:46:11.000000000 +0000 ++++ ioemu/vnc.c 2006-12-06 23:46:11.000000000 +0000 +@@ -1026,6 +1026,7 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) { @@ -10,7 +10,7 @@ Index: ioemu/vnc.c char pad[3] = { 0, 0, 0 }; vga_hw_update(); -@@ -1071,8 +1072,10 @@ +@@ -1073,8 +1074,10 @@ vnc_write(vs, pad, 3); /* padding */ diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-build --- a/tools/ioemu/patches/xen-build Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/xen-build Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/Makefile Index: ioemu/Makefile =================================================================== ---- ioemu.orig/Makefile 2006-10-24 14:37:25.000000000 +0100 -+++ ioemu/Makefile 2006-10-24 14:37:28.000000000 +0100 +--- ioemu.orig/Makefile 2006-12-08 01:26:04.000000000 +0000 ++++ ioemu/Makefile 2006-12-08 01:26:06.000000000 +0000 @@ -1,11 +1,14 @@ # Makefile for QEMU. @@ -85,8 +85,8 @@ Index: ioemu/Makefile info: qemu-doc.info qemu-tech.info Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-10-24 14:37:25.000000000 +0100 -+++ ioemu/Makefile.target 2006-10-24 14:40:25.000000000 +0100 +--- ioemu.orig/Makefile.target 2006-12-08 01:26:04.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 01:41:05.000000000 +0000 @@ -1,5 +1,8 @@ include config.mak @@ -120,9 +120,13 @@ Index: ioemu/Makefile.target #CFLAGS+=-Werror LDFLAGS=-g LIBS= -@@ -167,6 +177,9 @@ - - DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +@@ -165,8 +175,12 @@ + + ######################################################### + +-DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE ++DEFINES+=-D_GNU_SOURCE ++#-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE LIBS+=-lm +LIBS+=-L../../libxc -lxenctrl -lxenguest +LIBS+=-L../../xenstore -lxenstore @@ -130,7 +134,7 @@ Index: ioemu/Makefile.target ifndef CONFIG_USER_ONLY LIBS+=-lz endif -@@ -281,7 +294,7 @@ +@@ -281,7 +295,7 @@ all: $(PROGS) $(QEMU_USER): $(OBJS) @@ -139,7 +143,7 @@ Index: ioemu/Makefile.target ifeq ($(ARCH),alpha) # Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of # the address space (31 bit so sign extending doesn't matter) -@@ -528,10 +541,16 @@ +@@ -528,10 +542,16 @@ clean: rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o @@ -159,8 +163,8 @@ Index: ioemu/Makefile.target include .depend Index: ioemu/configure =================================================================== ---- ioemu.orig/configure 2006-10-24 14:37:25.000000000 +0100 -+++ ioemu/configure 2006-10-24 14:40:20.000000000 +0100 +--- ioemu.orig/configure 2006-12-08 01:26:04.000000000 +0000 ++++ ioemu/configure 2006-12-08 01:40:58.000000000 +0000 @@ -18,8 +18,8 @@ # default parameters diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-mm --- a/tools/ioemu/patches/xen-mm Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/xen-mm Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/hw/pc.c Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-08-17 19:36:00.588166019 +0100 -+++ ioemu/hw/pc.c 2006-08-17 19:37:36.704485734 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 02:00:38.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 02:02:07.000000000 +0000 @@ -646,7 +646,9 @@ } @@ -25,8 +25,8 @@ Index: ioemu/hw/pc.c isa_bios_size = bios_size; Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-08-17 19:36:00.667157242 +0100 -+++ ioemu/vl.c 2006-08-17 19:47:08.538087284 +0100 +--- ioemu.orig/vl.c 2006-12-08 02:00:39.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:28.000000000 +0000 @@ -158,6 +158,8 @@ int acpi_enabled = 1; int fd_bootchk = 1; @@ -60,7 +60,7 @@ Index: ioemu/vl.c break; case QEMU_OPTION_l: { -@@ -6133,12 +6140,67 @@ +@@ -6133,12 +6140,61 @@ /* init the memory */ phys_ram_size = ram_size + vga_ram_size + bios_size; @@ -85,14 +85,8 @@ Index: ioemu/vl.c + exit(-1); + } + -+ if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) { -+ fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno); -+ exit(-1); -+ } -+ -+ if (ram_size > HVM_BELOW_4G_RAM_END) -+ for (i = 0; i < nr_pages - (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT); i++) -+ page_array[tmp_nr_pages - 1 - i] = page_array[nr_pages - 1 - i]; ++ for ( i = 0; i < tmp_nr_pages; i++) ++ page_array[i] = i; + + phys_ram_base = xc_map_foreign_batch(xc_handle, domid, + PROT_READ|PROT_WRITE, page_array, @@ -130,8 +124,8 @@ Index: ioemu/vl.c if (cdrom_index >= 0) { Index: ioemu/hw/piix_pci.c =================================================================== ---- ioemu.orig/hw/piix_pci.c 2006-08-17 19:37:36.189542951 +0100 -+++ ioemu/hw/piix_pci.c 2006-08-17 19:38:05.806252180 +0100 +--- ioemu.orig/hw/piix_pci.c 2006-12-08 02:00:36.000000000 +0000 ++++ ioemu/hw/piix_pci.c 2006-12-08 02:02:06.000000000 +0000 @@ -399,7 +399,7 @@ uint8_t elcr[2]; @@ -143,8 +137,8 @@ Index: ioemu/hw/piix_pci.c elcr[0] = 0x00; Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-08-17 19:37:36.529505177 +0100 -+++ ioemu/vl.h 2006-08-17 19:47:32.680418959 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:00:39.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:07.000000000 +0000 @@ -39,6 +39,7 @@ #include <sys/stat.h> #include "xenctrl.h" diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-platform-device --- a/tools/ioemu/patches/xen-platform-device Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/xen-platform-device Sat Dec 09 14:34:53 2006 +0000 @@ -3,9 +3,9 @@ will come later. Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-10-24 14:41:01.000000000 +0100 -+++ ioemu/Makefile.target 2006-10-24 14:41:01.000000000 +0100 -@@ -359,6 +359,7 @@ +--- ioemu.orig/Makefile.target 2006-12-08 01:41:14.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 01:41:15.000000000 +0000 +@@ -360,6 +360,7 @@ VL_OBJS+= usb-uhci.o VL_OBJS+= piix4acpi.o VL_OBJS+= xenstore.o @@ -15,8 +15,8 @@ Index: ioemu/Makefile.target ifeq ($(TARGET_BASE_ARCH), ppc) Index: ioemu/hw/pc.c =================================================================== ---- ioemu.orig/hw/pc.c 2006-10-24 14:41:00.000000000 +0100 -+++ ioemu/hw/pc.c 2006-10-24 14:41:01.000000000 +0100 +--- ioemu.orig/hw/pc.c 2006-12-08 01:41:13.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 01:41:15.000000000 +0000 @@ -823,6 +823,9 @@ } #endif /* !CONFIG_DM */ @@ -30,7 +30,7 @@ Index: ioemu/hw/xen_platform.c Index: ioemu/hw/xen_platform.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/hw/xen_platform.c 2006-10-24 14:41:04.000000000 +0100 ++++ ioemu/hw/xen_platform.c 2006-12-08 01:41:15.000000000 +0000 @@ -0,0 +1,144 @@ +/* + * XEN platform fake pci device, formerly known as the event channel device @@ -178,8 +178,8 @@ Index: ioemu/hw/xen_platform.c +} Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:41:01.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:41:01.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 01:41:14.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 01:41:15.000000000 +0000 @@ -1212,6 +1212,9 @@ void xenstore_check_new_media_present(int timeout); void xenstore_write_vncport(int vnc_display); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-support-buffered-ioreqs --- a/tools/ioemu/patches/xen-support-buffered-ioreqs Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/xen-support-buffered-ioreqs Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/vl.c Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100 -@@ -5854,6 +5854,7 @@ +--- ioemu.orig/vl.c 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000 +@@ -5838,6 +5838,7 @@ unsigned long nr_pages, tmp_nr_pages, shared_page_nr; xen_pfn_t *page_array; extern void *shared_page; @@ -10,11 +10,10 @@ Index: ioemu/vl.c char qemu_dm_logfilename[64]; -@@ -6440,6 +6441,18 @@ +@@ -6418,6 +6419,17 @@ fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", shared_page_nr, (uint64_t)(page_array[shared_page_nr])); -+ /* not yet add for IA64 */ + buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, + PROT_READ|PROT_WRITE, + page_array[shared_page_nr - 2]); @@ -31,8 +30,8 @@ Index: ioemu/vl.c #elif defined(__ia64__) Index: ioemu/target-i386-dm/helper2.c =================================================================== ---- ioemu.orig/target-i386-dm/helper2.c 2006-10-24 14:33:45.000000000 +0100 -+++ ioemu/target-i386-dm/helper2.c 2006-10-24 14:33:47.000000000 +0100 +--- ioemu.orig/target-i386-dm/helper2.c 2006-12-08 02:02:35.000000000 +0000 ++++ ioemu/target-i386-dm/helper2.c 2006-12-08 02:02:37.000000000 +0000 @@ -76,6 +76,10 @@ shared_iopage_t *shared_page = NULL; @@ -44,14 +43,14 @@ Index: ioemu/target-i386-dm/helper2.c /* the evtchn fd for polling */ int xce_handle = -1; -@@ -419,36 +423,68 @@ - req->u.data = tmp1; +@@ -435,39 +439,71 @@ + req->data = tmp1; } +void __handle_ioreq(CPUState *env, ioreq_t *req) +{ -+ if (!req->pdata_valid && req->dir == IOREQ_WRITE && req->size != 4) -+ req->u.data &= (1UL << (8 * req->size)) - 1; ++ if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4) ++ req->data &= (1UL << (8 * req->size)) - 1; + + switch (req->type) { + case IOREQ_TYPE_PIO: @@ -62,6 +61,9 @@ Index: ioemu/target-i386-dm/helper2.c + break; + case IOREQ_TYPE_AND: + cpu_ioreq_and(env, req); ++ break; ++ case IOREQ_TYPE_ADD: ++ cpu_ioreq_add(env, req); + break; + case IOREQ_TYPE_OR: + cpu_ioreq_or(env, req); @@ -109,9 +111,9 @@ Index: ioemu/target-i386-dm/helper2.c + handle_buffered_io(env); if (req) { -- if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) { +- if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) { - if (req->size != 4) -- req->u.data &= (1UL << (8 * req->size))-1; +- req->data &= (1UL << (8 * req->size))-1; - } - - switch (req->type) { @@ -124,6 +126,9 @@ Index: ioemu/target-i386-dm/helper2.c - case IOREQ_TYPE_AND: - cpu_ioreq_and(env, req); - break; +- case IOREQ_TYPE_ADD: +- cpu_ioreq_add(env, req); +- break; - case IOREQ_TYPE_OR: - cpu_ioreq_or(env, req); - break; @@ -135,9 +140,9 @@ Index: ioemu/target-i386-dm/helper2.c - } + __handle_ioreq(env, req); - /* No state change if state = STATE_IORESP_HOOK */ - if (req->state == STATE_IOREQ_INPROCESS) { -@@ -466,6 +502,10 @@ + if (req->state != STATE_IOREQ_INPROCESS) { + fprintf(logfile, "Badness in I/O request ... not in service?!: " +@@ -492,6 +528,10 @@ CPUState *env = cpu_single_env; int evtchn_fd = xc_evtchn_fd(xce_handle); @@ -147,4 +152,4 @@ Index: ioemu/target-i386-dm/helper2.c + qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env); - env->send_event = 0; + while (1) { diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xenstore-block-device-config --- a/tools/ioemu/patches/xenstore-block-device-config Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/xenstore-block-device-config Sat Dec 09 14:34:53 2006 +0000 @@ -1,8 +1,8 @@ Index: ioemu/Makefile.target Index: ioemu/Makefile.target =================================================================== ---- ioemu.orig/Makefile.target 2006-10-24 14:31:36.000000000 +0100 -+++ ioemu/Makefile.target 2006-10-24 14:33:28.000000000 +0100 -@@ -358,6 +358,7 @@ +--- ioemu.orig/Makefile.target 2006-12-08 02:02:36.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 02:02:37.000000000 +0000 +@@ -359,6 +359,7 @@ VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o VL_OBJS+= usb-uhci.o VL_OBJS+= piix4acpi.o @@ -13,7 +13,7 @@ Index: ioemu/xenstore.c Index: ioemu/xenstore.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ioemu/xenstore.c 2006-10-24 14:33:28.000000000 +0100 ++++ ioemu/xenstore.c 2006-12-08 02:02:37.000000000 +0000 @@ -0,0 +1,187 @@ +/* + * This file is subject to the terms and conditions of the GNU General @@ -117,7 +117,7 @@ Index: ioemu/xenstore.c + if (strncmp(dev, "hd", 2) || strlen(dev) != 3) + continue; + hd_index = dev[2] - 'a'; -+ if (hd_index > MAX_DISKS) ++ if (hd_index >= MAX_DISKS) + continue; + /* read the type of the device */ + if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1) @@ -204,8 +204,8 @@ Index: ioemu/xenstore.c +} Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:24.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:33:28.000000000 +0100 +--- ioemu.orig/vl.c 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000 @@ -5256,9 +5256,11 @@ "Standard options:\n" "-M machine select emulated machine (-M ? for list)\n" @@ -246,7 +246,7 @@ Index: ioemu/vl.c { "boot", HAS_ARG, QEMU_OPTION_boot }, { "snapshot", 0, QEMU_OPTION_snapshot }, #ifdef TARGET_I386 -@@ -5817,10 +5823,16 @@ +@@ -5801,10 +5807,16 @@ #ifdef CONFIG_GDBSTUB int use_gdbstub, gdbstub_port; #endif @@ -265,7 +265,7 @@ Index: ioemu/vl.c const char *kernel_filename, *kernel_cmdline; DisplayState *ds = &display_state; int cyls, heads, secs, translation; -@@ -5881,8 +5893,10 @@ +@@ -5865,8 +5877,10 @@ initrd_filename = NULL; for(i = 0; i < MAX_FD; i++) fd_filename[i] = NULL; @@ -276,7 +276,7 @@ Index: ioemu/vl.c ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; vga_ram_size = VGA_RAM_SIZE; bios_size = BIOS_SIZE; -@@ -5896,11 +5910,13 @@ +@@ -5880,11 +5894,13 @@ vncunused = 0; kernel_filename = NULL; kernel_cmdline = ""; @@ -290,7 +290,7 @@ Index: ioemu/vl.c cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; pstrcpy(monitor_device, sizeof(monitor_device), "vc"); -@@ -5935,7 +5951,11 @@ +@@ -5919,7 +5935,11 @@ break; r = argv[optind]; if (r[0] != '-') { @@ -302,7 +302,7 @@ Index: ioemu/vl.c } else { const QEMUOption *popt; -@@ -5979,6 +5999,7 @@ +@@ -5963,6 +5983,7 @@ case QEMU_OPTION_initrd: initrd_filename = optarg; break; @@ -310,7 +310,7 @@ Index: ioemu/vl.c case QEMU_OPTION_hda: case QEMU_OPTION_hdb: case QEMU_OPTION_hdc: -@@ -5991,6 +6012,7 @@ +@@ -5975,6 +5996,7 @@ cdrom_index = -1; } break; @@ -318,7 +318,7 @@ Index: ioemu/vl.c case QEMU_OPTION_snapshot: snapshot = 1; break; -@@ -6043,11 +6065,13 @@ +@@ -6027,11 +6049,13 @@ case QEMU_OPTION_append: kernel_cmdline = optarg; break; @@ -332,7 +332,7 @@ Index: ioemu/vl.c case QEMU_OPTION_boot: boot_device = optarg[0]; if (boot_device != 'a' && -@@ -6305,12 +6329,18 @@ +@@ -6289,12 +6313,18 @@ } } @@ -351,7 +351,7 @@ Index: ioemu/vl.c if (!linux_boot && hd_filename[0] == '\0' && (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') && -@@ -6324,6 +6354,7 @@ +@@ -6308,6 +6338,7 @@ else boot_device = 'd'; } @@ -359,7 +359,7 @@ Index: ioemu/vl.c setvbuf(stdout, NULL, _IOLBF, 0); -@@ -6456,6 +6487,7 @@ +@@ -6441,6 +6472,7 @@ #endif /* !CONFIG_DM */ @@ -367,7 +367,7 @@ Index: ioemu/vl.c /* we always create the cdrom drive, even if no disk is there */ bdrv_init(); if (cdrom_index >= 0) { -@@ -6482,6 +6514,7 @@ +@@ -6467,6 +6499,7 @@ } } } @@ -375,7 +375,7 @@ Index: ioemu/vl.c /* we always create at least one floppy disk */ fd_table[0] = bdrv_new("fda"); -@@ -6560,6 +6593,8 @@ +@@ -6545,6 +6578,8 @@ } } @@ -386,8 +386,8 @@ Index: ioemu/vl.c kernel_filename, kernel_cmdline, initrd_filename, Index: ioemu/monitor.c =================================================================== ---- ioemu.orig/monitor.c 2006-10-24 14:31:36.000000000 +0100 -+++ ioemu/monitor.c 2006-10-24 14:33:28.000000000 +0100 +--- ioemu.orig/monitor.c 2006-12-08 02:02:35.000000000 +0000 ++++ ioemu/monitor.c 2006-12-08 02:02:37.000000000 +0000 @@ -24,6 +24,7 @@ #include "vl.h" #include "disas.h" @@ -416,8 +416,8 @@ Index: ioemu/monitor.c int i; Index: ioemu/block.c =================================================================== ---- ioemu.orig/block.c 2006-10-24 14:31:36.000000000 +0100 -+++ ioemu/block.c 2006-10-24 14:33:28.000000000 +0100 +--- ioemu.orig/block.c 2006-12-08 02:02:06.000000000 +0000 ++++ ioemu/block.c 2006-12-08 02:02:37.000000000 +0000 @@ -758,6 +758,7 @@ static void raw_close(BlockDriverState *bs) { @@ -428,8 +428,8 @@ Index: ioemu/block.c Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:33:24.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:33:28.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000 @@ -1191,6 +1191,8 @@ void term_print_help(void); void monitor_readline(const char *prompt, int is_password, @@ -455,8 +455,8 @@ Index: ioemu/vl.h extern char domain_name[]; Index: ioemu/hw/ide.c =================================================================== ---- ioemu.orig/hw/ide.c 2006-10-24 14:31:36.000000000 +0100 -+++ ioemu/hw/ide.c 2006-10-24 14:33:28.000000000 +0100 +--- ioemu.orig/hw/ide.c 2006-12-08 02:02:35.000000000 +0000 ++++ ioemu/hw/ide.c 2006-12-08 02:02:37.000000000 +0000 @@ -1158,6 +1158,7 @@ } else { ide_atapi_cmd_error(s, SENSE_NOT_READY, diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xenstore-write-vnc-port --- a/tools/ioemu/patches/xenstore-write-vnc-port Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/ioemu/patches/xenstore-write-vnc-port Sat Dec 09 14:34:53 2006 +0000 @@ -1,7 +1,7 @@ Index: ioemu/xenstore.c Index: ioemu/xenstore.c =================================================================== ---- ioemu.orig/xenstore.c 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/xenstore.c 2006-10-24 14:33:47.000000000 +0100 +--- ioemu.orig/xenstore.c 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/xenstore.c 2006-12-08 02:02:37.000000000 +0000 @@ -185,3 +185,31 @@ free(image); free(vec); @@ -36,9 +36,9 @@ Index: ioemu/xenstore.c +} Index: ioemu/vl.c =================================================================== ---- ioemu.orig/vl.c 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/vl.c 2006-10-24 14:33:47.000000000 +0100 -@@ -6550,6 +6550,7 @@ +--- ioemu.orig/vl.c 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 02:02:37.000000000 +0000 +@@ -6535,6 +6535,7 @@ vnc_display = vnc_display_init(ds, vnc_display, vncunused, &vnclisten_addr); if (vncviewer) vnc_start_viewer(vnc_display); @@ -48,8 +48,8 @@ Index: ioemu/vl.c sdl_display_init(ds, full_screen); Index: ioemu/vl.h =================================================================== ---- ioemu.orig/vl.h 2006-10-24 14:33:47.000000000 +0100 -+++ ioemu/vl.h 2006-10-24 14:33:47.000000000 +0100 +--- ioemu.orig/vl.h 2006-12-08 02:02:37.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 02:02:37.000000000 +0000 @@ -1210,6 +1210,7 @@ int xenstore_fd(void); void xenstore_process_event(void *opaque); diff -r 1cfd862e5254 -r 8cddaee4a51c tools/libxc/Makefile --- a/tools/libxc/Makefile Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/libxc/Makefile Sat Dec 09 14:34:53 2006 +0000 @@ -119,7 +119,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$( ln -sf $< $@ libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ -lpthread # libxenguest @@ -132,7 +132,7 @@ libxenguest.so.$(MAJOR): libxenguest.so. ln -sf $< $@ libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl -lpthread -include $(DEPS) diff -r 1cfd862e5254 -r 8cddaee4a51c tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/libxc/xc_private.c Sat Dec 09 14:34:53 2006 +0000 @@ -7,8 +7,8 @@ #include <inttypes.h> #include "xc_private.h" #include "xg_private.h" - #include <stdarg.h> +#include <pthread.h> static __thread xc_error last_error = { XC_ERROR_NONE, ""}; #if DEBUG @@ -486,14 +486,20 @@ char *safe_strerror(int errcode) char *safe_strerror(int errcode) { static __thread char errbuf[32]; -#ifdef __GLIBC__ - /* Broken GNU definition of strerror_r may not use our supplied buffer. */ - return strerror_r(errcode, errbuf, sizeof(errbuf)); -#else - /* Assume we have the POSIX definition of strerror_r. */ - strerror_r(errcode, errbuf, sizeof(errbuf)); + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + char *strerror_str; + + /* + * Thread-unsafe strerror() is protected by a local mutex. We copy + * the string to a thread-private buffer before releasing the mutex. + */ + pthread_mutex_lock(&mutex); + strerror_str = strerror(errcode); + strncpy(errbuf, strerror_str, sizeof(errbuf)); + errbuf[sizeof(errbuf)-1] = '\0'; + pthread_mutex_unlock(&mutex); + return errbuf; -#endif } /* diff -r 1cfd862e5254 -r 8cddaee4a51c tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/python/xen/xend/XendConfig.py Sat Dec 09 14:34:53 2006 +0000 @@ -390,11 +390,16 @@ class XendConfig(dict): if self.get('vcpus_number') != None: self['vcpu_avail'] = (1 << self['vcpus_number']) - 1 + def _uuid_sanity_check(self): + """Make sure UUID is in proper string format with hyphens.""" + self['uuid'] = uuid.toString(uuid.fromString(self['uuid'])) + def validate(self): self._memory_sanity_check() self._actions_sanity_check() self._builder_sanity_check() self._vcpus_sanity_check() + self._uuid_sanity_check() def _dominfo_to_xapi(self, dominfo): self['domid'] = dominfo['domid'] @@ -917,24 +922,11 @@ class XendConfig(dict): except ValueError: pass # SXP has no options for this device - - # Special handling for certain device parameters. - - def _get_config_ipaddr(cfg): - val = [] - for ipaddr in sxp.children(cfg, elt='ip'): - val.append(sxp.child0(ipaddr)) - return val - - if dev_type == 'vif' and 'ip' in dev_info: - dev_info['ip'] = _get_config_ipaddr(config) - if dev_type == 'vbd': if dev_info.get('dev', '').startswith('ioemu:'): dev_info['driver'] = 'ioemu' else: dev_info['driver'] = 'paravirtualised' - # create uuid if it doesn't exist dev_uuid = dev_info.get('uuid', uuid.createString()) diff -r 1cfd862e5254 -r 8cddaee4a51c tools/python/xen/xend/server/netif.py --- a/tools/python/xen/xend/server/netif.py Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/python/xen/xend/server/netif.py Sat Dec 09 14:34:53 2006 +0000 @@ -164,7 +164,7 @@ class NetifController(DevController): front = { 'handle' : "%i" % devid, 'mac' : mac } if ipaddr: - back['ip'] = ' '.join(ipaddr) + back['ip'] = ipaddr if bridge: back['bridge'] = bridge if vifname: @@ -189,7 +189,7 @@ class NetifController(DevController): network_script_dir = xroot.network_script_dir + os.sep result['script'] = script.replace(network_script_dir, "") if ip: - result['ip'] = ip.split(" ") + result['ip'] = ip if bridge: result['bridge'] = bridge if mac: diff -r 1cfd862e5254 -r 8cddaee4a51c tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Fri Dec 08 11:31:29 2006 -0700 +++ b/tools/python/xen/xm/main.py Sat Dec 09 14:34:53 2006 +0000 @@ -138,9 +138,9 @@ SUBCOMMAND_HELP = { # device commands - 'block-attach' : ('<Domain> <BackDev> <FrontDev> <Mode>', + 'block-attach' : ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]', 'Create a new virtual block device.'), - 'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]', + 'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]', 'Change block device configuration'), 'block-detach' : ('<Domain> <DevId>', 'Destroy a domain\'s virtual block device.'), diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/fix-interrupt-routing --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/fix-interrupt-routing Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,459 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID f555a90bcc373a7379bc18f875eac5e7c7122ae9 +# Parent b80f00215bbaf2050765e557f1a017a71e1e8529 +[HVM] Reworked interrupt distribution logic. + +TODO: + 1. Fix IO-APIC ID to not conflict with LAPIC IDS. + 2. Fix i8259 device model (seems to work already though!). + 3. Add INTSRC overrides in MPBIOS and ACPI tables so + that PCI legacy IRQ routing always ends up at an + IO-APIC input with level trigger. Restricting link + routing to {5,6,10,11} and setting overrides for all + four of those would work. + +Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> + +Index: ioemu/Makefile.target +=================================================================== +--- ioemu.orig/Makefile.target 2006-12-08 18:21:56.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 18:22:35.000000000 +0000 +@@ -298,7 +298,7 @@ + ifeq ($(ARCH),ia64) + LIBOBJS=helper2.o exec-dm.o i8259-dm.o + else +-LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o ++LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o + endif + + all: $(PROGS) +@@ -360,11 +360,11 @@ + # Hardware support + VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) + ifeq ($(ARCH),ia64) +-VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o ++VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o piix_pci.o + else + VL_OBJS+= fdc.o serial.o pc.o + endif +-VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o ++VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o + VL_OBJS+= usb-uhci.o + VL_OBJS+= piix4acpi.o + VL_OBJS+= xenstore.o +Index: ioemu/target-i386-dm/i8259-dm.c +=================================================================== +--- ioemu.orig/target-i386-dm/i8259-dm.c 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/target-i386-dm/i8259-dm.c 2006-12-08 18:22:35.000000000 +0000 +@@ -33,7 +33,7 @@ + + void pic_set_irq_new(void *opaque, int irq, int level) + { +- xc_hvm_set_irq_level(xc_handle, domid, irq, level); ++ xc_hvm_set_isa_irq_level(xc_handle, domid, irq, level); + } + + /* obsolete function */ +Index: ioemu/target-i386-dm/piix_pci-dm.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ ioemu/target-i386-dm/piix_pci-dm.c 2006-12-08 18:22:35.000000000 +0000 +@@ -0,0 +1,397 @@ ++/* ++ * QEMU i440FX/PIIX3 PCI Bridge Emulation ++ * ++ * Copyright (c) 2006 Fabrice Bellard ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#include "vl.h" ++typedef uint32_t pci_addr_t; ++#include "hw/pci_host.h" ++ ++typedef PCIHostState I440FXState; ++ ++static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val) ++{ ++ I440FXState *s = opaque; ++ s->config_reg = val; ++} ++ ++static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr) ++{ ++ I440FXState *s = opaque; ++ return s->config_reg; ++} ++ ++static void i440fx_set_irq(PCIDevice *pci_dev, void *pic, int intx, int level) ++{ ++ xc_hvm_set_pci_intx_level(xc_handle, domid, 0, 0, pci_dev->devfn >> 3, ++ intx, level); ++} ++ ++PCIBus *i440fx_init(void) ++{ ++ PCIBus *b; ++ PCIDevice *d; ++ I440FXState *s; ++ ++ s = qemu_mallocz(sizeof(I440FXState)); ++ b = pci_register_bus(i440fx_set_irq, NULL, 0); ++ s->bus = b; ++ ++ register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s); ++ register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s); ++ ++ register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s); ++ register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s); ++ register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s); ++ register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s); ++ register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s); ++ register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s); ++ ++ d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0, ++ NULL, NULL); ++ ++ d->config[0x00] = 0x86; // vendor_id ++ d->config[0x01] = 0x80; ++ d->config[0x02] = 0x37; // device_id ++ d->config[0x03] = 0x12; ++ d->config[0x08] = 0x02; // revision ++ d->config[0x0a] = 0x00; // class_sub = host2pci ++ d->config[0x0b] = 0x06; // class_base = PCI_bridge ++ d->config[0x0e] = 0x00; // header_type ++ return b; ++} ++ ++/* PIIX3 PCI to ISA bridge */ ++ ++static PCIDevice *piix3_dev; ++ ++static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) ++{ ++ /* This is the barber's pole mapping used by Xen. */ ++ return (irq_num + (pci_dev->devfn >> 3)) & 3; ++} ++ ++static void piix3_write_config(PCIDevice *d, ++ uint32_t address, uint32_t val, int len) ++{ ++ int i; ++ ++ /* Scan for updates to PCI link routes (0x60-0x63). */ ++ for (i = 0; i < len; i++) { ++ uint8_t v = (val >> (8*i)) & 0xff; ++ if (v & 0x80) ++ v = 0; ++ v &= 0xf; ++ if (((address+i) >= 0x60) && ((address+i) <= 0x63)) ++ xc_hvm_set_pci_link_route(xc_handle, domid, address + i - 0x60, v); ++ } ++ ++ /* Hand off to default logic. */ ++ pci_default_write_config(d, address, val, len); ++} ++ ++static void piix3_reset(PCIDevice *d) ++{ ++ uint8_t *pci_conf = d->config; ++ ++ pci_conf[0x04] = 0x07; // master, memory and I/O ++ pci_conf[0x05] = 0x00; ++ pci_conf[0x06] = 0x00; ++ pci_conf[0x07] = 0x02; // PCI_status_devsel_medium ++ pci_conf[0x4c] = 0x4d; ++ pci_conf[0x4e] = 0x03; ++ pci_conf[0x4f] = 0x00; ++ pci_conf[0x60] = 0x80; ++ pci_conf[0x61] = 0x80; ++ pci_conf[0x62] = 0x80; ++ pci_conf[0x63] = 0x80; ++ pci_conf[0x69] = 0x02; ++ pci_conf[0x70] = 0x80; ++ pci_conf[0x76] = 0x0c; ++ pci_conf[0x77] = 0x0c; ++ pci_conf[0x78] = 0x02; ++ pci_conf[0x79] = 0x00; ++ pci_conf[0x80] = 0x00; ++ pci_conf[0x82] = 0x00; ++ pci_conf[0xa0] = 0x08; ++ pci_conf[0xa0] = 0x08; ++ pci_conf[0xa2] = 0x00; ++ pci_conf[0xa3] = 0x00; ++ pci_conf[0xa4] = 0x00; ++ pci_conf[0xa5] = 0x00; ++ pci_conf[0xa6] = 0x00; ++ pci_conf[0xa7] = 0x00; ++ pci_conf[0xa8] = 0x0f; ++ pci_conf[0xaa] = 0x00; ++ pci_conf[0xab] = 0x00; ++ pci_conf[0xac] = 0x00; ++ pci_conf[0xae] = 0x00; ++} ++ ++int piix3_init(PCIBus *bus) ++{ ++ PCIDevice *d; ++ uint8_t *pci_conf; ++ ++ d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice), ++ -1, NULL, piix3_write_config); ++ register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d); ++ ++ piix3_dev = d; ++ pci_conf = d->config; ++ ++ pci_conf[0x00] = 0x86; // Intel ++ pci_conf[0x01] = 0x80; ++ pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1) ++ pci_conf[0x03] = 0x70; ++ pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA ++ pci_conf[0x0b] = 0x06; // class_base = PCI_bridge ++ pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic ++ ++ piix3_reset(d); ++ return d->devfn; ++} ++ ++/***********************************************************/ ++/* XXX: the following should be moved to the PC BIOS */ ++ ++static __attribute__((unused)) uint32_t isa_inb(uint32_t addr) ++{ ++ return cpu_inb(NULL, addr); ++} ++ ++static void isa_outb(uint32_t val, uint32_t addr) ++{ ++ cpu_outb(NULL, addr, val); ++} ++ ++static __attribute__((unused)) uint32_t isa_inw(uint32_t addr) ++{ ++ return cpu_inw(NULL, addr); ++} ++ ++static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr) ++{ ++ cpu_outw(NULL, addr, val); ++} ++ ++static __attribute__((unused)) uint32_t isa_inl(uint32_t addr) ++{ ++ return cpu_inl(NULL, addr); ++} ++ ++static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr) ++{ ++ cpu_outl(NULL, addr, val); ++} ++ ++static uint32_t pci_bios_io_addr; ++static uint32_t pci_bios_mem_addr; ++/* host irqs corresponding to PCI irqs A-D */ ++static uint8_t pci_irqs[4] = { 10, 11, 10, 11 }; ++ ++static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) ++{ ++ PCIBus *s = d->bus; ++ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); ++ pci_data_write(s, addr, val, 4); ++} ++ ++static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val) ++{ ++ PCIBus *s = d->bus; ++ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); ++ pci_data_write(s, addr, val, 2); ++} ++ ++static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val) ++{ ++ PCIBus *s = d->bus; ++ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); ++ pci_data_write(s, addr, val, 1); ++} ++ ++static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr) ++{ ++ PCIBus *s = d->bus; ++ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); ++ return pci_data_read(s, addr, 4); ++} ++ ++static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr) ++{ ++ PCIBus *s = d->bus; ++ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); ++ return pci_data_read(s, addr, 2); ++} ++ ++static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr) ++{ ++ PCIBus *s = d->bus; ++ addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); ++ return pci_data_read(s, addr, 1); ++} ++ ++static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr) ++{ ++ PCIIORegion *r; ++ uint16_t cmd; ++ uint32_t ofs; ++ ++ if ( region_num == PCI_ROM_SLOT ) { ++ ofs = 0x30; ++ }else{ ++ ofs = 0x10 + region_num * 4; ++ } ++ ++ pci_config_writel(d, ofs, addr); ++ r = &d->io_regions[region_num]; ++ ++ /* enable memory mappings */ ++ cmd = pci_config_readw(d, PCI_COMMAND); ++ if ( region_num == PCI_ROM_SLOT ) ++ cmd |= 2; ++ else if (r->type & PCI_ADDRESS_SPACE_IO) ++ cmd |= 1; ++ else ++ cmd |= 2; ++ pci_config_writew(d, PCI_COMMAND, cmd); ++} ++ ++static void pci_bios_init_device(PCIDevice *d) ++{ ++ int class; ++ PCIIORegion *r; ++ uint32_t *paddr; ++ int i, pin, pic_irq, vendor_id, device_id; ++ ++ class = pci_config_readw(d, PCI_CLASS_DEVICE); ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID); ++ device_id = pci_config_readw(d, PCI_DEVICE_ID); ++ switch(class) { ++ case 0x0101: ++ if (vendor_id == 0x8086 && device_id == 0x7010) { ++ /* PIIX3 IDE */ ++ pci_config_writew(d, 0x40, 0x8000); // enable IDE0 ++ pci_config_writew(d, 0x42, 0x8000); // enable IDE1 ++ goto default_map; ++ } else { ++ /* IDE: we map it as in ISA mode */ ++ pci_set_io_region_addr(d, 0, 0x1f0); ++ pci_set_io_region_addr(d, 1, 0x3f4); ++ pci_set_io_region_addr(d, 2, 0x170); ++ pci_set_io_region_addr(d, 3, 0x374); ++ } ++ break; ++ case 0x0680: ++ if (vendor_id == 0x8086 && device_id == 0x7113) { ++ /* ++ * PIIX4 ACPI PM. ++ * Special device with special PCI config space. No ordinary BARs. ++ */ ++ pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable ++ pci_config_writew(d, 0x22, 0x0000); ++ pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9 ++ pci_config_writew(d, 0x3d, 0x0001); ++ } ++ break; ++ case 0x0300: ++ if (vendor_id != 0x1234) ++ goto default_map; ++ /* VGA: map frame buffer to default Bochs VBE address */ ++ pci_set_io_region_addr(d, 0, 0xE0000000); ++ break; ++ case 0x0800: ++ /* PIC */ ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID); ++ device_id = pci_config_readw(d, PCI_DEVICE_ID); ++ if (vendor_id == 0x1014) { ++ /* IBM */ ++ if (device_id == 0x0046 || device_id == 0xFFFF) { ++ /* MPIC & MPIC2 */ ++ pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000); ++ } ++ } ++ break; ++ case 0xff00: ++ if (vendor_id == 0x0106b && ++ (device_id == 0x0017 || device_id == 0x0022)) { ++ /* macio bridge */ ++ pci_set_io_region_addr(d, 0, 0x80800000); ++ } ++ break; ++ default: ++ default_map: ++ /* default memory mappings */ ++ for(i = 0; i < PCI_NUM_REGIONS; i++) { ++ r = &d->io_regions[i]; ++ if (r->size) { ++ if (r->type & PCI_ADDRESS_SPACE_IO) ++ paddr = &pci_bios_io_addr; ++ else ++ paddr = &pci_bios_mem_addr; ++ *paddr = (*paddr + r->size - 1) & ~(r->size - 1); ++ pci_set_io_region_addr(d, i, *paddr); ++ *paddr += r->size; ++ } ++ } ++ break; ++ } ++ ++ /* map the interrupt */ ++ pin = pci_config_readb(d, PCI_INTERRUPT_PIN); ++ if (pin != 0) { ++ pin = pci_slot_get_pirq(d, pin - 1); ++ pic_irq = pci_irqs[pin]; ++ pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq); ++ } ++} ++ ++/* ++ * This function initializes the PCI devices as a normal PCI BIOS ++ * would do. It is provided just in case the BIOS has no support for ++ * PCI. ++ */ ++void pci_bios_init(void) ++{ ++ int i, irq; ++ uint8_t elcr[2]; ++ ++ pci_bios_io_addr = 0xc000; ++ pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START; ++ ++ /* activate IRQ mappings */ ++ elcr[0] = 0x00; ++ elcr[1] = 0x00; ++ for(i = 0; i < 4; i++) { ++ irq = pci_irqs[i]; ++ /* set to trigger level */ ++ elcr[irq >> 3] |= (1 << (irq & 7)); ++ /* activate irq remapping in PIIX */ ++ pci_config_writeb(piix3_dev, 0x60 + i, irq); ++ } ++ isa_outb(elcr[0], 0x4d0); ++ isa_outb(elcr[1], 0x4d1); ++ ++ pci_for_each_device(pci_bios_init_device); ++} ++ diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/ide-error-reporting --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/ide-error-reporting Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,110 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID fd28a1b139dea91b8bfcf06dd233dbdda8f51ff1 +# Parent d8befb109c394c2c2d3e1870a500107d461724ef +[QEMU] Error reporting in IDE device model. + +Following on from my patch to make blktap report I/O errors back to +guest OS, a similar problem exists in the QEMU codebase. The IDE +driver never reports I/O errors during read/write operations back to +the guest OS. Instead all I/O operations are reported as +succesfull. If, for example, the host FS holding the disk image fills +up, then writes may fail due to lack of space. Since the guest OS +never sees these failures, it assumes all is well & will continue +writing. Eventually this can lead to severe & unrecoverable filesystem +corruption. + +The attached patch fixes QEMU ide driver such that any failure of a +read or write operation sets the appropriate IDE status/error +registers. Having read the ATA-6 spec I think the most compliant +behaviour is to set the status register to 'READY_STAT | ERR_STAT', +and the error register to ABRT_ERR. There is already a convenience +function ide_abort_command() in the QEMU codebase which does just +this, so the attached patch simply calls that function. + +With this patch the guest OS sees the I/O failure & the kernel logs +IDE errors and then retries the operation. This at least ensures that +the guest can be shutdown the out of space issue in the host corrected +and the guest restarted, without any serious filesystem damage having +occurred. + +From: Daniel Berrange <berrange@xxxxxxxxxx> +Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> + +Index: ioemu/hw/ide.c +=================================================================== +--- ioemu.orig/hw/ide.c 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/hw/ide.c 2006-12-08 18:23:18.000000000 +0000 +@@ -680,7 +680,7 @@ + static void ide_sector_read(IDEState *s) + { + int64_t sector_num; +- int ret, n; ++ int n; + + s->status = READY_STAT | SEEK_STAT; + s->error = 0; /* not needed by IDE spec, but needed by Windows */ +@@ -695,7 +695,11 @@ + #endif + if (n > s->req_nb_sectors) + n = s->req_nb_sectors; +- ret = bdrv_read(s->bs, sector_num, s->io_buffer, n); ++ if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) { ++ ide_abort_command(s); ++ ide_set_irq(s); ++ return; ++ } + ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read); + ide_set_irq(s); + ide_set_sector(s, sector_num + n); +@@ -721,7 +725,11 @@ + if (n > MAX_MULT_SECTORS) + n = MAX_MULT_SECTORS; + sector_num = ide_get_sector(s); +- bdrv_read(s->bs, sector_num, s->io_buffer, n); ++ if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) { ++ ide_abort_command(s); ++ ide_set_irq(s); ++ return 0; ++ } + s->io_buffer_index = 0; + s->io_buffer_size = n * 512; + len = s->io_buffer_size; +@@ -767,7 +775,7 @@ + static void ide_sector_write(IDEState *s) + { + int64_t sector_num; +- int ret, n, n1; ++ int n, n1; + + s->status = READY_STAT | SEEK_STAT; + sector_num = ide_get_sector(s); +@@ -777,7 +785,11 @@ + n = s->nsector; + if (n > s->req_nb_sectors) + n = s->req_nb_sectors; +- ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); ++ if (bdrv_write(s->bs, sector_num, s->io_buffer, n) != 0) { ++ ide_abort_command(s); ++ ide_set_irq(s); ++ return; ++ } + s->nsector -= n; + if (s->nsector == 0) { + /* no more sector to write */ +@@ -823,8 +835,13 @@ + if (len == 0) { + n = s->io_buffer_size >> 9; + sector_num = ide_get_sector(s); +- bdrv_write(s->bs, sector_num, s->io_buffer, +- s->io_buffer_size >> 9); ++ if (bdrv_write(s->bs, sector_num, s->io_buffer, ++ s->io_buffer_size >> 9) != 0) { ++ ide_abort_command(s); ++ ide_set_irq(s); ++ return 0; ++ } ++ + sector_num += n; + ide_set_sector(s, sector_num); + s->nsector -= n; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/limit-fdc-sector-size-to-16K --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/limit-fdc-sector-size-to-16K Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,32 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID f711b87ba951e608287abd0de028c6f0d83400a9 +# Parent f3ee62b7fb5299c89d442845e0883bcfab78c067 +[QEMU] fdc: Limit sector size to 16K + +In fdctrl_start_transfer the sector size field (fifo[5]) is not +checked for overflows. This allows an arbitrarily large sector size +to be used, which can in turn result in a negative data_len field that +is then used for DMA transfers. + +This can lead to the corrpuption of qemu state because some subsequent +checks on the transfer length is conducted using signed integers. + +This patch limits the value fifo[5] to 7 which is the standard limit +on floppy sector size. + +Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> + +Index: ioemu/hw/fdc.c +=================================================================== +--- ioemu.orig/hw/fdc.c 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/hw/fdc.c 2006-12-08 18:22:57.000000000 +0000 +@@ -898,7 +898,7 @@ + fdctrl->data_len = fdctrl->fifo[8]; + } else { + int tmp; +- fdctrl->data_len = 128 << fdctrl->fifo[5]; ++ fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]); + tmp = (cur_drv->last_sect - ks + 1); + if (fdctrl->fifo[0] & 0x80) + tmp += cur_drv->last_sect; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/ne2000-bounds-checks --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/ne2000-bounds-checks Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,113 @@ +# HG changeset patch +# User kaf24@xxxxxxxxxxxxxxxxxxxxx +# Node ID 66fe61db9e69e03e12d0c4086683bebfb4a67780 +# Parent 1940ee13f9d6ab1be2c614a0fbf7769536a056d2 +[QEMU] ne2000: Stop memory access beyond buffer + +As a program that runs in dom0 which serves users from guests, +the qemu drivers need to be vigilant to the input that comes +from the guests since they may be malicious. + +As it is there are multiple ways to get ne2000 to read/write +memory beyond the 48K buffer that it has allocated for each +adapter. + +This patch checks the addresses and prevents this from occuring. + +The boundary is checked each time since it's changed for every +packet received while the other parameters are only changed +(by the guest) during setup. + +Signed-off: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> + +Index: ioemu/hw/ne2000.c +=================================================================== +--- ioemu.orig/hw/ne2000.c 2006-12-08 18:20:45.000000000 +0000 ++++ ioemu/hw/ne2000.c 2006-12-08 18:20:53.000000000 +0000 +@@ -137,6 +137,7 @@ + uint8_t curpag; + uint8_t mult[8]; /* multicast mask array */ + int irq; ++ int tainted; + PCIDevice *pci_dev; + VLANClientState *vc; + uint8_t macaddr[6]; +@@ -226,6 +227,27 @@ + + #define MIN_BUF_SIZE 60 + ++static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr) ++{ ++ addr <<= 8; ++ return addr < s->stop && addr >= s->start; ++} ++ ++static inline int ne2000_check_state(NE2000State *s) ++{ ++ if (!s->tainted) ++ return 0; ++ ++ if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE) ++ return -EINVAL; ++ ++ if (!ne2000_valid_ring_addr(s, s->curpag)) ++ return -EINVAL; ++ ++ s->tainted = 0; ++ return 0; ++} ++ + static void ne2000_receive(void *opaque, const uint8_t *buf, int size) + { + NE2000State *s = opaque; +@@ -239,6 +261,12 @@ + printf("NE2000: received len=%d\n", size); + #endif + ++ if (ne2000_check_state(s)) ++ return; ++ ++ if (!ne2000_valid_ring_addr(s, s->boundary)) ++ return; ++ + if (s->cmd & E8390_STOP || ne2000_buffer_full(s)) + return; + +@@ -359,9 +387,11 @@ + switch(offset) { + case EN0_STARTPG: + s->start = val << 8; ++ s->tainted = 1; + break; + case EN0_STOPPG: + s->stop = val << 8; ++ s->tainted = 1; + break; + case EN0_BOUNDARY: + s->boundary = val; +@@ -406,6 +436,7 @@ + break; + case EN1_CURPAG: + s->curpag = val; ++ s->tainted = 1; + break; + case EN1_MULT ... EN1_MULT + 7: + s->mult[offset - EN1_MULT] = val; +@@ -509,7 +540,7 @@ + { + addr &= ~1; /* XXX: check exact behaviour if not even */ + if (addr < 32 || +- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { ++ (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) { + cpu_to_le32wu((uint32_t *)(s->mem + addr), val); + } + } +@@ -539,7 +570,7 @@ + { + addr &= ~1; /* XXX: check exact behaviour if not even */ + if (addr < 32 || +- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { ++ (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) { + return le32_to_cpupu((uint32_t *)(s->mem + addr)); + } else { + return 0xffffffff; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/nodelay-serial-over-tcp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/nodelay-serial-over-tcp Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,29 @@ +# HG changeset patch +# User PeterJohnston <peter.johnston@xxxxxxxxxxxxx> +# Node ID b8cc9ffda0a3dc449b026c72c97f78dea2e6f114 +# Parent a8d2b1393b769048c7b62822e45bef27eef80fb6 +[QEMU] Add TCP_NODELAY to tcp connections exporting serial ports. + +Signed-off-by: Steven Smith <sos22@xxxxxxxxx> + +Index: ioemu/vl.c +=================================================================== +--- ioemu.orig/vl.c 2006-12-08 18:21:56.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 18:22:42.000000000 +0000 +@@ -2530,6 +2530,7 @@ + int is_waitconnect = 1; + const char *ptr; + struct sockaddr_in saddr; ++ int opt; + + if (parse_host_port(&saddr, host_str) < 0) + goto fail; +@@ -2598,6 +2599,8 @@ + } + } + s->fd = fd; ++ opt = 1; ++ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)); + if (s->connected) + tcp_chr_connect(chr); + else diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/qemu-serial-fixes --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/qemu-serial-fixes Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,133 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID c33272c2571c7bab7056d8228490700d1df405f9 +# Parent b3d94f4ddffefed8a5cb8dd65a60da9491d460e7 +[HVM] Fix Qemu-dm serial issues: + 1. Retry transmit via a polling timer if a byte cannot be written + immediately to its destination. + 2. Turn off output processing of raw serial lines. + +Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx> +Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx> +Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> + +Index: ioemu/vl.c +=================================================================== +--- ioemu.orig/vl.c 2006-12-08 01:28:59.000000000 +0000 ++++ ioemu/vl.c 2006-12-08 01:28:59.000000000 +0000 +@@ -1684,7 +1684,7 @@ + + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); +- tty.c_oflag |= OPOST; ++ tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */ + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG); + tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS); + switch(data_bits) { +Index: ioemu/hw/serial.c +=================================================================== +--- ioemu.orig/hw/serial.c 2006-12-08 01:28:17.000000000 +0000 ++++ ioemu/hw/serial.c 2006-12-08 01:29:10.000000000 +0000 +@@ -73,6 +73,11 @@ + #define UART_LSR_OE 0x02 /* Overrun error indicator */ + #define UART_LSR_DR 0x01 /* Receiver data ready */ + ++/* Maximum retries for a single byte transmit. */ ++#define WRITE_MAX_SINGLE_RETRIES 3 ++/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */ ++#define WRITE_MAX_TOTAL_RETRIES 10 ++ + struct SerialState { + uint8_t divider; + uint8_t rbr; /* receive register */ +@@ -93,6 +98,19 @@ + int last_break_enable; + target_ulong base; + int it_shift; ++ ++ /* ++ * If a character transmitted via UART cannot be written to its ++ * destination immediately we remember it here and retry a few times via ++ * a polling timer. ++ * - write_single_retries: Number of write retries for current byte. ++ * - write_total_retries: Number of write retries for back-to-back ++ * unsuccessful transmits. ++ */ ++ int write_single_retries; ++ int write_total_retries; ++ char write_chr; ++ QEMUTimer *write_retry_timer; + }; + + static void serial_update_irq(SerialState *s) +@@ -204,10 +222,37 @@ + tokens_avail--; + } + ++static void serial_chr_write(void *opaque) ++{ ++ SerialState *s = opaque; ++ ++ /* Cancel any outstanding retry if this is a new byte. */ ++ qemu_del_timer(s->write_retry_timer); ++ ++ /* Retry every 100ms for 300ms total. */ ++ if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) { ++ s->write_total_retries++; ++ if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES) ++ fprintf(stderr, "serial: write error\n"); ++ else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) { ++ qemu_mod_timer(s->write_retry_timer, ++ qemu_get_clock(vm_clock) + ticks_per_sec / 10); ++ return; ++ } ++ } else { ++ s->write_total_retries = 0; /* if successful then reset counter */ ++ } ++ ++ /* Success: Notify guest that THR is empty. */ ++ s->thr_ipending = 1; ++ s->lsr |= UART_LSR_THRE; ++ s->lsr |= UART_LSR_TEMT; ++ serial_update_irq(s); ++} ++ + static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) + { + SerialState *s = opaque; +- unsigned char ch; + + addr &= 7; + #ifdef DEBUG_SERIAL +@@ -223,12 +268,9 @@ + s->thr_ipending = 0; + s->lsr &= ~UART_LSR_THRE; + serial_update_irq(s); +- ch = val; +- qemu_chr_write(s->chr, &ch, 1); +- s->thr_ipending = 1; +- s->lsr |= UART_LSR_THRE; +- s->lsr |= UART_LSR_TEMT; +- serial_update_irq(s); ++ s->write_chr = val; ++ s->write_single_retries = 0; ++ serial_chr_write(s); + } + break; + case 1: +@@ -424,6 +466,7 @@ + s->lsr = UART_LSR_TEMT | UART_LSR_THRE; + s->iir = UART_IIR_NO_INT; + s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; ++ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s); + + register_savevm("serial", base, 1, serial_save, serial_load, s); + +@@ -511,6 +554,7 @@ + s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; + s->base = base; + s->it_shift = it_shift; ++ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s); + + register_savevm("serial", base, 1, serial_save, serial_load, s); + diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/remove-pci-bridge-setup --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/remove-pci-bridge-setup Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,289 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID a8d31d5ce2589762c3226185deeca3afca47a698 +# Parent b8cc9ffda0a3dc449b026c72c97f78dea2e6f114 +[HVM] Move PCI and PCI-ISA bridge setup to hvmloader. +Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> + +Index: ioemu/target-i386-dm/piix_pci-dm.c +=================================================================== +--- ioemu.orig/target-i386-dm/piix_pci-dm.c 2006-12-08 18:22:35.000000000 +0000 ++++ ioemu/target-i386-dm/piix_pci-dm.c 2006-12-08 18:22:50.000000000 +0000 +@@ -84,12 +84,6 @@ + + static PCIDevice *piix3_dev; + +-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) +-{ +- /* This is the barber's pole mapping used by Xen. */ +- return (irq_num + (pci_dev->devfn >> 3)) & 3; +-} +- + static void piix3_write_config(PCIDevice *d, + uint32_t address, uint32_t val, int len) + { +@@ -114,12 +108,9 @@ + uint8_t *pci_conf = d->config; + + pci_conf[0x04] = 0x07; // master, memory and I/O +- pci_conf[0x05] = 0x00; +- pci_conf[0x06] = 0x00; + pci_conf[0x07] = 0x02; // PCI_status_devsel_medium + pci_conf[0x4c] = 0x4d; + pci_conf[0x4e] = 0x03; +- pci_conf[0x4f] = 0x00; + pci_conf[0x60] = 0x80; + pci_conf[0x61] = 0x80; + pci_conf[0x62] = 0x80; +@@ -129,22 +120,9 @@ + pci_conf[0x76] = 0x0c; + pci_conf[0x77] = 0x0c; + pci_conf[0x78] = 0x02; +- pci_conf[0x79] = 0x00; +- pci_conf[0x80] = 0x00; +- pci_conf[0x82] = 0x00; + pci_conf[0xa0] = 0x08; + pci_conf[0xa0] = 0x08; +- pci_conf[0xa2] = 0x00; +- pci_conf[0xa3] = 0x00; +- pci_conf[0xa4] = 0x00; +- pci_conf[0xa5] = 0x00; +- pci_conf[0xa6] = 0x00; +- pci_conf[0xa7] = 0x00; + pci_conf[0xa8] = 0x0f; +- pci_conf[0xaa] = 0x00; +- pci_conf[0xab] = 0x00; +- pci_conf[0xac] = 0x00; +- pci_conf[0xae] = 0x00; + } + + int piix3_init(PCIBus *bus) +@@ -171,227 +149,4 @@ + return d->devfn; + } + +-/***********************************************************/ +-/* XXX: the following should be moved to the PC BIOS */ +- +-static __attribute__((unused)) uint32_t isa_inb(uint32_t addr) +-{ +- return cpu_inb(NULL, addr); +-} +- +-static void isa_outb(uint32_t val, uint32_t addr) +-{ +- cpu_outb(NULL, addr, val); +-} +- +-static __attribute__((unused)) uint32_t isa_inw(uint32_t addr) +-{ +- return cpu_inw(NULL, addr); +-} +- +-static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr) +-{ +- cpu_outw(NULL, addr, val); +-} +- +-static __attribute__((unused)) uint32_t isa_inl(uint32_t addr) +-{ +- return cpu_inl(NULL, addr); +-} +- +-static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr) +-{ +- cpu_outl(NULL, addr, val); +-} +- +-static uint32_t pci_bios_io_addr; +-static uint32_t pci_bios_mem_addr; +-/* host irqs corresponding to PCI irqs A-D */ +-static uint8_t pci_irqs[4] = { 10, 11, 10, 11 }; +- +-static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) +-{ +- PCIBus *s = d->bus; +- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); +- pci_data_write(s, addr, val, 4); +-} +- +-static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val) +-{ +- PCIBus *s = d->bus; +- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); +- pci_data_write(s, addr, val, 2); +-} +- +-static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val) +-{ +- PCIBus *s = d->bus; +- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); +- pci_data_write(s, addr, val, 1); +-} +- +-static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr) +-{ +- PCIBus *s = d->bus; +- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); +- return pci_data_read(s, addr, 4); +-} +- +-static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr) +-{ +- PCIBus *s = d->bus; +- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); +- return pci_data_read(s, addr, 2); +-} +- +-static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr) +-{ +- PCIBus *s = d->bus; +- addr |= (pci_bus_num(s) << 16) | (d->devfn << 8); +- return pci_data_read(s, addr, 1); +-} +- +-static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr) +-{ +- PCIIORegion *r; +- uint16_t cmd; +- uint32_t ofs; +- +- if ( region_num == PCI_ROM_SLOT ) { +- ofs = 0x30; +- }else{ +- ofs = 0x10 + region_num * 4; +- } +- +- pci_config_writel(d, ofs, addr); +- r = &d->io_regions[region_num]; +- +- /* enable memory mappings */ +- cmd = pci_config_readw(d, PCI_COMMAND); +- if ( region_num == PCI_ROM_SLOT ) +- cmd |= 2; +- else if (r->type & PCI_ADDRESS_SPACE_IO) +- cmd |= 1; +- else +- cmd |= 2; +- pci_config_writew(d, PCI_COMMAND, cmd); +-} +- +-static void pci_bios_init_device(PCIDevice *d) +-{ +- int class; +- PCIIORegion *r; +- uint32_t *paddr; +- int i, pin, pic_irq, vendor_id, device_id; +- +- class = pci_config_readw(d, PCI_CLASS_DEVICE); +- vendor_id = pci_config_readw(d, PCI_VENDOR_ID); +- device_id = pci_config_readw(d, PCI_DEVICE_ID); +- switch(class) { +- case 0x0101: +- if (vendor_id == 0x8086 && device_id == 0x7010) { +- /* PIIX3 IDE */ +- pci_config_writew(d, 0x40, 0x8000); // enable IDE0 +- pci_config_writew(d, 0x42, 0x8000); // enable IDE1 +- goto default_map; +- } else { +- /* IDE: we map it as in ISA mode */ +- pci_set_io_region_addr(d, 0, 0x1f0); +- pci_set_io_region_addr(d, 1, 0x3f4); +- pci_set_io_region_addr(d, 2, 0x170); +- pci_set_io_region_addr(d, 3, 0x374); +- } +- break; +- case 0x0680: +- if (vendor_id == 0x8086 && device_id == 0x7113) { +- /* +- * PIIX4 ACPI PM. +- * Special device with special PCI config space. No ordinary BARs. +- */ +- pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable +- pci_config_writew(d, 0x22, 0x0000); +- pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9 +- pci_config_writew(d, 0x3d, 0x0001); +- } +- break; +- case 0x0300: +- if (vendor_id != 0x1234) +- goto default_map; +- /* VGA: map frame buffer to default Bochs VBE address */ +- pci_set_io_region_addr(d, 0, 0xE0000000); +- break; +- case 0x0800: +- /* PIC */ +- vendor_id = pci_config_readw(d, PCI_VENDOR_ID); +- device_id = pci_config_readw(d, PCI_DEVICE_ID); +- if (vendor_id == 0x1014) { +- /* IBM */ +- if (device_id == 0x0046 || device_id == 0xFFFF) { +- /* MPIC & MPIC2 */ +- pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000); +- } +- } +- break; +- case 0xff00: +- if (vendor_id == 0x0106b && +- (device_id == 0x0017 || device_id == 0x0022)) { +- /* macio bridge */ +- pci_set_io_region_addr(d, 0, 0x80800000); +- } +- break; +- default: +- default_map: +- /* default memory mappings */ +- for(i = 0; i < PCI_NUM_REGIONS; i++) { +- r = &d->io_regions[i]; +- if (r->size) { +- if (r->type & PCI_ADDRESS_SPACE_IO) +- paddr = &pci_bios_io_addr; +- else +- paddr = &pci_bios_mem_addr; +- *paddr = (*paddr + r->size - 1) & ~(r->size - 1); +- pci_set_io_region_addr(d, i, *paddr); +- *paddr += r->size; +- } +- } +- break; +- } +- +- /* map the interrupt */ +- pin = pci_config_readb(d, PCI_INTERRUPT_PIN); +- if (pin != 0) { +- pin = pci_slot_get_pirq(d, pin - 1); +- pic_irq = pci_irqs[pin]; +- pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq); +- } +-} +- +-/* +- * This function initializes the PCI devices as a normal PCI BIOS +- * would do. It is provided just in case the BIOS has no support for +- * PCI. +- */ +-void pci_bios_init(void) +-{ +- int i, irq; +- uint8_t elcr[2]; +- +- pci_bios_io_addr = 0xc000; +- pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START; +- +- /* activate IRQ mappings */ +- elcr[0] = 0x00; +- elcr[1] = 0x00; +- for(i = 0; i < 4; i++) { +- irq = pci_irqs[i]; +- /* set to trigger level */ +- elcr[irq >> 3] |= (1 << (irq & 7)); +- /* activate irq remapping in PIIX */ +- pci_config_writeb(piix3_dev, 0x60 + i, irq); +- } +- isa_outb(elcr[0], 0x4d0); +- isa_outb(elcr[1], 0x4d1); +- +- pci_for_each_device(pci_bios_init_device); +-} +- ++void pci_bios_init(void) {} diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/rtl8139-bound-chaining --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/rtl8139-bound-chaining Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,36 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID 075f4ffdbbce5527ba525a515abe320703d17a0e +# Parent 51edd3c6a4d861db6ce1c9a02251ed49213c3002 +[QEMU] rtl8139: Disallow chaining above 64K + +As it stands the 8139C+ TX chaining is only bounded by realloc failure. +This is contrary to how the real hardware operates. It also has DoS +potential when ioemu runs in dom0. + +This patch makes any attempt to chain a frame beyond 64K fail +immediately. + +Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> + +Index: ioemu/hw/rtl8139.c +=================================================================== +--- ioemu.orig/hw/rtl8139.c 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/hw/rtl8139.c 2006-12-08 18:22:22.000000000 +0000 +@@ -1999,12 +1999,12 @@ + DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len)); + } + +- while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len) ++ if (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len) + { +- s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE; +- s->cplus_txbuffer = realloc(s->cplus_txbuffer, s->cplus_txbuffer_len); ++ free(s->cplus_txbuffer); ++ s->cplus_txbuffer = NULL; + +- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len)); ++ DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space exceeded: %d\n", s->cplus_txbuffer_offset + txsize)); + } + + if (!s->cplus_txbuffer) diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/tpm-tis-device --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/tpm-tis-device Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,1188 @@ +# HG changeset patch +# User kaf24@xxxxxxxxxxxxxxxxxxxxx +# Node ID d60b709724f48397b95da3d56299213cae391789 +# Parent bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2 +[QEMU] Add a TIS device model compliant to the 1.2 TPM specification. +It implements all registers necessary to make the Linux TIS driver +work (tpm_tis.c). All of the basic registers supported by this type of +device are implemented. Also the locality selection has been +implemented, but has not been tested. The legacy registers as +described in the specification are not supported. + +Current caveat: The device has so far not yet been integrated with the +virtual TPM available in the repository. It will require changes to +the virtual TPM spawned by the vTPM manager to offer an additional message +interface. The TIS interface itself then needs to have an additional +transport implemented. (see vTPMTransmit array). + +The relevant specification for the device model can be found here: +https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf + +Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx> + +Index: ioemu/Makefile.target +=================================================================== +--- ioemu.orig/Makefile.target 2006-12-08 18:33:48.000000000 +0000 ++++ ioemu/Makefile.target 2006-12-08 18:35:14.000000000 +0000 +@@ -369,6 +369,7 @@ + VL_OBJS+= piix4acpi.o + VL_OBJS+= xenstore.o + VL_OBJS+= xen_platform.o ++VL_OBJS+= tpm_tis.o + DEFINES += -DHAS_AUDIO + endif + ifeq ($(TARGET_BASE_ARCH), ppc) +Index: ioemu/hw/pc.c +=================================================================== +--- ioemu.orig/hw/pc.c 2006-12-08 18:33:47.000000000 +0000 ++++ ioemu/hw/pc.c 2006-12-08 18:33:48.000000000 +0000 +@@ -875,6 +875,9 @@ + } + } + ++ if (has_tpm_device()) ++ tpm_tis_init(&pic_set_irq_new, isa_pic, 11); ++ + kbd_init(); + DMA_init(0); + #ifdef HAS_AUDIO +Index: ioemu/hw/tpm_tis.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ ioemu/hw/tpm_tis.c 2006-12-08 18:35:25.000000000 +0000 +@@ -0,0 +1,1120 @@ ++/* ++ * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface ++ * ++ * Copyright (C) 2006 IBM Corporation ++ * ++ * Author: Stefan Berger <stefanb@xxxxxxxxxx> ++ * David Safford <safford@xxxxxxxxxx> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation, version 2 of the ++ * License. ++ * ++ * ++ * Implementation of the TIS interface according to specs at ++ * https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf ++ * ++ */ ++ ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <sys/socket.h> ++#include <sys/un.h> ++#include <fcntl.h> ++#include <errno.h> ++#include "vl.h" ++ ++//#define DEBUG_TPM ++ ++#define TPM_MAX_PKT 4096 ++ ++#define VTPM_BAD_INSTANCE (uint32_t)0xffffffff ++ ++#define TIS_ADDR_BASE 0xFED40000 ++ ++/* tis registers */ ++#define TPM_REG_ACCESS 0x00 ++#define TPM_REG_INT_ENABLE 0x08 ++#define TPM_REG_INT_VECTOR 0x0c ++#define TPM_REG_INT_STATUS 0x10 ++#define TPM_REG_INTF_CAPABILITY 0x14 ++#define TPM_REG_STS 0x18 ++#define TPM_REG_DATA_FIFO 0x24 ++#define TPM_REG_DID_VID 0xf00 ++#define TPM_REG_RID 0xf04 ++ ++#define STS_VALID (1 << 7) ++#define STS_COMMAND_READY (1 << 6) ++#define STS_TPM_GO (1 << 5) ++#define STS_DATA_AVAILABLE (1 << 4) ++#define STS_EXPECT (1 << 3) ++#define STS_RESPONSE_RETRY (1 << 1) ++ ++#define ACCESS_TPM_REG_VALID_STS (1 << 7) ++#define ACCESS_ACTIVE_LOCALITY (1 << 5) ++#define ACCESS_BEEN_SEIZED (1 << 4) ++#define ACCESS_SEIZE (1 << 3) ++#define ACCESS_PENDING_REQUEST (1 << 2) ++#define ACCESS_REQUEST_USE (1 << 1) ++#define ACCESS_TPM_ESTABLISHMENT (1 << 0) ++ ++#define INT_ENABLED (1 << 31) ++#define INT_DATA_AVAILABLE (1 << 0) ++#define INT_LOCALITY_CHANGED (1 << 2) ++#define INT_COMMAND_READY (1 << 7) ++ ++#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \ ++ INT_DATA_AVAILABLE | \ ++ INT_COMMAND_READY) ++#define CAPABILITIES_SUPPORTED ((1 << 4) | \ ++ INTERRUPTS_SUPPORTED) ++ ++enum { ++ STATE_IDLE = 0, ++ STATE_READY, ++ STATE_COMPLETION, ++ STATE_EXECUTION, ++ STATE_RECEPTION ++}; ++ ++#define NUM_LOCALITIES 5 ++#define NO_LOCALITY 0xff ++ ++#define IS_VALID_LOC(x) ((x) < NUM_LOCALITIES) ++ ++#define TPM_DID 0x0001 ++#define TPM_VID 0x0001 ++#define TPM_RID 0x0001 ++ ++/* if the connection to the vTPM should be closed after a successfully ++ received response; set to '0' to allow keeping the connection */ ++#define FORCE_CLOSE 0 ++ ++/* local data structures */ ++ ++typedef struct TPMTx { ++ int fd[2]; ++} tpmTx; ++ ++typedef struct TPMBuffer { ++ uint8_t instance[4]; /* instance number in network byte order */ ++ uint8_t buf[TPM_MAX_PKT]; ++} __attribute__((packed)) tpmBuffer; ++ ++/* locality data */ ++typedef struct TPMLocal { ++ uint32_t state; ++ uint8_t access; ++ uint8_t sts; ++ uint32_t inte; ++ uint32_t ints; ++} tpmLoc; ++ ++/* overall state of the TPM interface; 's' marks as save upon suspension */ ++typedef struct TPMState { ++ uint32_t offset; /* s */ ++ tpmBuffer buffer; /* s */ ++ uint8_t active_loc; /* s */ ++ uint8_t aborting_locty; ++ uint8_t next_locty; ++ uint8_t irq_pending; /* s */ ++ tpmLoc loc[NUM_LOCALITIES]; /* s */ ++ QEMUTimer *poll_timer; ++ SetIRQFunc *set_irq; ++ void *irq_opaque; ++ int irq; ++ int poll_attempts; ++ uint32_t vtpm_instance; /* vtpm inst. number; determined from xenstore*/ ++ int Transmitlayer; ++ tpmTx tpmTx; ++} tpmState; ++ ++ ++/* local prototypes */ ++static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg); ++static int TPM_Receive(tpmState *s, tpmBuffer *buffer); ++static uint32_t vtpm_instance_from_xenstore(void); ++static void tis_poll_timer(void *opaque); ++static void tis_prep_next_interrupt(tpmState *s); ++static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask); ++static void close_vtpm_channel(tpmState *s, int force); ++static void open_vtpm_channel(tpmState *s); ++static void tis_attempt_receive(tpmState *s, uint8_t locty); ++ ++/* transport layer functions: local sockets */ ++static int create_local_socket(tpmState *s, uint32_t vtpm_instance); ++static int write_local_socket(tpmState *s, const tpmBuffer *); ++static int read_local_socket(tpmState *s, tpmBuffer *); ++static int close_local_socket(tpmState *s, int force); ++static int has_channel_local_socket(tpmState *s); ++#define LOCAL_SOCKET_PATH "/var/vtpm/vtpm_all.socket" ++ ++ ++#define NUM_TRANSPORTS 1 ++ ++struct vTPM_transmit { ++ int (*open) (tpmState *s, uint32_t vtpm_instance); ++ int (*write) (tpmState *s, const tpmBuffer *); ++ int (*read) (tpmState *s, tpmBuffer *); ++ int (*close) (tpmState *s, int); ++ int (*has_channel) (tpmState *s); ++} vTPMTransmit[NUM_TRANSPORTS] = { ++ { .open = create_local_socket, ++ .write = write_local_socket, ++ .read = read_local_socket, ++ .close = close_local_socket, ++ .has_channel = has_channel_local_socket, ++ } ++}; ++ ++ ++#define IS_COMM_WITH_VTPM(s) \ ++ ((s)->Transmitlayer >= 0 && \ ++ vTPMTransmit[(s)->Transmitlayer].has_channel(s)) ++ ++ ++/********************************************************************** ++ helper functions ++ *********************************************************************/ ++ ++static inline uint32_t tpm_get_size_from_buffer(const uint8_t *buffer) ++{ ++ uint32_t len = (buffer[4] << 8) + buffer[5]; ++ return len; ++} ++ ++static inline void tpm_initialize_instance(tpmState *s, uint32_t instance) ++{ ++ s->buffer.instance[0] = (instance >> 24) & 0xff; ++ s->buffer.instance[1] = (instance >> 16) & 0xff; ++ s->buffer.instance[2] = (instance >> 8) & 0xff; ++ s->buffer.instance[3] = (instance >> 0) & 0xff; ++} ++ ++/* ++ * open communication channel with a vTPM ++ */ ++static void open_vtpm_channel(tpmState *s) ++{ ++ int idx; ++ /* search a usable transmit layer */ ++ for (idx = 0; idx < NUM_TRANSPORTS; idx++) { ++ if (1 == vTPMTransmit[idx].open(s, s->vtpm_instance)) { ++ /* found one */ ++ s->Transmitlayer = idx; ++ break; ++ } ++ } ++} ++ ++/* ++ * close the communication channel with the vTPM ++ */ ++static inline void close_vtpm_channel(tpmState *s, int force) ++{ ++ if (1 == vTPMTransmit[s->Transmitlayer].close(s, force)) { ++ s->Transmitlayer = -1; ++ } ++} ++ ++static inline uint8_t locality_from_addr(target_phys_addr_t addr) ++{ ++ return (uint8_t)((addr >> 12) & 0x7); ++} ++ ++ ++/********************************************************************** ++ low-level transmission layer methods ++ *********************************************************************/ ++ ++/* ++ * the 'open' method that creates the filedescriptor for communicating ++ * only one is needed for reading and writing ++ */ ++static int create_local_socket(tpmState *s, uint32_t vtpm_instance) ++{ ++ int success = 1; ++ if (s->tpmTx.fd[0] < 0) { ++ s->tpmTx.fd[0] = socket(PF_LOCAL, SOCK_STREAM, 0); ++ ++ if (has_channel_local_socket(s)) { ++ struct sockaddr_un addr; ++ memset(&addr, 0x0, sizeof(addr)); ++ addr.sun_family = AF_LOCAL; ++ strcpy(addr.sun_path, LOCAL_SOCKET_PATH); ++ if (connect(s->tpmTx.fd[0], ++ (struct sockaddr *)&addr, ++ sizeof(addr)) != 0) { ++ close_local_socket(s, 1); ++ success = 0; ++ } else { ++ /* put filedescriptor in non-blocking mode for polling */ ++ int flags = fcntl(s->tpmTx.fd[0], F_GETFL); ++ fcntl(s->tpmTx.fd[0], F_SETFL, flags | O_NONBLOCK); ++ } ++#ifdef DEBUG_TPM ++ if (success) ++ fprintf(logfile,"Successfully connected using local socket " ++ LOCAL_SOCKET_PATH ".\n"); ++ else ++ fprintf(logfile,"Could not connect to local socket " ++ LOCAL_SOCKET_PATH ".\n"); ++#endif ++ } else { ++ success = 0; ++ } ++ } ++ return success; ++} ++ ++/* ++ * the 'write' method for sending requests to the vTPM ++ * four bytes with the vTPM instance number are prepended to each request ++ * the locality in which the command was sent is transmitted in the ++ * highest 3 bits ++ */ ++static int write_local_socket(tpmState *s, const tpmBuffer *buffer) ++{ ++ uint32_t size = tpm_get_size_from_buffer(buffer->buf); ++ int len; ++ ++ len = write(s->tpmTx.fd[0], ++ buffer->instance, ++ sizeof(buffer->instance) + size); ++ if (len == sizeof(buffer->instance) + size) { ++ return len; ++ } else { ++ return -1; ++ } ++} ++ ++/* ++ * the 'read' method for receiving of responses from the TPM ++ * this function expects that four bytes with the instance number ++ * are received from the vTPM ++ */ ++static int read_local_socket(tpmState *s, tpmBuffer *buffer) ++{ ++ int off; ++#ifdef DEBUG_TPM ++ fprintf(logfile, "Reading from fd %d\n", s->tpmTx.fd[0]); ++#endif ++ off = read(s->tpmTx.fd[0], ++ buffer->instance, ++ sizeof(buffer->instance)+TPM_MAX_PKT); ++#ifdef DEBUG_TPM ++ fprintf(logfile, "Read %d bytes\n", off); ++#endif ++ return off; ++} ++ ++/* ++ * the 'close' method ++ * shut down communication with the vTPM ++ * 'force' = 1 indicates that the socket *must* be closed ++ * 'force' = 0 indicates that a connection may be maintained ++ */ ++static int close_local_socket(tpmState *s, int force) ++{ ++ if (force) { ++ close(s->tpmTx.fd[0]); ++#ifdef DEBUG_TPM ++ fprintf(logfile,"Closed connection with fd %d\n",s->tpmTx.fd[0]); ++#endif ++ s->tpmTx.fd[0] = -1; ++ return 1; /* socket was closed */ ++ } ++#ifdef DEBUG_TPM ++ fprintf(logfile,"Keeping connection with fd %d\n",s->tpmTx.fd[0]); ++#endif ++ return 0; ++} ++ ++/* ++ * the 'has_channel' method that checks whether there's a communication ++ * channel with the vTPM ++ */ ++static int has_channel_local_socket(tpmState *s) ++{ ++ return (s->tpmTx.fd[0] > 0); ++} ++ ++/**********************************************************************/ ++ ++/* ++ * read a byte of response data ++ */ ++static uint32_t tpm_data_read(tpmState *s, uint8_t locty) ++{ ++ uint32_t ret, len; ++ ++ /* try to receive data, if none are there it is ok */ ++ tis_attempt_receive(s, locty); ++ ++ if (s->loc[locty].state != STATE_COMPLETION) { ++ return 0xff; ++ } ++ ++ len = tpm_get_size_from_buffer(s->buffer.buf); ++ ret = s->buffer.buf[s->offset++]; ++ if (s->offset >= len) { ++ s->loc[locty].sts = STS_VALID ; ++ s->offset = 0; ++ } ++#ifdef DEBUG_TPM ++ fprintf(logfile,"tpm_data_read byte x%02x [%d]\n",ret,s->offset-1); ++#endif ++ return ret; ++} ++ ++ ++ ++/* raise an interrupt if allowed */ ++static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask) ++{ ++ if (!s->irq_pending && ++ (s->loc[locty].inte & INT_ENABLED) && ++ (s->loc[locty].inte & irqmask)) { ++ if ((irqmask & s->loc[locty].ints) == 0) { ++#ifdef DEBUG_TPM ++ fprintf(logfile,"Raising IRQ for flag %08x\n",irqmask); ++#endif ++ s->set_irq(s->irq_opaque, s->irq, 1); ++ s->irq_pending = 1; ++ s->loc[locty].ints |= irqmask; ++ } ++ } ++} ++ ++/* abort execution of command */ ++static void tis_abort(tpmState *s) ++{ ++ s->offset = 0; ++ s->active_loc = s->next_locty; ++ ++ /* ++ * Need to react differently depending on who's aborting now and ++ * which locality will become active afterwards. ++ */ ++ if (s->aborting_locty == s->next_locty) { ++ s->loc[s->aborting_locty].state = STATE_READY; ++ s->loc[s->aborting_locty].sts = STS_COMMAND_READY; ++ tis_raise_irq(s, s->aborting_locty, INT_COMMAND_READY); ++ } ++ ++ /* locality after abort is another one than the current one */ ++ if (s->aborting_locty != s->next_locty && s->next_locty != NO_LOCALITY) { ++ s->loc[s->aborting_locty].access &= ~ACCESS_ACTIVE_LOCALITY; ++ s->loc[s->next_locty].access |= ACCESS_ACTIVE_LOCALITY; ++ tis_raise_irq(s, s->next_locty, INT_LOCALITY_CHANGED); ++ } ++ ++ s->aborting_locty = NO_LOCALITY; /* nobody's aborting a command anymore */ ++ ++ qemu_del_timer(s->poll_timer); ++} ++ ++/* abort current command */ ++static void tis_prep_abort(tpmState *s, uint8_t locty, uint8_t newlocty) ++{ ++ s->aborting_locty = locty; /* current locality */ ++ s->next_locty = newlocty; /* locality after successful abort */ ++ ++ /* ++ * only abort a command using an interrupt if currently executing ++ * a command AND if there's a valid connection to the vTPM. ++ */ ++ if (s->loc[locty].state == STATE_EXECUTION && ++ IS_COMM_WITH_VTPM(s)) { ++ /* start timer and inside the timer wait for the result */ ++ s->poll_attempts = 0; ++ tis_prep_next_interrupt(s); ++ } else { ++ tis_abort(s); ++ } ++} ++ ++ ++/* ++ * Try to receive a response from the vTPM ++ */ ++static void tis_attempt_receive(tpmState *s, uint8_t locty) ++{ ++ /* ++ * Attempt to read from the vTPM here if ++ * - not aborting a command ++ * - command has been sent and state is 'EXECUTION' now ++ * - no data are already available (data have already been read) ++ * - there's a communication path to the vTPM established ++ */ ++ if (!IS_VALID_LOC(s->aborting_locty)) { ++ if (s->loc[locty].state == STATE_EXECUTION) { ++ if (0 == (s->loc[locty].sts & STS_DATA_AVAILABLE)){ ++ if (IS_COMM_WITH_VTPM(s)) { ++ int n = TPM_Receive(s, &s->buffer); ++ if (n > 0) { ++ s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE; ++ s->loc[locty].state = STATE_COMPLETION; ++ close_vtpm_channel(s, FORCE_CLOSE); ++ tis_raise_irq(s, locty, INT_DATA_AVAILABLE); ++ } ++ } ++ } ++ } ++ } ++} ++ ++/* ++ * Read a register of the TIS interface ++ * See specs pages 33-63 for description of the registers ++ */ ++static uint32_t tis_mem_readl(void *opaque, target_phys_addr_t addr) ++{ ++ tpmState *s = (tpmState *)opaque; ++ uint16_t offset = addr & 0xffc; ++ uint8_t shift = (addr & 0x3) * 8; ++ uint32_t val = 0; ++ uint8_t locty = locality_from_addr(addr); ++ ++ if (offset == TPM_REG_ACCESS) { ++ if (s->active_loc == locty) { ++ s->loc[locty].access |= (1 << 5); ++ } else { ++ s->loc[locty].access &= ~(1 << 5); ++ } ++ val = s->loc[locty].access; ++ } else ++ if (offset == TPM_REG_INT_ENABLE) { ++ val = s->loc[locty].inte; ++ } else ++ if (offset == TPM_REG_INT_VECTOR) { ++ val = s->irq; ++ } else ++ if (offset == TPM_REG_INT_STATUS) { ++ tis_attempt_receive(s, locty); ++ val = s->loc[locty].ints; ++ } else ++ if (offset == TPM_REG_INTF_CAPABILITY) { ++ val = CAPABILITIES_SUPPORTED; ++ } else ++ if (offset == TPM_REG_STS) { /* status register */ ++ tis_attempt_receive(s, locty); ++ val = (sizeof(s->buffer.buf) - s->offset) << 8 | s->loc[locty].sts; ++ } else ++ if (offset == TPM_REG_DATA_FIFO) { ++ val = tpm_data_read(s, locty); ++ } else ++ if (offset == TPM_REG_DID_VID) { ++ val = (TPM_DID << 16) | TPM_VID; ++ } else ++ if (offset == TPM_REG_RID) { ++ val = TPM_RID; ++ } ++ ++ if (shift) ++ val >>= shift; ++ ++#ifdef DEBUG_TPM ++ fprintf(logfile," read(%08x) = %08x\n", ++ addr, ++ val); ++#endif ++ ++ return val; ++} ++ ++/* ++ * Write a value to a register of the TIS interface ++ * See specs pages 33-63 for description of the registers ++ */ ++static void tis_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) ++{ ++ tpmState* s=(tpmState*)opaque; ++ uint16_t off = addr & 0xfff; ++ uint8_t locty = locality_from_addr(addr); ++ int n, c; ++ uint32_t len; ++ ++#ifdef DEBUG_TPM ++ fprintf(logfile,"write(%08x) = %08x\n", ++ addr, ++ val); ++#endif ++ ++ if (off == TPM_REG_ACCESS) { ++ if (val & ACCESS_ACTIVE_LOCALITY) { ++ /* give up locality if currently owned */ ++ if (s->active_loc == locty) { ++ uint8_t newlocty = NO_LOCALITY; ++ s->loc[locty].access &= ~(ACCESS_PENDING_REQUEST); ++ /* anybody wants the locality ? */ ++ for (c = NUM_LOCALITIES - 1; c >= 0; c--) { ++ if (s->loc[c].access & ACCESS_REQUEST_USE) { ++ s->loc[c].access |= ACCESS_TPM_REG_VALID_STS; ++ s->loc[c].access &= ~ACCESS_REQUEST_USE; ++ newlocty = c; ++ break; ++ } ++ } ++ tis_prep_abort(s, locty, newlocty); ++ } ++ } ++ if (val & ACCESS_BEEN_SEIZED) { ++ /* clear the flag */ ++ s->loc[locty].access &= ~ACCESS_BEEN_SEIZED; ++ } ++ if (val & ACCESS_SEIZE) { ++ if (locty > s->active_loc && IS_VALID_LOC(s->active_loc)) { ++ s->loc[s->active_loc].access |= ACCESS_BEEN_SEIZED; ++ s->loc[locty].access = ACCESS_TPM_REG_VALID_STS; ++ tis_prep_abort(s, s->active_loc, locty); ++ } ++ } ++ if (val & ACCESS_REQUEST_USE) { ++ if (IS_VALID_LOC(s->active_loc)) { ++ /* locality election */ ++ s->loc[s->active_loc].access |= ACCESS_PENDING_REQUEST; ++ } else { ++ /* no locality active -> make this one active now */ ++ s->loc[locty].access |= ACCESS_ACTIVE_LOCALITY; ++ s->active_loc = locty; ++ tis_raise_irq(s, locty, INT_LOCALITY_CHANGED); ++ } ++ } ++ } else ++ if (off == TPM_REG_INT_ENABLE) { ++ s->loc[locty].inte = (val & (INT_ENABLED | (0x3 << 3) | ++ INTERRUPTS_SUPPORTED)); ++ } else ++ if (off == TPM_REG_INT_STATUS) { ++ /* clearing of interrupt flags */ ++ if ((val & INTERRUPTS_SUPPORTED) && ++ (s->loc[locty].ints & INTERRUPTS_SUPPORTED)) { ++ s->set_irq(s->irq_opaque, s->irq, 0); ++ s->irq_pending = 0; ++ } ++ s->loc[locty].ints &= ~(val & INTERRUPTS_SUPPORTED); ++ } else ++ if (off == TPM_REG_STS) { ++ if (val & STS_COMMAND_READY) { ++ if (s->loc[locty].state == STATE_IDLE) { ++ s->loc[locty].sts = STS_COMMAND_READY; ++ s->loc[locty].state = STATE_READY; ++ tis_raise_irq(s, locty, INT_COMMAND_READY); ++ } else if (s->loc[locty].state == STATE_COMPLETION || ++ s->loc[locty].state == STATE_EXECUTION || ++ s->loc[locty].state == STATE_RECEPTION) { ++ /* abort currently running command */ ++ tis_prep_abort(s, locty, locty); ++ } ++ } ++ if (val & STS_TPM_GO) { ++ n = TPM_Send(s, &s->buffer, locty, "tpm_data_write"); ++ if (n > 0) { ++ /* sending of data was successful */ ++ s->offset = 0; ++ s->loc[locty].state = STATE_EXECUTION; ++ if (s->loc[locty].inte & (INT_ENABLED | INT_DATA_AVAILABLE)) { ++ s->poll_attempts = 0; ++ tis_prep_next_interrupt(s); ++ } ++ } ++ } ++ if (val & STS_RESPONSE_RETRY) { ++ s->offset = 0; ++ } ++ } else if (off == TPM_REG_DATA_FIFO) { ++ /* data fifo */ ++ if (s->loc[locty].state == STATE_IDLE || ++ s->loc[locty].state == STATE_EXECUTION || ++ s->loc[locty].state == STATE_COMPLETION) { ++ /* drop the byte */ ++ } else { ++#ifdef TPM_DEBUG ++ fprintf(logfile,"Byte to send to TPM: %02x\n", val); ++#endif ++ s->loc[locty].state = STATE_RECEPTION; ++ ++ if (s->offset < sizeof(s->buffer.buf)) ++ s->buffer.buf[s->offset++] = (uint8_t)val; ++ ++ if (s->offset > 5) { ++ /* we have a packet length - see if we have all of it */ ++ len = tpm_get_size_from_buffer(s->buffer.buf); ++ if (len > s->offset) { ++ s->loc[locty].sts = STS_EXPECT | STS_VALID; ++ } else { ++ s->loc[locty].sts = STS_VALID; ++ } ++ } ++ } ++ } ++} ++ ++/* ++ * Prepare the next interrupt for example after a command has ++ * been sent out for the purpose of receiving the response. ++ * Depending on how many interrupts (used for polling on the fd) have ++ * already been schedule, this function determines the delta in time ++ * to the next interrupt. This accomodates for commands that finish ++ * quickly. ++ */ ++static void tis_prep_next_interrupt(tpmState *s) ++{ ++ int64_t expiration; ++ int rate = 5; /* 5 times per second */ ++ ++ /* ++ poll often at the beginning for quickly finished commands, ++ then back off ++ */ ++ if (s->poll_attempts < 5) { ++ rate = 20; ++ } else if (s->poll_attempts < 10) { ++ rate = 10; ++ } ++ ++ expiration = qemu_get_clock(vm_clock) + (ticks_per_sec / rate); ++ qemu_mod_timer(s->poll_timer, expiration); ++ s->poll_attempts++; ++} ++ ++ ++/* ++ * The polling routine called when the 'timer interrupt' fires. ++ * Tries to receive a command from the vTPM. ++ */ ++static void tis_poll_timer(void *opaque) ++{ ++ tpmState* s=(tpmState*)opaque; ++ uint8_t locty = s->active_loc; ++ ++ if (!IS_VALID_LOC(locty) || ++ (!(s->loc[locty].inte & INT_ENABLED) && ++ (s->aborting_locty != NO_LOCALITY)) || ++ !IS_COMM_WITH_VTPM(s)) { ++ /* no more interrupts requested, so no more polling needed */ ++ qemu_del_timer(s->poll_timer); ++ } ++ ++ if (!IS_COMM_WITH_VTPM(s)) { ++ if (s->aborting_locty != NO_LOCALITY) { ++ tis_abort(s); ++ } ++ return; ++ } ++ ++ if (s->aborting_locty != NO_LOCALITY) { ++ int n = TPM_Receive(s, &s->buffer); ++#ifdef DEBUG_TPM ++ fprintf(logfile,"Receiving for abort.\n"); ++#endif ++ if (n > 0) { ++ close_vtpm_channel(s, FORCE_CLOSE); ++ tis_abort(s); ++#ifdef DEBUG_TPM ++ fprintf(logfile,"Abort is complete.\n"); ++#endif ++ } else { ++ tis_prep_next_interrupt(s); ++ } ++ } else if (IS_VALID_LOC(locty)) { ++ if (s->loc[locty].state == STATE_EXECUTION) { ++ /* poll for result */ ++ int n = TPM_Receive(s, &s->buffer); ++ if (n > 0) { ++ s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE; ++ s->loc[locty].state = STATE_COMPLETION; ++ close_vtpm_channel(s, FORCE_CLOSE); ++ tis_raise_irq(s, locty, INT_DATA_AVAILABLE); ++ } else { ++ /* nothing received */ ++ tis_prep_next_interrupt(s); ++ } ++ } ++ } ++} ++ ++ ++static CPUReadMemoryFunc *tis_readfn[3]={ ++ tis_mem_readl, ++ tis_mem_readl, ++ tis_mem_readl ++}; ++ ++static CPUWriteMemoryFunc *tis_writefn[3]={ ++ tis_mem_writel, ++ tis_mem_writel, ++ tis_mem_writel ++}; ++ ++/* ++ * Save the internal state of this interface for later resumption. ++ * Need to get any outstanding responses from the vTPM back, so ++ * this might delay the suspend for a while. ++ */ ++static void tpm_save(QEMUFile* f,void* opaque) ++{ ++ tpmState* s=(tpmState*)opaque; ++ int c; ++ ++ /* need to wait for outstanding requests to complete */ ++ if (IS_COMM_WITH_VTPM(s)) { ++ int repeats = 30; /* 30 seconds; really should be infty */ ++ while (repeats > 0 && ++ !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) { ++ int n = TPM_Receive(s, &s->buffer); ++ if (n > 0) { ++ if (IS_VALID_LOC(s->active_loc)) { ++ s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE; ++ } ++ /* close the connection with the vTPM for good */ ++ close_vtpm_channel(s, 1); ++ break; ++ } ++ sleep(1); ++ } ++ } ++ ++ qemu_put_be32s(f,&s->offset); ++ qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT); ++ qemu_put_8s(f, &s->active_loc); ++ qemu_put_8s(f, &s->irq_pending); ++ for (c = 0; c < NUM_LOCALITIES; c++) { ++ qemu_put_be32s(f, &s->loc[c].state); ++ qemu_put_8s(f, &s->loc[c].access); ++ qemu_put_8s(f, &s->loc[c].sts); ++ qemu_put_be32s(f, &s->loc[c].inte); ++ qemu_put_be32s(f, &s->loc[c].ints); ++ } ++} ++ ++/* ++ * load TIS interface state ++ */ ++static int tpm_load(QEMUFile* f,void* opaque,int version_id) ++{ ++ tpmState* s=(tpmState*)opaque; ++ int c; ++ ++ if (version_id != 1) ++ return -EINVAL; ++ ++ qemu_get_be32s(f,&s->offset); ++ qemu_get_buffer(f, s->buffer.buf, TPM_MAX_PKT); ++ qemu_get_8s(f, &s->active_loc); ++ qemu_get_8s(f, &s->irq_pending); ++ for (c = 0; c < NUM_LOCALITIES; c++) { ++ qemu_get_be32s(f, &s->loc[c].state); ++ qemu_get_8s(f, &s->loc[c].access); ++ qemu_get_8s(f, &s->loc[c].sts); ++ qemu_get_be32s(f, &s->loc[c].inte); ++ qemu_get_be32s(f, &s->loc[c].ints); ++ } ++ ++ /* need to be able to get the instance number from the xenstore */ ++ s->vtpm_instance = vtpm_instance_from_xenstore(); ++ if (s->vtpm_instance == VTPM_BAD_INSTANCE) ++ return -EINVAL; ++ tpm_initialize_instance(s, s->vtpm_instance); ++ ++ return 0; ++} ++ ++ ++typedef struct LPCtpmState { ++ tpmState tpm; ++ int mem; ++} LPCtpmState; ++ ++ ++/* ++ * initialize TIS interface ++ */ ++void tpm_tis_init(SetIRQFunc *set_irq, void *opaque, int irq) ++{ ++ LPCtpmState *d; ++ tpmState *s; ++ int c = 0; ++ uint32_t vtpm_in; ++ ++ vtpm_in = vtpm_instance_from_xenstore(); ++ /* no valid vtpm instance -> no device */ ++ if (vtpm_in == VTPM_BAD_INSTANCE) ++ return; ++ ++ d = qemu_mallocz(sizeof(LPCtpmState)); ++ d->mem = cpu_register_io_memory(0, tis_readfn, tis_writefn, d); ++ ++ if (d->mem == -1) { ++ return; ++ } ++ ++ cpu_register_physical_memory(TIS_ADDR_BASE, ++ 0x1000 * NUM_LOCALITIES, d->mem); ++ ++ /* initialize tpmState */ ++ s = &d->tpm; ++ ++ s->offset = 0; ++ s->active_loc = NO_LOCALITY; ++ ++ while (c < NUM_LOCALITIES) { ++ s->loc[c].access = (1 << 7); ++ s->loc[c].sts = 0; ++ s->loc[c].inte = (1 << 3); ++ s->loc[c].ints = 0; ++ s->loc[c].state = STATE_IDLE; ++ c++; ++ } ++ s->poll_timer = qemu_new_timer(vm_clock, tis_poll_timer, s); ++ s->set_irq = set_irq; ++ s->irq_opaque = opaque; ++ s->irq = irq; ++ s->vtpm_instance = vtpm_in; ++ s->Transmitlayer = -1; ++ s->tpmTx.fd[0] = -1; ++ s->tpmTx.fd[1] = -1; ++ ++ tpm_initialize_instance(s, s->vtpm_instance); ++ memset(s->buffer.buf,0,sizeof(s->buffer.buf)); ++ ++ register_savevm("tpm-tis", 0, 1, tpm_save, tpm_load, s); ++} ++ ++/****************************************************************************/ ++/* optional verbose logging of data to/from vtpm */ ++/****************************************************************************/ ++#ifdef DEBUG_TPM ++static void showBuff(unsigned char *buff, char *string) ++{ ++ uint32_t i, len; ++ ++ len = tpm_get_size_from_buffer(buff); ++ fprintf(logfile,"%s length = %d\n", string, len); ++ for (i = 0; i < len; i++) { ++ if (i && !(i % 16)) { ++ fprintf(logfile,"\n"); ++ } ++ fprintf(logfile,"%.2X ", buff[i]); ++ } ++ fprintf(logfile,"\n"); ++} ++#endif ++ ++/****************************************************************************/ ++/* Transmit request to TPM and read Response */ ++/****************************************************************************/ ++ ++const static unsigned char tpm_failure[] = { ++ 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x0a, ++ 0x00, 0x00, 0x00, 0x09 ++}; ++ ++ ++/* ++ * Send a TPM request. ++ */ ++static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg) ++{ ++ int len; ++ uint32_t size = tpm_get_size_from_buffer(buffer->buf); ++ ++ /* try to establish a connection to the vTPM */ ++ if ( !IS_COMM_WITH_VTPM(s)) { ++ open_vtpm_channel(s); ++ } ++ ++ if ( !IS_COMM_WITH_VTPM(s)) { ++ unsigned char tag = buffer->buf[1]; ++ ++ /* there's a failure response from the TPM */ ++ memcpy(buffer->buf, tpm_failure, sizeof(tpm_failure)); ++ buffer->buf[1] = tag + 3; ++ if (IS_VALID_LOC(s->active_loc)) { ++ s->loc[s->active_loc].sts = STS_DATA_AVAILABLE | STS_VALID; ++ } ++#ifdef DEBUG_TPM ++ fprintf(logfile,"No TPM running!\n"); ++#endif ++ /* the request went out ok. */ ++ return sizeof(buffer->instance) + size; ++ } ++ ++#ifdef DEBUG_TPM ++ showBuff(buffer->buf, "To TPM"); ++#endif ++ ++ /* transmit the locality in the highest 3 bits */ ++ buffer->instance[0] &= 0x1f; ++ buffer->instance[0] |= (locty << 5); ++ ++ len = vTPMTransmit[s->Transmitlayer].write(s, buffer); ++ if (len < 0) { ++ s->Transmitlayer = -1; ++ } ++ return len; ++} ++ ++/* ++ * Try to receive data from the file descriptor. Since it is in ++ * non-blocking mode it is possible that no data are actually received - ++ * whatever calls this function needs to try again later. ++ */ ++static int TPM_Receive(tpmState *s, tpmBuffer *buffer) ++{ ++ int off; ++ ++ off = vTPMTransmit[s->Transmitlayer].read(s, buffer); ++ ++ if (off < 0) { ++ /* EAGAIN is set in errno due to non-blocking mode */ ++ return -1; ++ } ++ ++ if (off == 0) { ++#ifdef DEBUG_TPM ++ fprintf(logfile,"TPM GONE? errno=%d\n",errno); ++#endif ++ close_vtpm_channel(s, 1); ++ /* pretend that data are available */ ++ if (IS_VALID_LOC(s->active_loc)) { ++ s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE; ++ s->loc[s->active_loc].state = STATE_COMPLETION; ++ tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE); ++ } ++ return -1; ++ } ++ ++#ifdef DEBUG_TPM ++ if (off > sizeof(buffer->instance ) + 6) { ++ uint32_t size = tpm_get_size_from_buffer(buffer->buf); ++ if (size + sizeof(buffer->instance) != off) { ++ fprintf(logfile,"TPM: Packet size is bad! %d != %d\n", ++ size + sizeof(buffer->instance), ++ off); ++ } else { ++ uint32_t ret; ++ showBuff(buffer->buf, "From TPM"); ++ ret = (buffer->buf[8])*256 + buffer->buf[9]; ++ if (ret) ++ fprintf(logfile,"Receive failed with error %d\n", ret); ++ else ++ fprintf(logfile,"Receive succeeded. Got response of length %d (=%d)\n", ++ size, off); ++ } ++ } ++#endif ++ ++ /* assuming reading in one chunk for now */ ++ return off; ++} ++ ++ ++/**************************************************************************** ++ Helper functions for reading data from the xenstore such as ++ reading virtual TPM instance information ++ ****************************************************************************/ ++int has_tpm_device(void) ++{ ++ int ret = 0; ++ struct xs_handle *handle = xs_daemon_open(); ++ if (handle) { ++ ret = xenstore_domain_has_devtype(handle, "vtpm"); ++ xs_daemon_close(handle); ++ } ++ return ret; ++} ++ ++ ++/* ++ * Wait until hotplug scripts have finished then read the vTPM instance ++ * number from the xenstore. ++ */ ++static uint32_t vtpm_instance_from_xenstore(void) ++{ ++ unsigned int num; ++ uint32_t number = VTPM_BAD_INSTANCE; ++ int end = 0; ++ char *token = "tok"; ++ int subscribed = 0; ++ int ctr = 0; ++ fd_set readfds; ++ ++ struct xs_handle *handle = xs_daemon_open(); ++ ++ FD_ZERO(&readfds); ++ ++ if (handle) { ++ char **e = xenstore_domain_get_devices(handle, "vtpm", &num); ++ int fd = xs_fileno(handle); ++ FD_SET(fd, &readfds); ++ if (e) { ++ do { ++ struct timeval tv = { ++ .tv_sec = 30, ++ .tv_usec = 0, ++ }; ++ /* need to make sure that the hotplug scripts have finished */ ++ char *status = xenstore_read_hotplug_status(handle, ++ "vtpm", ++ e[0]); ++ if (status) { ++ if (!strcmp(status, "connected")) { ++ char *inst = xenstore_backend_read_variable(handle, ++ "vtpm", ++ e[0], ++ "instance"); ++ if (1 != (sscanf(inst,"%d",&number))) ++ number = VTPM_BAD_INSTANCE; ++ free(inst); ++ } else { ++ fprintf(logfile, ++ "bad status '%s' from vtpm hotplug\n", ++ status); ++ } ++ free(status); ++ end = 1; ++ } else { ++ /* no status, yet */ ++ int rc; ++ unsigned int nr; ++ char **f; ++ ++ if (!subscribed) { ++ rc = xenstore_subscribe_to_hotplug_status(handle, ++ "vtpm", ++ e[0], ++ token); ++ if (rc != 0) ++ break; ++ subscribed = 1; ++ } ++ rc = select(fd+1, &readfds, NULL, NULL, &tv); ++ /* get what's available -- drain the fd */ ++ f = xs_read_watch(handle, &nr); ++ ctr++; ++ free(f); ++ if (ctr > 2) ++ end = 1; ++ } ++ } while (end == 0); ++ free(e); ++ } ++ if (subscribed) { ++ /* clean up */ ++ xenstore_unsubscribe_from_hotplug_status(handle, ++ "vtpm", ++ e[0], ++ token); ++ } ++ xs_daemon_close(handle); ++ } ++ if (number == VTPM_BAD_INSTANCE) ++ fprintf(logfile, "no valid vtpm instance"); ++ else ++ fprintf(logfile,"vtpm instance:%d\n",number); ++ return number; ++} +Index: ioemu/vl.h +=================================================================== +--- ioemu.orig/vl.h 2006-12-08 18:33:48.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 18:35:14.000000000 +0000 +@@ -932,6 +932,10 @@ + void piix4_pm_init(PCIBus *bus, int devfn); + void acpi_bios_init(void); + ++/* tpm_tis.c */ ++int has_tpm_device(void); ++void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq); ++ + /* piix4acpi.c */ + extern void pci_piix4_acpi_init(PCIBus *bus, int devfn); + diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/usb-mouse-tablet-status-check --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/usb-mouse-tablet-status-check Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,168 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID 60bbcf799384d779c2a561b9d9ba30f28e31d970 +# Parent fb3cb6f52a2905be938559529ae43b6ba990c878 +[HVM] qemu mouse: Adds support for USB mouse/tablet status check and +restricts Universal Host Controller interrupt generating when received +NAK in interrupt transfer. + +According to usb spec, USB mouse/tablet device returns NAK to host +controller if its status does not alter in interrupt transfer. +And UHC should leave a TD active when receiving NAK and execute this +incompleted TD in a subseqent frame. UHC only generates an interrupt +on complete after the TD with ICO bit is completed. + +This patch make UHC & USB mouse/tablet behave consistently with spec. + +Signed-off-by: Xinmei Huang <xinmei.huang@xxxxxxxxx> + +diff -r fb3cb6f52a29 -r 60bbcf799384 tools/ioemu/hw/usb-hid.c +--- a/tools/ioemu/hw/usb-hid.c Thu Dec 07 11:51:22 2006 +0000 ++++ b/tools/ioemu/hw/usb-hid.c Thu Dec 07 11:52:26 2006 +0000 +@@ -39,6 +39,7 @@ typedef struct USBMouseState { + int x, y; + int kind; + int mouse_grabbed; ++ int status_changed; + } USBMouseState; + + /* mostly the same values as the Bochs USB Mouse device */ +@@ -231,6 +232,7 @@ static void usb_mouse_event(void *opaque + s->dy += dy1; + s->dz += dz1; + s->buttons_state = buttons_state; ++ s->status_changed = 1; + } + + static void usb_tablet_event(void *opaque, +@@ -242,6 +244,7 @@ static void usb_tablet_event(void *opaqu + s->y = y; + s->dz += dz; + s->buttons_state = buttons_state; ++ s->status_changed = 1; + } + + static inline int int_clamp(int val, int vmin, int vmax) +@@ -483,10 +486,16 @@ static int usb_mouse_handle_data(USBDevi + switch(pid) { + case USB_TOKEN_IN: + if (devep == 1) { +- if (s->kind == USB_MOUSE) +- ret = usb_mouse_poll(s, data, len); +- else if (s->kind == USB_TABLET) +- ret = usb_tablet_poll(s, data, len); ++ if (s->kind == USB_MOUSE) ++ ret = usb_mouse_poll(s, data, len); ++ else if (s->kind == USB_TABLET) ++ ret = usb_tablet_poll(s, data, len); ++ ++ if (!s->status_changed) ++ ret = USB_RET_NAK; ++ else ++ s->status_changed = 0; ++ + } else { + goto fail; + } +@@ -523,6 +532,7 @@ USBDevice *usb_tablet_init(void) + s->dev.handle_data = usb_mouse_handle_data; + s->dev.handle_destroy = usb_mouse_handle_destroy; + s->kind = USB_TABLET; ++ s->status_changed = 0; + + pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet"); + +@@ -544,6 +554,7 @@ USBDevice *usb_mouse_init(void) + s->dev.handle_data = usb_mouse_handle_data; + s->dev.handle_destroy = usb_mouse_handle_destroy; + s->kind = USB_MOUSE; ++ s->status_changed = 0; + + pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse"); + +diff -r fb3cb6f52a29 -r 60bbcf799384 tools/ioemu/hw/usb-uhci.c +--- a/tools/ioemu/hw/usb-uhci.c Thu Dec 07 11:51:22 2006 +0000 ++++ b/tools/ioemu/hw/usb-uhci.c Thu Dec 07 11:52:26 2006 +0000 +@@ -424,12 +424,10 @@ static int uhci_handle_td(UHCIState *s, + uint8_t buf[2048]; + int len, max_len, err, ret; + +- if (td->ctrl & TD_CTRL_IOC) { +- *int_mask |= 0x01; +- } +- +- if (!(td->ctrl & TD_CTRL_ACTIVE)) +- return 1; ++ if (!(td->ctrl & TD_CTRL_ACTIVE)){ ++ ret = 1; ++ goto out; ++ } + + /* TD is active */ + max_len = ((td->token >> 21) + 1) & 0x7ff; +@@ -467,7 +465,8 @@ static int uhci_handle_td(UHCIState *s, + /* invalid pid : frame interrupted */ + s->status |= UHCI_STS_HCPERR; + uhci_update_irq(s); +- return -1; ++ ret = -1; ++ goto out; + } + if (td->ctrl & TD_CTRL_IOS) + td->ctrl &= ~TD_CTRL_ACTIVE; +@@ -479,10 +478,12 @@ static int uhci_handle_td(UHCIState *s, + len < max_len) { + *int_mask |= 0x02; + /* short packet: do not update QH */ +- return 1; ++ ret = 1; ++ goto out; + } else { + /* success */ +- return 0; ++ ret = 0; ++ goto out; + } + } else { + switch(ret) { +@@ -501,23 +502,34 @@ static int uhci_handle_td(UHCIState *s, + } + td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) | + (err << TD_CTRL_ERROR_SHIFT); +- return 1; ++ ret = 1; ++ goto out; + case USB_RET_NAK: + td->ctrl |= TD_CTRL_NAK; + if (pid == USB_TOKEN_SETUP) + goto do_timeout; +- return 1; ++ ret = 1; ++ goto out; + case USB_RET_STALL: + td->ctrl |= TD_CTRL_STALL; + td->ctrl &= ~TD_CTRL_ACTIVE; +- return 1; ++ ret = 1; ++ goto out; + case USB_RET_BABBLE: + td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL; + td->ctrl &= ~TD_CTRL_ACTIVE; + /* frame interrupted */ +- return -1; +- } +- } ++ ret = -1; ++ goto out; ++ } ++ } ++ ++out: ++ /* If TD is inactive and IOC bit set to 1 then update int_mask */ ++ if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) { ++ *int_mask |= 0x01; ++ } ++ return ret; + } + + static void uhci_frame_timer(void *opaque) diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/usb-uhci-buffer-size --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/usb-uhci-buffer-size Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,25 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID f19ddc0ee3e68d5d8a250ba0a20ab7d90ae9a36a +# Parent f66f7c3a82a7420d80714b0d349ee9a24b50ec28 +[QEMU] usb-uhci: Data buffer is too small + +The data buffer is only 1280 bytes long but the user-supplied length +can be as large as 0x7ff. This patch extends the buffer to 2048 +bytes. + +Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> + +Index: ioemu/hw/usb-uhci.c +=================================================================== +--- ioemu.orig/hw/usb-uhci.c 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/hw/usb-uhci.c 2006-12-08 18:23:06.000000000 +0000 +@@ -421,7 +421,7 @@ + static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask) + { + uint8_t pid; +- uint8_t buf[1280]; ++ uint8_t buf[2048]; + int len, max_len, err, ret; + + if (td->ctrl & TD_CTRL_IOC) { diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-japan-keymap --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/vnc-japan-keymap Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,39 @@ +# HG changeset patch +# User kasai.takanori@xxxxxxxxxxxxxx +# Node ID ea1ffa51b4121d36cffdc90276378a6ed334c2cc +# Parent edd592c823a520d4072a95ac39beb2012c05321e +Add the Japanese keymap for VNC Server. + +Signed-off-by: Takanori Kasai < kasai.takanori@xxxxxxxxxxxxxx > + +Index: ioemu/keymaps/ja +=================================================================== +--- ioemu.orig/keymaps/ja 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/keymaps/ja 2006-12-08 18:21:56.000000000 +0000 +@@ -102,3 +102,6 @@ + Henkan_Mode 0x79 + Katakana 0x70 + Muhenkan 0x7b ++Henkan_Mode_Real 0x79 ++Henkan_Mode_Ultra 0x79 ++backslash_ja 0x73 +Index: ioemu/vnc_keysym.h +=================================================================== +--- ioemu.orig/vnc_keysym.h 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/vnc_keysym.h 2006-12-08 18:21:56.000000000 +0000 +@@ -271,5 +271,15 @@ + {"Num_Lock", 0xff7f}, /* XK_Num_Lock */ + {"Pause", 0xff13}, /* XK_Pause */ + {"Escape", 0xff1b}, /* XK_Escape */ ++ ++ /* localized keys */ ++{"BackApostrophe", 0xff21}, ++{"Muhenkan", 0xff22}, ++{"Katakana", 0xff25}, ++{"Zenkaku_Hankaku", 0xff29}, ++{"Henkan_Mode_Real", 0xff23}, ++{"Henkan_Mode_Ultra", 0xff3e}, ++{"backslash_ja", 0xffa5}, ++ + {0,0}, + }; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-monitor-shift-key-processing --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/vnc-monitor-shift-key-processing Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,60 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID 582d21e2d3cd12a13ad4debee9af8bb0f1be413a +# Parent b7095209e31ae1f52cd4b196225a360543e37a80 +[QEMU] Do shift-key processing in QEMU monitor terminal when connected via VNC. +Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> + +Index: ioemu/vnc.c +=================================================================== +--- ioemu.orig/vnc.c 2006-12-08 18:21:36.000000000 +0000 ++++ ioemu/vnc.c 2006-12-08 18:23:12.000000000 +0000 +@@ -114,6 +114,7 @@ + int visible_h; + + int ctl_keys; /* Ctrl+Alt starts calibration */ ++ int shift_keys; /* Shift / CapsLock keys */ + }; + + #define DIRTY_PIXEL_BITS 64 +@@ -870,9 +871,12 @@ + } else if (down) { + int qemu_keysym = 0; + +- if (sym <= 128) /* normal ascii */ ++ if (sym <= 128) { /* normal ascii */ ++ int shifted = vs->shift_keys == 1 || vs->shift_keys == 2; + qemu_keysym = sym; +- else { ++ if (sym >= 'a' && sym <= 'z' && shifted) ++ qemu_keysym -= 'a' - 'A'; ++ } else { + switch (sym) { + case XK_Up: qemu_keysym = QEMU_KEY_UP; break; + case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break; +@@ -903,6 +907,10 @@ + vs->ctl_keys |= 2; + break; + ++ case XK_Shift_L: ++ vs->shift_keys |= 1; ++ break; ++ + default: + break; + } +@@ -916,6 +924,14 @@ + vs->ctl_keys &= ~2; + break; + ++ case XK_Shift_L: ++ vs->shift_keys &= ~1; ++ break; ++ ++ case XK_Caps_Lock: ++ vs->shift_keys ^= 2; ++ break; ++ + case XK_1 ... XK_9: + if ((vs->ctl_keys & 3) != 3) + break; diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/vnc-numpad-handling --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/vnc-numpad-handling Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,236 @@ +# HG changeset patch +# User Ewan Mellor <ewan@xxxxxxxxxxxxx> +# Node ID c7f4a89eb054a1ad411da1e4cdc8aeda1a98c4fa +# Parent 565cd8f32c70da8ae7dbaaeb9dff28aa8b6307e1 +Fix numpad handling in QEMU's VNC server. The keymaps that we have include +information on which keys change depending upon the numlock setting, but +this isn't being used. By forcing numlock on and off as necessary, when +receiving these keysyms through the VNC connection, we ensure that the +server's numlock status is the same as the client's. + +Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx> + +Index: ioemu/keymaps.c +=================================================================== +--- ioemu.orig/keymaps.c 2006-12-06 23:41:30.000000000 +0000 ++++ ioemu/keymaps.c 2006-12-08 18:20:27.000000000 +0000 +@@ -36,8 +36,10 @@ + #define MAX_EXTRA_COUNT 256 + typedef struct { + uint16_t keysym2keycode[MAX_NORMAL_KEYCODE]; ++ int keysym2numlock[MAX_NORMAL_KEYCODE]; + struct { + int keysym; ++ int numlock; + uint16_t keycode; + } keysym2keycode_extra[MAX_EXTRA_COUNT]; + int extra_count; +@@ -50,6 +52,8 @@ + char file_name[1024]; + char line[1024]; + int len; ++ int *keycode2numlock; ++ int i; + + snprintf(file_name, sizeof(file_name), + "%s/keymaps/%s", bios_dir, language); +@@ -63,6 +67,15 @@ + "Could not read keymap file: '%s'\n", file_name); + return 0; + } ++ ++ /* Allocate a temporary map tracking which keycodes change when numlock is ++ set. Keycodes are 16 bit, so 65536 is safe. */ ++ keycode2numlock = malloc(65536 * sizeof(int)); ++ if (!keycode2numlock) { ++ perror("Could not read keymap file"); ++ return 0; ++ } ++ + for(;;) { + if (fgets(line, 1024, f) == NULL) + break; +@@ -86,13 +99,19 @@ + if (keysym == 0) { + // fprintf(stderr, "Warning: unknown keysym %s\n", line); + } else { +- const char *rest = end_of_keysym + 1; +- int keycode = strtol(rest, NULL, 0); ++ char *rest = end_of_keysym + 1; ++ int keycode = strtol(rest, &rest, 0); ++ int numlock = (rest != NULL && ++ strstr(rest, "numlock") != NULL); ++ ++ keycode2numlock[keycode] = numlock; ++ + /* if(keycode&0x80) + keycode=(keycode<<8)^0x80e0; */ + if (keysym < MAX_NORMAL_KEYCODE) { + //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode); + k->keysym2keycode[keysym] = keycode; ++ k->keysym2numlock[keysym] = numlock; + } else { + if (k->extra_count >= MAX_EXTRA_COUNT) { + fprintf(stderr, +@@ -107,6 +126,8 @@ + keysym = keysym; + k->keysym2keycode_extra[k->extra_count]. + keycode = keycode; ++ k->keysym2keycode_extra[k->extra_count]. ++ numlock = numlock; + k->extra_count++; + } + } +@@ -115,6 +136,22 @@ + } + } + fclose(f); ++ ++ for (i = 0; i < MAX_NORMAL_KEYCODE; i++) { ++ if (k->keysym2numlock[i] != 1) { ++ k->keysym2numlock[i] = -keycode2numlock[k->keysym2keycode[i]]; ++ } ++ } ++ ++ for (i = 0; i < k->extra_count; i++) { ++ if (k->keysym2keycode_extra[i].numlock != 1) { ++ k->keysym2keycode_extra[i].numlock = ++ -keycode2numlock[k->keysym2keycode_extra[i].keycode]; ++ } ++ } ++ ++ free(keycode2numlock); ++ + return k; + } + +@@ -143,3 +180,25 @@ + } + return 0; + } ++ ++/** ++ * Returns 1 if the given keysym requires numlock to be pressed, -1 if it ++ * requires it to be cleared, and 0 otherwise. ++ */ ++static int keysym2numlock(void *kbd_layout, int keysym) ++{ ++ kbd_layout_t *k = kbd_layout; ++ if (keysym < MAX_NORMAL_KEYCODE) { ++ return k->keysym2numlock[keysym]; ++ } else { ++ int i; ++#ifdef XK_ISO_Left_Tab ++ if (keysym == XK_ISO_Left_Tab) ++ keysym = XK_Tab; ++#endif ++ for (i = 0; i < k->extra_count; i++) ++ if (k->keysym2keycode_extra[i].keysym == keysym) ++ return k->keysym2keycode_extra[i].numlock; ++ } ++ return 0; ++} +Index: ioemu/vnc.c +=================================================================== +--- ioemu.orig/vnc.c 2006-12-08 18:18:26.000000000 +0000 ++++ ioemu/vnc.c 2006-12-08 18:19:43.000000000 +0000 +@@ -115,6 +115,7 @@ + + int ctl_keys; /* Ctrl+Alt starts calibration */ + int shift_keys; /* Shift / CapsLock keys */ ++ int numlock; + }; + + #define DIRTY_PIXEL_BITS 64 +@@ -854,14 +855,40 @@ + } + } + ++static void press_key(VncState *vs, int keycode) ++{ ++ kbd_put_keycode(keysym2scancode(vs->kbd_layout, keycode) & 0x7f); ++ kbd_put_keycode(keysym2scancode(vs->kbd_layout, keycode) | 0x80); ++} ++ + static void do_key_event(VncState *vs, int down, uint32_t sym) + { + sym &= 0xFFFF; + + if (is_graphic_console()) { + int keycode; ++ int numlock; + + keycode = keysym2scancode(vs->kbd_layout, sym); ++ numlock = keysym2numlock(vs->kbd_layout, sym); ++ ++ /* If the numlock state needs to change then simulate an additional ++ keypress before sending this one. This will happen if the user ++ toggles numlock away from the VNC window. ++ */ ++ if (numlock == 1) { ++ if (!vs->numlock) { ++ vs->numlock = 1; ++ press_key(vs, XK_Num_Lock); ++ } ++ } ++ else if (numlock == -1) { ++ if (vs->numlock) { ++ vs->numlock = 0; ++ press_key(vs, XK_Num_Lock); ++ } ++ } ++ + if (keycode & 0x80) + kbd_put_keycode(0xe0); + if (down) +@@ -932,6 +959,10 @@ + vs->shift_keys ^= 2; + break; + ++ case XK_Num_Lock: ++ vs->numlock = !vs->numlock; ++ break; ++ + case XK_1 ... XK_9: + if ((vs->ctl_keys & 3) != 3) + break; +@@ -1355,6 +1386,7 @@ + vs->lsock = -1; + vs->csock = -1; + vs->depth = 4; ++ vs->numlock = 0; + + vs->ds = ds; + +Index: ioemu/vnc_keysym.h +=================================================================== +--- ioemu.orig/vnc_keysym.h 2006-12-08 18:17:01.000000000 +0000 ++++ ioemu/vnc_keysym.h 2006-12-08 18:19:43.000000000 +0000 +@@ -231,6 +231,19 @@ + {"Home", 0xff50}, /* XK_Home */ + {"End", 0xff57}, /* XK_End */ + {"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */ ++{"KP_Home", 0xff95}, ++{"KP_Left", 0xff96}, ++{"KP_Up", 0xff97}, ++{"KP_Right", 0xff98}, ++{"KP_Down", 0xff99}, ++{"KP_Prior", 0xff9a}, ++{"KP_Page_Up", 0xff9a}, ++{"KP_Next", 0xff9b}, ++{"KP_Page_Down", 0xff9b}, ++{"KP_End", 0xff9c}, ++{"KP_Begin", 0xff9d}, ++{"KP_Insert", 0xff9e}, ++{"KP_Delete", 0xff9f}, + {"F1", 0xffbe}, /* XK_F1 */ + {"F2", 0xffbf}, /* XK_F2 */ + {"F3", 0xffc0}, /* XK_F3 */ +@@ -258,6 +271,7 @@ + {"KP_8", 0xffb8}, /* XK_KP_8 */ + {"KP_9", 0xffb9}, /* XK_KP_9 */ + {"KP_Add", 0xffab}, /* XK_KP_Add */ ++{"KP_Separator", 0xffac},/* XK_KP_Separator */ + {"KP_Decimal", 0xffae}, /* XK_KP_Decimal */ + {"KP_Divide", 0xffaf}, /* XK_KP_Divide */ + {"KP_Enter", 0xff8d}, /* XK_KP_Enter */ diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xen-mapcache --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/xen-mapcache Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,300 @@ +# HG changeset patch +# User kfraser@xxxxxxxxxxxxxxxxxxxxx +# Node ID 67a06a9b7b1dca707e1cd3b08ae0a341d6e97b3d +# Parent 3f0ca90351e268084fbdb733d70fc596cb46537d +[HVM] qemu: Add guest address-space mapping cache. + +On IA32 host or IA32 PAE host, at present, generally, we can't create +an HVM guest with more than 2G memory, because generally it's almost +impossible for Qemu to find a large enough and consecutive virtual +address space to map an HVM guest's whole physical address space. +The attached patch fixes this issue using dynamic mapping based on +little blocks of memory. + +Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx> +Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx> +Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> + +diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/target-i386-dm/cpu.h +--- a/tools/ioemu/target-i386-dm/cpu.h Thu Dec 07 10:54:43 2006 +0000 ++++ b/tools/ioemu/target-i386-dm/cpu.h Thu Dec 07 11:12:52 2006 +0000 +@@ -25,7 +25,8 @@ + #ifdef TARGET_X86_64 + #define TARGET_LONG_BITS 64 + #else +-#define TARGET_LONG_BITS 32 ++/* #define TARGET_LONG_BITS 32 */ ++#define TARGET_LONG_BITS 64 /* for Qemu map cache */ + #endif + + /* target supports implicit self modifying code */ +diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/target-i386-dm/exec-dm.c +--- a/tools/ioemu/target-i386-dm/exec-dm.c Thu Dec 07 10:54:43 2006 +0000 ++++ b/tools/ioemu/target-i386-dm/exec-dm.c Thu Dec 07 11:12:52 2006 +0000 +@@ -36,6 +36,7 @@ + + #include "cpu.h" + #include "exec-all.h" ++#include "vl.h" + + //#define DEBUG_TB_INVALIDATE + //#define DEBUG_FLUSH +@@ -426,6 +427,12 @@ static inline int paddr_is_ram(target_ph + #endif + } + ++#if defined(__i386__) || defined(__x86_64__) ++#define phys_ram_addr(x) (qemu_map_cache(x)) ++#elif defined(__ia64__) ++#define phys_ram_addr(x) (phys_ram_base + (x)) ++#endif ++ + void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write) + { +@@ -438,7 +445,7 @@ void cpu_physical_memory_rw(target_phys_ + l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); + if (l > len) + l = len; +- ++ + io_index = iomem_index(addr); + if (is_write) { + if (io_index) { +@@ -460,9 +467,10 @@ void cpu_physical_memory_rw(target_phys_ + } + } else if (paddr_is_ram(addr)) { + /* Reading from RAM */ +- memcpy(phys_ram_base + addr, buf, l); ++ ptr = phys_ram_addr(addr); ++ memcpy(ptr, buf, l); + #ifdef __ia64__ +- sync_icache((unsigned long)(phys_ram_base + addr), l); ++ sync_icache(ptr, l); + #endif + } + } else { +@@ -485,7 +493,8 @@ void cpu_physical_memory_rw(target_phys_ + } + } else if (paddr_is_ram(addr)) { + /* Reading from RAM */ +- memcpy(buf, phys_ram_base + addr, l); ++ ptr = phys_ram_addr(addr); ++ memcpy(buf, ptr, l); + } else { + /* Neither RAM nor known MMIO space */ + memset(buf, 0xff, len); +diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/vl.c +--- a/tools/ioemu/vl.c Thu Dec 07 10:54:43 2006 +0000 ++++ b/tools/ioemu/vl.c Thu Dec 07 11:12:52 2006 +0000 +@@ -5807,6 +5807,92 @@ int set_mm_mapping(int xc_handle, uint32 + + return 0; + } ++ ++#if defined(__i386__) || defined(__x86_64__) ++static struct map_cache *mapcache_entry; ++static unsigned long nr_buckets; ++ ++static int qemu_map_cache_init(unsigned long nr_pages) ++{ ++ unsigned long max_pages = MAX_MCACHE_SIZE >> PAGE_SHIFT; ++ int i; ++ ++ if (nr_pages < max_pages) ++ max_pages = nr_pages; ++ ++ nr_buckets = (max_pages << PAGE_SHIFT) >> MCACHE_BUCKET_SHIFT; ++ ++ fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets); ++ ++ mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache)); ++ if (mapcache_entry == NULL) { ++ errno = ENOMEM; ++ return -1; ++ } ++ ++ memset(mapcache_entry, 0, nr_buckets * sizeof(struct map_cache)); ++ ++ /* ++ * To avoid ENOMEM from xc_map_foreign_batch() at runtime, we ++ * pre-fill all the map caches in advance. ++ */ ++ for (i = 0; i < nr_buckets; i++) ++ (void)qemu_map_cache(((target_phys_addr_t)i) << MCACHE_BUCKET_SHIFT); ++ ++ return 0; ++} ++ ++uint8_t *qemu_map_cache(target_phys_addr_t phys_addr) ++{ ++ struct map_cache *entry; ++ unsigned long address_index = phys_addr >> MCACHE_BUCKET_SHIFT; ++ unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1); ++ ++ /* For most cases (>99.9%), the page address is the same. */ ++ static unsigned long last_address_index = ~0UL; ++ static uint8_t *last_address_vaddr; ++ ++ if (address_index == last_address_index) ++ return last_address_vaddr + address_offset; ++ ++ entry = &mapcache_entry[address_index % nr_buckets]; ++ ++ if (entry->vaddr_base == NULL || entry->paddr_index != address_index) ++ { ++ /* We need to remap a bucket. */ ++ uint8_t *vaddr_base; ++ unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT]; ++ unsigned int i; ++ ++ if (entry->vaddr_base != NULL) { ++ errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE); ++ if (errno) { ++ fprintf(logfile, "unmap fails %d\n", errno); ++ exit(-1); ++ } ++ } ++ ++ for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++) ++ pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i; ++ ++ vaddr_base = xc_map_foreign_batch( ++ xc_handle, domid, PROT_READ|PROT_WRITE, ++ pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT); ++ if (vaddr_base == NULL) { ++ fprintf(logfile, "xc_map_foreign_batch error %d\n", errno); ++ exit(-1); ++ } ++ ++ entry->vaddr_base = vaddr_base; ++ entry->paddr_index = address_index;; ++ } ++ ++ last_address_index = address_index; ++ last_address_vaddr = entry->vaddr_base; ++ ++ return last_address_vaddr + address_offset; ++} ++#endif + + int main(int argc, char **argv) + { +@@ -6130,6 +6216,7 @@ int main(int argc, char **argv) + break; + case QEMU_OPTION_m: + ram_size = atol(optarg) * 1024 * 1024; ++ ram_size = (uint64_t)atol(optarg) * 1024 * 1024; + if (ram_size <= 0) + help(); + #ifndef CONFIG_DM +@@ -6400,50 +6487,41 @@ int main(int argc, char **argv) + shared_page_nr = nr_pages - 1; + #endif + ++#if defined(__i386__) || defined(__x86_64__) ++ ++ if ( qemu_map_cache_init(tmp_nr_pages) ) ++ { ++ fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno); ++ exit(-1); ++ } ++ ++ shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, ++ PROT_READ|PROT_WRITE, shared_page_nr); ++ if (shared_page == NULL) { ++ fprintf(logfile, "map shared IO page returned error %d\n", errno); ++ exit(-1); ++ } ++ ++ fprintf(logfile, "shared page at pfn:%lx\n", shared_page_nr); ++ ++ buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, ++ PROT_READ|PROT_WRITE, ++ shared_page_nr - 2); ++ if (buffered_io_page == NULL) { ++ fprintf(logfile, "map buffered IO page returned error %d\n", errno); ++ exit(-1); ++ } ++ ++ fprintf(logfile, "buffered io page at pfn:%lx\n", shared_page_nr - 2); ++ ++#elif defined(__ia64__) ++ + page_array = (xen_pfn_t *)malloc(tmp_nr_pages * sizeof(xen_pfn_t)); + if (page_array == NULL) { + fprintf(logfile, "malloc returned error %d\n", errno); + exit(-1); + } + +-#if defined(__i386__) || defined(__x86_64__) +- for ( i = 0; i < tmp_nr_pages; i++) +- page_array[i] = i; +- +- phys_ram_base = xc_map_foreign_batch(xc_handle, domid, +- PROT_READ|PROT_WRITE, page_array, +- tmp_nr_pages); +- if (phys_ram_base == NULL) { +- fprintf(logfile, "batch map guest memory returned error %d\n", errno); +- exit(-1); +- } +- +- shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, +- PROT_READ|PROT_WRITE, +- page_array[shared_page_nr]); +- if (shared_page == NULL) { +- fprintf(logfile, "map shared IO page returned error %d\n", errno); +- exit(-1); +- } +- +- fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", +- shared_page_nr, (uint64_t)(page_array[shared_page_nr])); +- +- buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, +- PROT_READ|PROT_WRITE, +- page_array[shared_page_nr - 2]); +- if (buffered_io_page == NULL) { +- fprintf(logfile, "map buffered IO page returned error %d\n", errno); +- exit(-1); +- } +- +- fprintf(logfile, "buffered io page at pfn:%lx, mfn: %"PRIx64"\n", +- shared_page_nr - 2, (uint64_t)(page_array[shared_page_nr - 2])); +- +- free(page_array); +- +-#elif defined(__ia64__) +- + if (xc_ia64_get_pfn_list(xc_handle, domid, page_array, + IO_PAGE_START >> PAGE_SHIFT, 3) != 3) { + fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno); +diff -r 3f0ca90351e2 -r 67a06a9b7b1d tools/ioemu/vl.h +--- a/tools/ioemu/vl.h Thu Dec 07 10:54:43 2006 +0000 ++++ b/tools/ioemu/vl.h Thu Dec 07 11:12:52 2006 +0000 +@@ -156,6 +156,26 @@ extern void *shared_vram; + + extern FILE *logfile; + ++ ++#if defined(__i386__) || defined(__x86_64__) ++#if defined(__i386__) ++#define MAX_MCACHE_SIZE 0x40000000 /* 1GB max for x86 */ ++#define MCACHE_BUCKET_SHIFT 16 ++#elif defined(__x86_64__) ++#define MAX_MCACHE_SIZE 0x1000000000 /* 64GB max for x86_64 */ ++#define MCACHE_BUCKET_SHIFT 20 ++#endif ++ ++#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT) ++ ++struct map_cache { ++ unsigned long paddr_index; ++ uint8_t *vaddr_base; ++}; ++ ++uint8_t *qemu_map_cache(target_phys_addr_t phys_addr); ++#endif ++ + extern int xc_handle; + extern int domid; + diff -r 1cfd862e5254 -r 8cddaee4a51c tools/ioemu/patches/xenstore-device-info-functions --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/patches/xenstore-device-info-functions Sat Dec 09 14:34:53 2006 +0000 @@ -0,0 +1,190 @@ +# HG changeset patch +# User kaf24@xxxxxxxxxxxxxxxxxxxxx +# Node ID bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2 +# Parent dc973fe5633386547ce5bc8fd4cf5f2bb5b55174 +[QEMU] Helper functions to interface with the xenstore and read device information from it. + + - detect what types of devices a domain has or whether a domain has a + device of a certain type + - read the content of a variable related to a device, i.e., + hotplug-status + - subscribe to changes of the hotplug status of a device for not + having to poll the status + +Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx> + +Index: ioemu/xenstore.c +=================================================================== +--- ioemu.orig/xenstore.c 2006-12-08 18:20:53.000000000 +0000 ++++ ioemu/xenstore.c 2006-12-08 18:20:53.000000000 +0000 +@@ -264,3 +264,140 @@ + + return rc; + } ++ ++ ++/* ++ * get all device instances of a certain type ++ */ ++char **xenstore_domain_get_devices(struct xs_handle *handle, ++ const char *devtype, unsigned int *num) ++{ ++ char *path; ++ char *buf = NULL; ++ char **e = NULL; ++ ++ path = xs_get_domain_path(handle, domid); ++ if (path == NULL) ++ goto out; ++ ++ if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1) ++ goto out; ++ ++ e = xs_directory(handle, XBT_NULL, buf, num); ++ ++ out: ++ free(path); ++ free(buf); ++ return e; ++} ++ ++/* ++ * Check whether a domain has devices of the given type ++ */ ++int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype) ++{ ++ int rc = 0; ++ unsigned int num; ++ char **e = xenstore_domain_get_devices(handle, devtype, &num); ++ if (e) ++ rc = 1; ++ free(e); ++ return rc; ++} ++ ++/* ++ * Function that creates a path to a variable of an instance of a ++ * certain device ++ */ ++static char *get_device_variable_path(const char *devtype, const char *inst, ++ const char *var) ++{ ++ char *buf = NULL; ++ if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s", ++ devtype, ++ domid, ++ inst, ++ var) == -1) { ++ free(buf); ++ buf = NULL; ++ } ++ return buf; ++} ++ ++char *xenstore_backend_read_variable(struct xs_handle *handle, ++ const char *devtype, const char *inst, ++ const char *var) ++{ ++ char *value = NULL; ++ char *buf = NULL; ++ unsigned int len; ++ ++ buf = get_device_variable_path(devtype, inst, var); ++ if (NULL == buf) ++ goto out; ++ ++ value = xs_read(handle, XBT_NULL, buf, &len); ++ ++ free(buf); ++ ++out: ++ return value; ++} ++ ++/* ++ Read the hotplug status variable from the backend given the type ++ of device and its instance. ++*/ ++char *xenstore_read_hotplug_status(struct xs_handle *handle, ++ const char *devtype, const char *inst) ++{ ++ return xenstore_backend_read_variable(handle, devtype, inst, ++ "hotplug-status"); ++} ++ ++/* ++ Subscribe to the hotplug status of a device given the type of device and ++ its instance. ++ In case an error occurrs, a negative number is returned. ++ */ ++int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle, ++ const char *devtype, ++ const char *inst, ++ const char *token) ++{ ++ int rc = 0; ++ char *path = get_device_variable_path(devtype, inst, "hotplug-status"); ++ ++ if (path == NULL) ++ return -1; ++ ++ if (0 == xs_watch(handle, path, token)) ++ rc = -2; ++ ++ free(path); ++ ++ return rc; ++} ++ ++/* ++ * Unsubscribe from a subscription to the status of a hotplug variable of ++ * a device. ++ */ ++int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle, ++ const char *devtype, ++ const char *inst, ++ const char *token) ++{ ++ int rc = 0; ++ char *path; ++ path = get_device_variable_path(devtype, inst, "hotplug-status"); ++ if (path == NULL) ++ return -1; ++ ++ if (0 == xs_unwatch(handle, path, token)) ++ rc = -2; ++ ++ free(path); ++ ++ return rc; ++} +Index: ioemu/vl.h +=================================================================== +--- ioemu.orig/vl.h 2006-12-08 18:20:53.000000000 +0000 ++++ ioemu/vl.h 2006-12-08 18:20:53.000000000 +0000 +@@ -1216,6 +1216,25 @@ + void xenstore_write_vncport(int vnc_display); + int xenstore_read_vncpasswd(int domid); + ++int xenstore_domain_has_devtype(struct xs_handle *handle, ++ const char *devtype); ++char **xenstore_domain_get_devices(struct xs_handle *handle, ++ const char *devtype, unsigned int *num); ++char *xenstore_read_hotplug_status(struct xs_handle *handle, ++ const char *devtype, const char *inst); ++char *xenstore_backend_read_variable(struct xs_handle *, ++ const char *devtype, const char *inst, ++ const char *var); ++int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle, ++ const char *devtype, ++ const char *inst, ++ const char *token); ++int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle, ++ const char *devtype, ++ const char *inst, ++ const char *token); ++ ++ + /* xen_platform.c */ + void pci_xen_platform_init(PCIBus *bus); + _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |