direct-io.hg

changeset 12814:c3ad3fcfe364

[qemu patches] Update patches upto changeset 12756:1d32fb45e0.

Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
author Christian Limpach <Christian.Limpach@xensource.com>
date Fri Dec 08 18:31:01 2006 +0000 (2006-12-08)
parents 7258a2009cfa
children 1ad7dff99968
files tools/ioemu/patches/acpi-support tools/ioemu/patches/acpi-timer-support tools/ioemu/patches/domain-destroy tools/ioemu/patches/domain-reset tools/ioemu/patches/domain-timeoffset tools/ioemu/patches/fix-interrupt-routing tools/ioemu/patches/hypervisor-pit tools/ioemu/patches/hypervisor-rtc tools/ioemu/patches/ide-error-reporting tools/ioemu/patches/ioemu-ia64 tools/ioemu/patches/limit-fdc-sector-size-to-16K tools/ioemu/patches/ne2000-bounds-checks tools/ioemu/patches/nodelay-serial-over-tcp tools/ioemu/patches/qemu-bootorder tools/ioemu/patches/qemu-daemonize tools/ioemu/patches/qemu-dm tools/ioemu/patches/qemu-no-apic tools/ioemu/patches/qemu-pci tools/ioemu/patches/qemu-serial-fixes tools/ioemu/patches/qemu-target-i386-dm tools/ioemu/patches/remove-pci-bridge-setup tools/ioemu/patches/rtl8139-bound-chaining tools/ioemu/patches/series tools/ioemu/patches/shared-vram tools/ioemu/patches/tpm-tis-device tools/ioemu/patches/usb-uhci-buffer-size tools/ioemu/patches/vnc-access-monitor-vt tools/ioemu/patches/vnc-backoff-screen-scan tools/ioemu/patches/vnc-display-find-unused tools/ioemu/patches/vnc-fixes tools/ioemu/patches/vnc-japan-keymap tools/ioemu/patches/vnc-listen-specific-interface tools/ioemu/patches/vnc-monitor-shift-key-processing tools/ioemu/patches/vnc-numpad-handling tools/ioemu/patches/vnc-password tools/ioemu/patches/vnc-protocol-fixes tools/ioemu/patches/vnc-start-vncviewer tools/ioemu/patches/vnc-title-domain-name tools/ioemu/patches/xen-build tools/ioemu/patches/xen-mm tools/ioemu/patches/xen-platform-device tools/ioemu/patches/xen-support-buffered-ioreqs tools/ioemu/patches/xenstore-block-device-config tools/ioemu/patches/xenstore-device-info-functions tools/ioemu/patches/xenstore-write-vnc-port
line diff
     1.1 --- a/tools/ioemu/patches/acpi-support	Fri Dec 08 07:22:21 2006 -0800
     1.2 +++ b/tools/ioemu/patches/acpi-support	Fri Dec 08 18:31:01 2006 +0000
     1.3 @@ -1,8 +1,8 @@
     1.4  Index: ioemu/Makefile.target
     1.5  ===================================================================
     1.6 ---- ioemu.orig/Makefile.target	2006-08-17 19:49:50.228216099 +0100
     1.7 -+++ ioemu/Makefile.target	2006-08-17 19:50:02.405870095 +0100
     1.8 -@@ -357,6 +357,7 @@
     1.9 +--- ioemu.orig/Makefile.target	2006-12-08 02:00:40.000000000 +0000
    1.10 ++++ ioemu/Makefile.target	2006-12-08 02:00:40.000000000 +0000
    1.11 +@@ -358,6 +358,7 @@
    1.12   VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
    1.13   VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
    1.14   VL_OBJS+= usb-uhci.o
    1.15 @@ -12,8 +12,8 @@ Index: ioemu/Makefile.target
    1.16   ifeq ($(TARGET_BASE_ARCH), ppc)
    1.17  Index: ioemu/hw/pc.c
    1.18  ===================================================================
    1.19 ---- ioemu.orig/hw/pc.c	2006-08-17 19:49:59.312212039 +0100
    1.20 -+++ ioemu/hw/pc.c	2006-08-17 19:50:02.406869984 +0100
    1.21 +--- ioemu.orig/hw/pc.c	2006-12-08 02:00:40.000000000 +0000
    1.22 ++++ ioemu/hw/pc.c	2006-12-08 02:00:40.000000000 +0000
    1.23  @@ -874,13 +874,19 @@
    1.24   
    1.25       cmos_init(ram_size, boot_device, bs_table, timeoffset);
    1.26 @@ -49,8 +49,8 @@ Index: ioemu/hw/pc.c
    1.27  Index: ioemu/hw/piix4acpi.c
    1.28  ===================================================================
    1.29  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
    1.30 -+++ ioemu/hw/piix4acpi.c	2006-08-17 19:50:02.407869874 +0100
    1.31 -@@ -0,0 +1,388 @@
    1.32 ++++ ioemu/hw/piix4acpi.c	2006-12-08 02:00:40.000000000 +0000
    1.33 +@@ -0,0 +1,396 @@
    1.34  +/*
    1.35  + * PIIX4 ACPI controller emulation
    1.36  + *
    1.37 @@ -434,15 +434,23 @@ Index: ioemu/hw/piix4acpi.c
    1.38  +    pci_conf[0x0e] = 0x00;
    1.39  +    pci_conf[0x3d] = 0x01;  /* Hardwired to PIRQA is used */
    1.40  +
    1.41 -+    pci_register_io_region((PCIDevice *)d, 4, 0x10,
    1.42 -+                           PCI_ADDRESS_SPACE_IO, acpi_map);
    1.43  +
    1.44 -+    acpi_reset (d);
    1.45 ++    /* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40 
    1.46 ++     * to make shutdown work for IPF, due to IPF Guest Firmware 
    1.47 ++     * will enumerate pci devices. 
    1.48 ++     *
    1.49 ++     * TODO:  if Guest Firmware or Guest OS will change this PMBA,
    1.50 ++     * More logic will be added.
    1.51 ++     */
    1.52 ++    pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
    1.53 ++    pci_conf[0x41] = 0x1f;
    1.54 ++    acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
    1.55 ++    acpi_reset(d);
    1.56  +}
    1.57  Index: ioemu/vl.c
    1.58  ===================================================================
    1.59 ---- ioemu.orig/vl.c	2006-08-17 19:49:59.315211708 +0100
    1.60 -+++ ioemu/vl.c	2006-08-17 19:50:02.410869542 +0100
    1.61 +--- ioemu.orig/vl.c	2006-12-08 02:00:40.000000000 +0000
    1.62 ++++ ioemu/vl.c	2006-12-08 02:00:40.000000000 +0000
    1.63  @@ -156,7 +156,7 @@
    1.64   #else
    1.65   #define MAX_CPUS 1
    1.66 @@ -476,7 +484,7 @@ Index: ioemu/vl.c
    1.67       { NULL },
    1.68   };
    1.69   
    1.70 -@@ -6256,6 +6259,9 @@
    1.71 +@@ -6240,6 +6243,9 @@
    1.72               case QEMU_OPTION_timeoffset:
    1.73                   timeoffset = strtol(optarg, NULL, 0);
    1.74                   break;
    1.75 @@ -488,8 +496,8 @@ Index: ioemu/vl.c
    1.76       }
    1.77  Index: ioemu/vl.h
    1.78  ===================================================================
    1.79 ---- ioemu.orig/vl.h	2006-08-17 19:49:59.316211597 +0100
    1.80 -+++ ioemu/vl.h	2006-08-17 19:50:02.411869432 +0100
    1.81 +--- ioemu.orig/vl.h	2006-12-08 02:00:40.000000000 +0000
    1.82 ++++ ioemu/vl.h	2006-12-08 02:00:40.000000000 +0000
    1.83  @@ -168,6 +168,7 @@
    1.84   extern int kqemu_allowed;
    1.85   extern int win2k_install_hack;
    1.86 @@ -510,8 +518,8 @@ Index: ioemu/vl.h
    1.87   extern QEMUMachine isapc_machine;
    1.88  Index: ioemu/hw/piix_pci.c
    1.89  ===================================================================
    1.90 ---- ioemu.orig/hw/piix_pci.c	2006-08-17 19:38:05.806252180 +0100
    1.91 -+++ ioemu/hw/piix_pci.c	2006-08-17 19:50:02.411869432 +0100
    1.92 +--- ioemu.orig/hw/piix_pci.c	2006-12-08 02:00:39.000000000 +0000
    1.93 ++++ ioemu/hw/piix_pci.c	2006-12-08 02:00:40.000000000 +0000
    1.94  @@ -241,7 +241,7 @@
    1.95   static uint32_t pci_bios_io_addr;
    1.96   static uint32_t pci_bios_mem_addr;
    1.97 @@ -521,33 +529,22 @@ Index: ioemu/hw/piix_pci.c
    1.98   
    1.99   static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
   1.100   {
   1.101 -@@ -336,6 +336,14 @@
   1.102 +@@ -336,6 +336,18 @@
   1.103               pci_set_io_region_addr(d, 3, 0x374);
   1.104           }
   1.105           break;
   1.106  +    case 0x0680:
   1.107  +        if (vendor_id == 0x8086 && device_id == 0x7113) {
   1.108 -+            /* PIIX4 ACPI PM */
   1.109 -+            pci_config_writew(d, 0x20, 0x0000); /* NO smb bus IO enable in PIIX4 */
   1.110 ++            /*
   1.111 ++             * PIIX4 ACPI PM.
   1.112 ++             * Special device with special PCI config space. No ordinary BARs.
   1.113 ++             */
   1.114 ++            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
   1.115  +            pci_config_writew(d, 0x22, 0x0000);
   1.116 -+            goto default_map;
   1.117 ++            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
   1.118 ++            pci_config_writew(d, 0x3d, 0x0001);
   1.119  +        }
   1.120  +        break;
   1.121       case 0x0300:
   1.122           if (vendor_id != 0x1234)
   1.123               goto default_map;
   1.124 -@@ -386,6 +394,14 @@
   1.125 -         pic_irq = pci_irqs[pin];
   1.126 -         pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
   1.127 -     }
   1.128 -+
   1.129 -+    if (class== 0x0680&& vendor_id == 0x8086 && device_id == 0x7113) {
   1.130 -+         // PIIX4 ACPI PM
   1.131 -+       pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
   1.132 -+       pci_config_writew(d, 0x22, 0x0000);
   1.133 -+       pci_config_writew(d, 0x3c, 0x0009); // Hardcodeed IRQ9
   1.134 -+       pci_config_writew(d, 0x3d, 0x0001);
   1.135 -+    }
   1.136 - }
   1.137 - 
   1.138 - /*
     2.1 --- a/tools/ioemu/patches/acpi-timer-support	Fri Dec 08 07:22:21 2006 -0800
     2.2 +++ b/tools/ioemu/patches/acpi-timer-support	Fri Dec 08 18:31:01 2006 +0000
     2.3 @@ -1,7 +1,7 @@
     2.4  Index: ioemu/hw/piix4acpi.c
     2.5  ===================================================================
     2.6 ---- ioemu.orig/hw/piix4acpi.c	2006-08-17 19:50:02.407869874 +0100
     2.7 -+++ ioemu/hw/piix4acpi.c	2006-08-17 19:50:05.060576667 +0100
     2.8 +--- ioemu.orig/hw/piix4acpi.c	2006-12-08 01:35:52.000000000 +0000
     2.9 ++++ ioemu/hw/piix4acpi.c	2006-12-08 01:35:59.000000000 +0000
    2.10  @@ -24,31 +24,30 @@
    2.11    */
    2.12   
    2.13 @@ -186,10 +186,3 @@ Index: ioemu/hw/piix4acpi.c
    2.14   
    2.15   /* PIIX4 acpi pci configuration space, func 2 */
    2.16   void pci_piix4_acpi_init(PCIBus *bus, int devfn)
    2.17 -@@ -384,5 +383,5 @@
    2.18 -     pci_register_io_region((PCIDevice *)d, 4, 0x10,
    2.19 -                            PCI_ADDRESS_SPACE_IO, acpi_map);
    2.20 - 
    2.21 --    acpi_reset (d);
    2.22 -+    acpi_reset(d);
    2.23 - }
     3.1 --- a/tools/ioemu/patches/domain-destroy	Fri Dec 08 07:22:21 2006 -0800
     3.2 +++ b/tools/ioemu/patches/domain-destroy	Fri Dec 08 18:31:01 2006 +0000
     3.3 @@ -1,7 +1,7 @@
     3.4  Index: ioemu/monitor.c
     3.5  ===================================================================
     3.6 ---- ioemu.orig/monitor.c	2006-08-17 19:37:36.489509621 +0100
     3.7 -+++ ioemu/monitor.c	2006-08-17 19:49:44.491850141 +0100
     3.8 +--- ioemu.orig/monitor.c	2006-12-08 01:26:07.000000000 +0000
     3.9 ++++ ioemu/monitor.c	2006-12-08 01:26:08.000000000 +0000
    3.10  @@ -308,6 +308,7 @@
    3.11   
    3.12   static void do_quit(void)
    3.13 @@ -12,11 +12,11 @@ Index: ioemu/monitor.c
    3.14   
    3.15  Index: ioemu/target-i386-dm/helper2.c
    3.16  ===================================================================
    3.17 ---- ioemu.orig/target-i386-dm/helper2.c	2006-08-17 19:49:40.116333768 +0100
    3.18 -+++ ioemu/target-i386-dm/helper2.c	2006-08-17 19:49:44.491850141 +0100
    3.19 -@@ -488,5 +488,25 @@
    3.20 -             xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
    3.21 -         }
    3.22 +--- ioemu.orig/target-i386-dm/helper2.c	2006-12-08 01:26:08.000000000 +0000
    3.23 ++++ ioemu/target-i386-dm/helper2.c	2006-12-08 01:26:08.000000000 +0000
    3.24 +@@ -507,5 +507,25 @@
    3.25 +         /* Wait up to 10 msec. */
    3.26 +         main_loop_wait(10);
    3.27       }
    3.28  +    destroy_hvm_domain();
    3.29       return 0;
    3.30 @@ -42,8 +42,8 @@ Index: ioemu/target-i386-dm/helper2.c
    3.31  +}
    3.32  Index: ioemu/vl.h
    3.33  ===================================================================
    3.34 ---- ioemu.orig/vl.h	2006-08-17 19:49:40.120333326 +0100
    3.35 -+++ ioemu/vl.h	2006-08-17 19:49:44.492850031 +0100
    3.36 +--- ioemu.orig/vl.h	2006-12-08 01:26:08.000000000 +0000
    3.37 ++++ ioemu/vl.h	2006-12-08 01:26:08.000000000 +0000
    3.38  @@ -1190,4 +1190,7 @@
    3.39   void kqemu_record_dump(void);
    3.40   
     4.1 --- a/tools/ioemu/patches/domain-reset	Fri Dec 08 07:22:21 2006 -0800
     4.2 +++ b/tools/ioemu/patches/domain-reset	Fri Dec 08 18:31:01 2006 +0000
     4.3 @@ -1,7 +1,7 @@
     4.4  Index: ioemu/target-i386-dm/helper2.c
     4.5  ===================================================================
     4.6 ---- ioemu.orig/target-i386-dm/helper2.c	2006-08-17 19:37:36.530505066 +0100
     4.7 -+++ ioemu/target-i386-dm/helper2.c	2006-08-17 19:49:40.116333768 +0100
     4.8 +--- ioemu.orig/target-i386-dm/helper2.c	2006-12-08 01:26:06.000000000 +0000
     4.9 ++++ ioemu/target-i386-dm/helper2.c	2006-12-08 01:26:08.000000000 +0000
    4.10  @@ -127,6 +127,25 @@
    4.11   /* called from main_cpu_reset */
    4.12   void cpu_reset(CPUX86State *env)
    4.13 @@ -28,7 +28,7 @@ Index: ioemu/target-i386-dm/helper2.c
    4.14   }
    4.15   
    4.16   void cpu_x86_close(CPUX86State *env)
    4.17 -@@ -455,6 +474,10 @@
    4.18 +@@ -479,6 +498,10 @@
    4.19           if (vm_running) {
    4.20               if (shutdown_requested)
    4.21                   break;
    4.22 @@ -41,8 +41,8 @@ Index: ioemu/target-i386-dm/helper2.c
    4.23           /* Wait up to 10 msec. */
    4.24  Index: ioemu/vl.c
    4.25  ===================================================================
    4.26 ---- ioemu.orig/vl.c	2006-08-17 19:49:39.442408257 +0100
    4.27 -+++ ioemu/vl.c	2006-08-17 19:49:40.119333436 +0100
    4.28 +--- ioemu.orig/vl.c	2006-12-08 01:26:08.000000000 +0000
    4.29 ++++ ioemu/vl.c	2006-12-08 01:26:08.000000000 +0000
    4.30  @@ -4948,7 +4948,7 @@
    4.31   } QEMUResetEntry;
    4.32   
    4.33 @@ -54,8 +54,8 @@ Index: ioemu/vl.c
    4.34   
    4.35  Index: ioemu/vl.h
    4.36  ===================================================================
    4.37 ---- ioemu.orig/vl.h	2006-08-17 19:47:32.680418959 +0100
    4.38 -+++ ioemu/vl.h	2006-08-17 19:49:40.120333326 +0100
    4.39 +--- ioemu.orig/vl.h	2006-12-08 01:26:07.000000000 +0000
    4.40 ++++ ioemu/vl.h	2006-12-08 01:26:08.000000000 +0000
    4.41  @@ -131,6 +131,7 @@
    4.42   
    4.43   void qemu_register_reset(QEMUResetHandler *func, void *opaque);
     5.1 --- a/tools/ioemu/patches/domain-timeoffset	Fri Dec 08 07:22:21 2006 -0800
     5.2 +++ b/tools/ioemu/patches/domain-timeoffset	Fri Dec 08 18:31:01 2006 +0000
     5.3 @@ -1,7 +1,7 @@
     5.4  Index: ioemu/hw/mc146818rtc.c
     5.5  ===================================================================
     5.6 ---- ioemu.orig/hw/mc146818rtc.c	2006-10-24 14:45:21.000000000 +0100
     5.7 -+++ ioemu/hw/mc146818rtc.c	2006-10-24 14:45:39.000000000 +0100
     5.8 +--- ioemu.orig/hw/mc146818rtc.c	2006-12-08 18:23:40.000000000 +0000
     5.9 ++++ ioemu/hw/mc146818rtc.c	2006-12-08 18:23:46.000000000 +0000
    5.10  @@ -178,10 +178,27 @@
    5.11       }
    5.12   }
    5.13 @@ -46,8 +46,8 @@ Index: ioemu/hw/mc146818rtc.c
    5.14   static void rtc_copy_date(RTCState *s)
    5.15  Index: ioemu/hw/pc.c
    5.16  ===================================================================
    5.17 ---- ioemu.orig/hw/pc.c	2006-10-24 14:45:38.000000000 +0100
    5.18 -+++ ioemu/hw/pc.c	2006-10-24 14:45:39.000000000 +0100
    5.19 +--- ioemu.orig/hw/pc.c	2006-12-08 18:23:46.000000000 +0000
    5.20 ++++ ioemu/hw/pc.c	2006-12-08 18:23:46.000000000 +0000
    5.21  @@ -159,7 +159,7 @@
    5.22   }
    5.23   
    5.24 @@ -117,8 +117,8 @@ Index: ioemu/hw/pc.c
    5.25   QEMUMachine pc_machine = {
    5.26  Index: ioemu/vl.c
    5.27  ===================================================================
    5.28 ---- ioemu.orig/vl.c	2006-10-24 14:45:38.000000000 +0100
    5.29 -+++ ioemu/vl.c	2006-10-24 14:45:39.000000000 +0100
    5.30 +--- ioemu.orig/vl.c	2006-12-08 18:23:46.000000000 +0000
    5.31 ++++ ioemu/vl.c	2006-12-08 18:23:46.000000000 +0000
    5.32  @@ -163,6 +163,8 @@
    5.33   
    5.34   int xc_handle;
    5.35 @@ -152,7 +152,7 @@ Index: ioemu/vl.c
    5.36       { NULL },
    5.37   };
    5.38   
    5.39 -@@ -6248,6 +6253,9 @@
    5.40 +@@ -6232,6 +6237,9 @@
    5.41                   vcpus = atoi(optarg);
    5.42                   fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
    5.43                   break;
    5.44 @@ -162,7 +162,7 @@ Index: ioemu/vl.c
    5.45               }
    5.46           }
    5.47       }
    5.48 -@@ -6507,7 +6515,8 @@
    5.49 +@@ -6492,7 +6500,8 @@
    5.50   
    5.51       machine->init(ram_size, vga_ram_size, boot_device,
    5.52                     ds, fd_filename, snapshot,
    5.53 @@ -174,8 +174,8 @@ Index: ioemu/vl.c
    5.54       if (usb_enabled) {
    5.55  Index: ioemu/vl.h
    5.56  ===================================================================
    5.57 ---- ioemu.orig/vl.h	2006-10-24 14:45:38.000000000 +0100
    5.58 -+++ ioemu/vl.h	2006-10-24 14:45:39.000000000 +0100
    5.59 +--- ioemu.orig/vl.h	2006-12-08 18:23:46.000000000 +0000
    5.60 ++++ ioemu/vl.h	2006-12-08 18:23:46.000000000 +0000
    5.61  @@ -576,7 +576,7 @@
    5.62                                    int boot_device,
    5.63                DisplayState *ds, const char **fd_filename, int snapshot,
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/ioemu/patches/fix-interrupt-routing	Fri Dec 08 18:31:01 2006 +0000
     6.3 @@ -0,0 +1,459 @@
     6.4 +# HG changeset patch
     6.5 +# User kfraser@localhost.localdomain
     6.6 +# Node ID f555a90bcc373a7379bc18f875eac5e7c7122ae9
     6.7 +# Parent  b80f00215bbaf2050765e557f1a017a71e1e8529
     6.8 +[HVM] Reworked interrupt distribution logic.
     6.9 +
    6.10 +TODO:
    6.11 + 1. Fix IO-APIC ID to not conflict with LAPIC IDS.
    6.12 + 2. Fix i8259 device model (seems to work already though!).
    6.13 + 3. Add INTSRC overrides in MPBIOS and ACPI tables so
    6.14 +    that PCI legacy IRQ routing always ends up at an
    6.15 +    IO-APIC input with level trigger. Restricting link
    6.16 +    routing to {5,6,10,11} and setting overrides for all
    6.17 +    four of those would work.
    6.18 +
    6.19 +Signed-off-by: Keir Fraser <keir@xensource.com>
    6.20 +
    6.21 +Index: ioemu/Makefile.target
    6.22 +===================================================================
    6.23 +--- ioemu.orig/Makefile.target	2006-12-08 18:21:56.000000000 +0000
    6.24 ++++ ioemu/Makefile.target	2006-12-08 18:22:35.000000000 +0000
    6.25 +@@ -298,7 +298,7 @@
    6.26 + ifeq ($(ARCH),ia64)
    6.27 + LIBOBJS=helper2.o exec-dm.o i8259-dm.o
    6.28 + else
    6.29 +-LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o
    6.30 ++LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o
    6.31 + endif
    6.32 + 
    6.33 + all: $(PROGS)
    6.34 +@@ -360,11 +360,11 @@
    6.35 + # Hardware support
    6.36 + VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    6.37 + ifeq ($(ARCH),ia64)
    6.38 +-VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
    6.39 ++VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o piix_pci.o
    6.40 + else
    6.41 + VL_OBJS+= fdc.o serial.o pc.o
    6.42 + endif
    6.43 +-VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
    6.44 ++VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o
    6.45 + VL_OBJS+= usb-uhci.o
    6.46 + VL_OBJS+= piix4acpi.o
    6.47 + VL_OBJS+= xenstore.o
    6.48 +Index: ioemu/target-i386-dm/i8259-dm.c
    6.49 +===================================================================
    6.50 +--- ioemu.orig/target-i386-dm/i8259-dm.c	2006-12-08 18:21:36.000000000 +0000
    6.51 ++++ ioemu/target-i386-dm/i8259-dm.c	2006-12-08 18:22:35.000000000 +0000
    6.52 +@@ -33,7 +33,7 @@
    6.53 + 
    6.54 + void pic_set_irq_new(void *opaque, int irq, int level)
    6.55 + {
    6.56 +-    xc_hvm_set_irq_level(xc_handle, domid, irq, level);
    6.57 ++    xc_hvm_set_isa_irq_level(xc_handle, domid, irq, level);
    6.58 + }
    6.59 + 
    6.60 + /* obsolete function */
    6.61 +Index: ioemu/target-i386-dm/piix_pci-dm.c
    6.62 +===================================================================
    6.63 +--- /dev/null	1970-01-01 00:00:00.000000000 +0000
    6.64 ++++ ioemu/target-i386-dm/piix_pci-dm.c	2006-12-08 18:22:35.000000000 +0000
    6.65 +@@ -0,0 +1,397 @@
    6.66 ++/*
    6.67 ++ * QEMU i440FX/PIIX3 PCI Bridge Emulation
    6.68 ++ *
    6.69 ++ * Copyright (c) 2006 Fabrice Bellard
    6.70 ++ * 
    6.71 ++ * Permission is hereby granted, free of charge, to any person obtaining a copy
    6.72 ++ * of this software and associated documentation files (the "Software"), to deal
    6.73 ++ * in the Software without restriction, including without limitation the rights
    6.74 ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    6.75 ++ * copies of the Software, and to permit persons to whom the Software is
    6.76 ++ * furnished to do so, subject to the following conditions:
    6.77 ++ *
    6.78 ++ * The above copyright notice and this permission notice shall be included in
    6.79 ++ * all copies or substantial portions of the Software.
    6.80 ++ *
    6.81 ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    6.82 ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    6.83 ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    6.84 ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    6.85 ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    6.86 ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    6.87 ++ * THE SOFTWARE.
    6.88 ++ */
    6.89 ++
    6.90 ++#include "vl.h"
    6.91 ++typedef uint32_t pci_addr_t;
    6.92 ++#include "hw/pci_host.h"
    6.93 ++
    6.94 ++typedef PCIHostState I440FXState;
    6.95 ++
    6.96 ++static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
    6.97 ++{
    6.98 ++    I440FXState *s = opaque;
    6.99 ++    s->config_reg = val;
   6.100 ++}
   6.101 ++
   6.102 ++static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
   6.103 ++{
   6.104 ++    I440FXState *s = opaque;
   6.105 ++    return s->config_reg;
   6.106 ++}
   6.107 ++
   6.108 ++static void i440fx_set_irq(PCIDevice *pci_dev, void *pic, int intx, int level)
   6.109 ++{
   6.110 ++    xc_hvm_set_pci_intx_level(xc_handle, domid, 0, 0, pci_dev->devfn >> 3,
   6.111 ++                              intx, level);
   6.112 ++}
   6.113 ++
   6.114 ++PCIBus *i440fx_init(void)
   6.115 ++{
   6.116 ++    PCIBus *b;
   6.117 ++    PCIDevice *d;
   6.118 ++    I440FXState *s;
   6.119 ++
   6.120 ++    s = qemu_mallocz(sizeof(I440FXState));
   6.121 ++    b = pci_register_bus(i440fx_set_irq, NULL, 0);
   6.122 ++    s->bus = b;
   6.123 ++
   6.124 ++    register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
   6.125 ++    register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
   6.126 ++
   6.127 ++    register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
   6.128 ++    register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
   6.129 ++    register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
   6.130 ++    register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
   6.131 ++    register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
   6.132 ++    register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
   6.133 ++
   6.134 ++    d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0, 
   6.135 ++                            NULL, NULL);
   6.136 ++
   6.137 ++    d->config[0x00] = 0x86; // vendor_id
   6.138 ++    d->config[0x01] = 0x80;
   6.139 ++    d->config[0x02] = 0x37; // device_id
   6.140 ++    d->config[0x03] = 0x12;
   6.141 ++    d->config[0x08] = 0x02; // revision
   6.142 ++    d->config[0x0a] = 0x00; // class_sub = host2pci
   6.143 ++    d->config[0x0b] = 0x06; // class_base = PCI_bridge
   6.144 ++    d->config[0x0e] = 0x00; // header_type
   6.145 ++    return b;
   6.146 ++}
   6.147 ++
   6.148 ++/* PIIX3 PCI to ISA bridge */
   6.149 ++
   6.150 ++static PCIDevice *piix3_dev;
   6.151 ++
   6.152 ++static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
   6.153 ++{
   6.154 ++    /* This is the barber's pole mapping used by Xen. */
   6.155 ++    return (irq_num + (pci_dev->devfn >> 3)) & 3;
   6.156 ++}
   6.157 ++
   6.158 ++static void piix3_write_config(PCIDevice *d, 
   6.159 ++                               uint32_t address, uint32_t val, int len)
   6.160 ++{
   6.161 ++    int i;
   6.162 ++
   6.163 ++    /* Scan for updates to PCI link routes (0x60-0x63). */
   6.164 ++    for (i = 0; i < len; i++) {
   6.165 ++        uint8_t v = (val >> (8*i)) & 0xff;
   6.166 ++        if (v & 0x80)
   6.167 ++            v = 0;
   6.168 ++        v &= 0xf;
   6.169 ++        if (((address+i) >= 0x60) && ((address+i) <= 0x63))
   6.170 ++            xc_hvm_set_pci_link_route(xc_handle, domid, address + i - 0x60, v);
   6.171 ++    }
   6.172 ++
   6.173 ++    /* Hand off to default logic. */
   6.174 ++    pci_default_write_config(d, address, val, len);
   6.175 ++}
   6.176 ++
   6.177 ++static void piix3_reset(PCIDevice *d)
   6.178 ++{
   6.179 ++    uint8_t *pci_conf = d->config;
   6.180 ++
   6.181 ++    pci_conf[0x04] = 0x07; // master, memory and I/O
   6.182 ++    pci_conf[0x05] = 0x00;
   6.183 ++    pci_conf[0x06] = 0x00;
   6.184 ++    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
   6.185 ++    pci_conf[0x4c] = 0x4d;
   6.186 ++    pci_conf[0x4e] = 0x03;
   6.187 ++    pci_conf[0x4f] = 0x00;
   6.188 ++    pci_conf[0x60] = 0x80;
   6.189 ++    pci_conf[0x61] = 0x80;
   6.190 ++    pci_conf[0x62] = 0x80;
   6.191 ++    pci_conf[0x63] = 0x80;
   6.192 ++    pci_conf[0x69] = 0x02;
   6.193 ++    pci_conf[0x70] = 0x80;
   6.194 ++    pci_conf[0x76] = 0x0c;
   6.195 ++    pci_conf[0x77] = 0x0c;
   6.196 ++    pci_conf[0x78] = 0x02;
   6.197 ++    pci_conf[0x79] = 0x00;
   6.198 ++    pci_conf[0x80] = 0x00;
   6.199 ++    pci_conf[0x82] = 0x00;
   6.200 ++    pci_conf[0xa0] = 0x08;
   6.201 ++    pci_conf[0xa0] = 0x08;
   6.202 ++    pci_conf[0xa2] = 0x00;
   6.203 ++    pci_conf[0xa3] = 0x00;
   6.204 ++    pci_conf[0xa4] = 0x00;
   6.205 ++    pci_conf[0xa5] = 0x00;
   6.206 ++    pci_conf[0xa6] = 0x00;
   6.207 ++    pci_conf[0xa7] = 0x00;
   6.208 ++    pci_conf[0xa8] = 0x0f;
   6.209 ++    pci_conf[0xaa] = 0x00;
   6.210 ++    pci_conf[0xab] = 0x00;
   6.211 ++    pci_conf[0xac] = 0x00;
   6.212 ++    pci_conf[0xae] = 0x00;
   6.213 ++}
   6.214 ++
   6.215 ++int piix3_init(PCIBus *bus)
   6.216 ++{
   6.217 ++    PCIDevice *d;
   6.218 ++    uint8_t *pci_conf;
   6.219 ++
   6.220 ++    d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),
   6.221 ++                                    -1, NULL, piix3_write_config);
   6.222 ++    register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
   6.223 ++
   6.224 ++    piix3_dev = d;
   6.225 ++    pci_conf = d->config;
   6.226 ++
   6.227 ++    pci_conf[0x00] = 0x86; // Intel
   6.228 ++    pci_conf[0x01] = 0x80;
   6.229 ++    pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
   6.230 ++    pci_conf[0x03] = 0x70;
   6.231 ++    pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
   6.232 ++    pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
   6.233 ++    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
   6.234 ++
   6.235 ++    piix3_reset(d);
   6.236 ++    return d->devfn;
   6.237 ++}
   6.238 ++
   6.239 ++/***********************************************************/
   6.240 ++/* XXX: the following should be moved to the PC BIOS */
   6.241 ++
   6.242 ++static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
   6.243 ++{
   6.244 ++    return cpu_inb(NULL, addr);
   6.245 ++}
   6.246 ++
   6.247 ++static void isa_outb(uint32_t val, uint32_t addr)
   6.248 ++{
   6.249 ++    cpu_outb(NULL, addr, val);
   6.250 ++}
   6.251 ++
   6.252 ++static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
   6.253 ++{
   6.254 ++    return cpu_inw(NULL, addr);
   6.255 ++}
   6.256 ++
   6.257 ++static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
   6.258 ++{
   6.259 ++    cpu_outw(NULL, addr, val);
   6.260 ++}
   6.261 ++
   6.262 ++static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
   6.263 ++{
   6.264 ++    return cpu_inl(NULL, addr);
   6.265 ++}
   6.266 ++
   6.267 ++static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
   6.268 ++{
   6.269 ++    cpu_outl(NULL, addr, val);
   6.270 ++}
   6.271 ++
   6.272 ++static uint32_t pci_bios_io_addr;
   6.273 ++static uint32_t pci_bios_mem_addr;
   6.274 ++/* host irqs corresponding to PCI irqs A-D */
   6.275 ++static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
   6.276 ++
   6.277 ++static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
   6.278 ++{
   6.279 ++    PCIBus *s = d->bus;
   6.280 ++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
   6.281 ++    pci_data_write(s, addr, val, 4);
   6.282 ++}
   6.283 ++
   6.284 ++static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
   6.285 ++{
   6.286 ++    PCIBus *s = d->bus;
   6.287 ++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
   6.288 ++    pci_data_write(s, addr, val, 2);
   6.289 ++}
   6.290 ++
   6.291 ++static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
   6.292 ++{
   6.293 ++    PCIBus *s = d->bus;
   6.294 ++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
   6.295 ++    pci_data_write(s, addr, val, 1);
   6.296 ++}
   6.297 ++
   6.298 ++static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
   6.299 ++{
   6.300 ++    PCIBus *s = d->bus;
   6.301 ++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
   6.302 ++    return pci_data_read(s, addr, 4);
   6.303 ++}
   6.304 ++
   6.305 ++static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
   6.306 ++{
   6.307 ++    PCIBus *s = d->bus;
   6.308 ++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
   6.309 ++    return pci_data_read(s, addr, 2);
   6.310 ++}
   6.311 ++
   6.312 ++static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
   6.313 ++{
   6.314 ++    PCIBus *s = d->bus;
   6.315 ++    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
   6.316 ++    return pci_data_read(s, addr, 1);
   6.317 ++}
   6.318 ++
   6.319 ++static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
   6.320 ++{
   6.321 ++    PCIIORegion *r;
   6.322 ++    uint16_t cmd;
   6.323 ++    uint32_t ofs;
   6.324 ++
   6.325 ++    if ( region_num == PCI_ROM_SLOT ) {
   6.326 ++        ofs = 0x30;
   6.327 ++    }else{
   6.328 ++        ofs = 0x10 + region_num * 4;
   6.329 ++    }
   6.330 ++
   6.331 ++    pci_config_writel(d, ofs, addr);
   6.332 ++    r = &d->io_regions[region_num];
   6.333 ++
   6.334 ++    /* enable memory mappings */
   6.335 ++    cmd = pci_config_readw(d, PCI_COMMAND);
   6.336 ++    if ( region_num == PCI_ROM_SLOT )
   6.337 ++        cmd |= 2;
   6.338 ++    else if (r->type & PCI_ADDRESS_SPACE_IO)
   6.339 ++        cmd |= 1;
   6.340 ++    else
   6.341 ++        cmd |= 2;
   6.342 ++    pci_config_writew(d, PCI_COMMAND, cmd);
   6.343 ++}
   6.344 ++
   6.345 ++static void pci_bios_init_device(PCIDevice *d)
   6.346 ++{
   6.347 ++    int class;
   6.348 ++    PCIIORegion *r;
   6.349 ++    uint32_t *paddr;
   6.350 ++    int i, pin, pic_irq, vendor_id, device_id;
   6.351 ++
   6.352 ++    class = pci_config_readw(d, PCI_CLASS_DEVICE);
   6.353 ++    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
   6.354 ++    device_id = pci_config_readw(d, PCI_DEVICE_ID);
   6.355 ++    switch(class) {
   6.356 ++    case 0x0101:
   6.357 ++        if (vendor_id == 0x8086 && device_id == 0x7010) {
   6.358 ++            /* PIIX3 IDE */
   6.359 ++            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
   6.360 ++            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
   6.361 ++            goto default_map;
   6.362 ++        } else {
   6.363 ++            /* IDE: we map it as in ISA mode */
   6.364 ++            pci_set_io_region_addr(d, 0, 0x1f0);
   6.365 ++            pci_set_io_region_addr(d, 1, 0x3f4);
   6.366 ++            pci_set_io_region_addr(d, 2, 0x170);
   6.367 ++            pci_set_io_region_addr(d, 3, 0x374);
   6.368 ++        }
   6.369 ++        break;
   6.370 ++    case 0x0680:
   6.371 ++        if (vendor_id == 0x8086 && device_id == 0x7113) {
   6.372 ++            /*
   6.373 ++             * PIIX4 ACPI PM.
   6.374 ++             * Special device with special PCI config space. No ordinary BARs.
   6.375 ++             */
   6.376 ++            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
   6.377 ++            pci_config_writew(d, 0x22, 0x0000);
   6.378 ++            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
   6.379 ++            pci_config_writew(d, 0x3d, 0x0001);
   6.380 ++        }
   6.381 ++        break;
   6.382 ++    case 0x0300:
   6.383 ++        if (vendor_id != 0x1234)
   6.384 ++            goto default_map;
   6.385 ++        /* VGA: map frame buffer to default Bochs VBE address */
   6.386 ++        pci_set_io_region_addr(d, 0, 0xE0000000);
   6.387 ++        break;
   6.388 ++    case 0x0800:
   6.389 ++        /* PIC */
   6.390 ++        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
   6.391 ++        device_id = pci_config_readw(d, PCI_DEVICE_ID);
   6.392 ++        if (vendor_id == 0x1014) {
   6.393 ++            /* IBM */
   6.394 ++            if (device_id == 0x0046 || device_id == 0xFFFF) {
   6.395 ++                /* MPIC & MPIC2 */
   6.396 ++                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
   6.397 ++            }
   6.398 ++        }
   6.399 ++        break;
   6.400 ++    case 0xff00:
   6.401 ++        if (vendor_id == 0x0106b &&
   6.402 ++            (device_id == 0x0017 || device_id == 0x0022)) {
   6.403 ++            /* macio bridge */
   6.404 ++            pci_set_io_region_addr(d, 0, 0x80800000);
   6.405 ++        }
   6.406 ++        break;
   6.407 ++    default:
   6.408 ++    default_map:
   6.409 ++        /* default memory mappings */
   6.410 ++        for(i = 0; i < PCI_NUM_REGIONS; i++) {
   6.411 ++            r = &d->io_regions[i];
   6.412 ++            if (r->size) {
   6.413 ++                if (r->type & PCI_ADDRESS_SPACE_IO)
   6.414 ++                    paddr = &pci_bios_io_addr;
   6.415 ++                else
   6.416 ++                    paddr = &pci_bios_mem_addr;
   6.417 ++                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
   6.418 ++                pci_set_io_region_addr(d, i, *paddr);
   6.419 ++                *paddr += r->size;
   6.420 ++            }
   6.421 ++        }
   6.422 ++        break;
   6.423 ++    }
   6.424 ++
   6.425 ++    /* map the interrupt */
   6.426 ++    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
   6.427 ++    if (pin != 0) {
   6.428 ++        pin = pci_slot_get_pirq(d, pin - 1);
   6.429 ++        pic_irq = pci_irqs[pin];
   6.430 ++        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
   6.431 ++    }
   6.432 ++}
   6.433 ++
   6.434 ++/*
   6.435 ++ * This function initializes the PCI devices as a normal PCI BIOS
   6.436 ++ * would do. It is provided just in case the BIOS has no support for
   6.437 ++ * PCI.
   6.438 ++ */
   6.439 ++void pci_bios_init(void)
   6.440 ++{
   6.441 ++    int i, irq;
   6.442 ++    uint8_t elcr[2];
   6.443 ++
   6.444 ++    pci_bios_io_addr = 0xc000;
   6.445 ++    pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START;
   6.446 ++
   6.447 ++    /* activate IRQ mappings */
   6.448 ++    elcr[0] = 0x00;
   6.449 ++    elcr[1] = 0x00;
   6.450 ++    for(i = 0; i < 4; i++) {
   6.451 ++        irq = pci_irqs[i];
   6.452 ++        /* set to trigger level */
   6.453 ++        elcr[irq >> 3] |= (1 << (irq & 7));
   6.454 ++        /* activate irq remapping in PIIX */
   6.455 ++        pci_config_writeb(piix3_dev, 0x60 + i, irq);
   6.456 ++    }
   6.457 ++    isa_outb(elcr[0], 0x4d0);
   6.458 ++    isa_outb(elcr[1], 0x4d1);
   6.459 ++
   6.460 ++    pci_for_each_device(pci_bios_init_device);
   6.461 ++}
   6.462 ++
     7.1 --- a/tools/ioemu/patches/hypervisor-pit	Fri Dec 08 07:22:21 2006 -0800
     7.2 +++ b/tools/ioemu/patches/hypervisor-pit	Fri Dec 08 18:31:01 2006 +0000
     7.3 @@ -1,8 +1,8 @@
     7.4  Index: ioemu/Makefile.target
     7.5  ===================================================================
     7.6 ---- ioemu.orig/Makefile.target	2006-08-17 19:49:33.813030472 +0100
     7.7 -+++ ioemu/Makefile.target	2006-08-17 19:49:50.228216099 +0100
     7.8 -@@ -354,7 +354,7 @@
     7.9 +--- ioemu.orig/Makefile.target	2006-12-08 01:41:12.000000000 +0000
    7.10 ++++ ioemu/Makefile.target	2006-12-08 01:41:12.000000000 +0000
    7.11 +@@ -355,7 +355,7 @@
    7.12   ifeq ($(TARGET_BASE_ARCH), i386)
    7.13   # Hardware support
    7.14   VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    7.15 @@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
    7.16   DEFINES += -DHAS_AUDIO
    7.17  Index: ioemu/hw/pc.c
    7.18  ===================================================================
    7.19 ---- ioemu.orig/hw/pc.c	2006-08-17 19:49:35.507843144 +0100
    7.20 -+++ ioemu/hw/pc.c	2006-08-17 19:49:50.229215988 +0100
    7.21 +--- ioemu.orig/hw/pc.c	2006-12-08 01:41:12.000000000 +0000
    7.22 ++++ ioemu/hw/pc.c	2006-12-08 01:41:12.000000000 +0000
    7.23  @@ -38,7 +38,9 @@
    7.24   
    7.25   static fdctrl_t *floppy_controller;
    7.26 @@ -38,8 +38,8 @@ Index: ioemu/hw/pc.c
    7.27           pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
    7.28  Index: ioemu/vl.c
    7.29  ===================================================================
    7.30 ---- ioemu.orig/vl.c	2006-08-17 19:49:48.566399780 +0100
    7.31 -+++ ioemu/vl.c	2006-08-17 19:49:50.231215767 +0100
    7.32 +--- ioemu.orig/vl.c	2006-12-08 01:41:12.000000000 +0000
    7.33 ++++ ioemu/vl.c	2006-12-08 01:41:12.000000000 +0000
    7.34  @@ -5570,6 +5570,7 @@
    7.35   
    7.36   #ifdef HAS_AUDIO
     8.1 --- a/tools/ioemu/patches/hypervisor-rtc	Fri Dec 08 07:22:21 2006 -0800
     8.2 +++ b/tools/ioemu/patches/hypervisor-rtc	Fri Dec 08 18:31:01 2006 +0000
     8.3 @@ -5,9 +5,11 @@
     8.4  [HVM] Move RTC emulation into the hypervisor.
     8.5  Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
     8.6  
     8.7 ---- ioemu/Makefile.target	Wed Oct 18 18:13:57 2006 +0100
     8.8 -+++ ioemu/Makefile.target	Wed Oct 18 18:35:21 2006 +0100
     8.9 -@@ -294,7 +294,11 @@ endif
    8.10 +Index: ioemu/Makefile.target
    8.11 +===================================================================
    8.12 +--- ioemu.orig/Makefile.target	2006-12-08 01:41:15.000000000 +0000
    8.13 ++++ ioemu/Makefile.target	2006-12-08 01:41:15.000000000 +0000
    8.14 +@@ -295,7 +295,11 @@
    8.15   endif
    8.16   
    8.17   # qemu-dm objects
    8.18 @@ -19,7 +21,7 @@ Signed-off-by: Xiaowei Yang <xiaowei.yan
    8.19   
    8.20   all: $(PROGS)
    8.21   
    8.22 -@@ -354,7 +358,11 @@ ifeq ($(TARGET_BASE_ARCH), i386)
    8.23 +@@ -355,7 +359,11 @@
    8.24   ifeq ($(TARGET_BASE_ARCH), i386)
    8.25   # Hardware support
    8.26   VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    8.27 @@ -31,8 +33,10 @@ Signed-off-by: Xiaowei Yang <xiaowei.yan
    8.28   VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
    8.29   VL_OBJS+= usb-uhci.o
    8.30   VL_OBJS+= piix4acpi.o
    8.31 ---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    8.32 -+++ ioemu/target-i386-dm/rtc-dm.c	Wed Oct 18 18:35:21 2006 +0100
    8.33 +Index: ioemu/target-i386-dm/rtc-dm.c
    8.34 +===================================================================
    8.35 +--- /dev/null	1970-01-01 00:00:00.000000000 +0000
    8.36 ++++ ioemu/target-i386-dm/rtc-dm.c	2006-12-08 01:41:15.000000000 +0000
    8.37  @@ -0,0 +1,107 @@
    8.38  +/*
    8.39  + * QEMU MC146818 RTC emulation
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/ioemu/patches/ide-error-reporting	Fri Dec 08 18:31:01 2006 +0000
     9.3 @@ -0,0 +1,110 @@
     9.4 +# HG changeset patch
     9.5 +# User kfraser@localhost.localdomain
     9.6 +# Node ID fd28a1b139dea91b8bfcf06dd233dbdda8f51ff1
     9.7 +# Parent  d8befb109c394c2c2d3e1870a500107d461724ef
     9.8 +[QEMU] Error reporting in IDE device model.
     9.9 +
    9.10 +Following on from my patch to make blktap report I/O errors back to
    9.11 +guest OS, a similar problem exists in the QEMU codebase. The IDE
    9.12 +driver never reports I/O errors during read/write operations back to
    9.13 +the guest OS. Instead all I/O operations are reported as
    9.14 +succesfull. If, for example, the host FS holding the disk image fills
    9.15 +up, then writes may fail due to lack of space. Since the guest OS
    9.16 +never sees these failures, it assumes all is well & will continue
    9.17 +writing. Eventually this can lead to severe & unrecoverable filesystem
    9.18 +corruption.
    9.19 +
    9.20 +The attached patch fixes QEMU ide driver such that any failure of a
    9.21 +read or write operation sets the appropriate IDE status/error
    9.22 +registers. Having read the ATA-6 spec I think the most compliant
    9.23 +behaviour is to set the status register to 'READY_STAT | ERR_STAT',
    9.24 +and the error register to ABRT_ERR. There is already a convenience
    9.25 +function ide_abort_command() in the QEMU codebase which does just
    9.26 +this, so the attached patch simply calls that function.
    9.27 +
    9.28 +With this patch the guest OS sees the I/O failure & the kernel logs
    9.29 +IDE errors and then retries the operation. This at least ensures that
    9.30 +the guest can be shutdown the out of space issue in the host corrected
    9.31 +and the guest restarted, without any serious filesystem damage having
    9.32 +occurred.
    9.33 +
    9.34 +From: Daniel Berrange <berrange@redhat.com>
    9.35 +Signed-off-by: Keir Fraser <keir@xensource.com>
    9.36 +
    9.37 +Index: ioemu/hw/ide.c
    9.38 +===================================================================
    9.39 +--- ioemu.orig/hw/ide.c	2006-12-08 18:21:36.000000000 +0000
    9.40 ++++ ioemu/hw/ide.c	2006-12-08 18:23:18.000000000 +0000
    9.41 +@@ -680,7 +680,7 @@
    9.42 + static void ide_sector_read(IDEState *s)
    9.43 + {
    9.44 +     int64_t sector_num;
    9.45 +-    int ret, n;
    9.46 ++    int n;
    9.47 + 
    9.48 +     s->status = READY_STAT | SEEK_STAT;
    9.49 +     s->error = 0; /* not needed by IDE spec, but needed by Windows */
    9.50 +@@ -695,7 +695,11 @@
    9.51 + #endif
    9.52 +         if (n > s->req_nb_sectors)
    9.53 +             n = s->req_nb_sectors;
    9.54 +-        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
    9.55 ++        if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) {
    9.56 ++            ide_abort_command(s);
    9.57 ++            ide_set_irq(s);
    9.58 ++            return;
    9.59 ++        }
    9.60 +         ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
    9.61 +         ide_set_irq(s);
    9.62 +         ide_set_sector(s, sector_num + n);
    9.63 +@@ -721,7 +725,11 @@
    9.64 +             if (n > MAX_MULT_SECTORS)
    9.65 +                 n = MAX_MULT_SECTORS;
    9.66 +             sector_num = ide_get_sector(s);
    9.67 +-            bdrv_read(s->bs, sector_num, s->io_buffer, n);
    9.68 ++            if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) {
    9.69 ++                ide_abort_command(s);
    9.70 ++                ide_set_irq(s);
    9.71 ++                return 0;
    9.72 ++            }
    9.73 +             s->io_buffer_index = 0;
    9.74 +             s->io_buffer_size = n * 512;
    9.75 +             len = s->io_buffer_size;
    9.76 +@@ -767,7 +775,7 @@
    9.77 + static void ide_sector_write(IDEState *s)
    9.78 + {
    9.79 +     int64_t sector_num;
    9.80 +-    int ret, n, n1;
    9.81 ++    int n, n1;
    9.82 + 
    9.83 +     s->status = READY_STAT | SEEK_STAT;
    9.84 +     sector_num = ide_get_sector(s);
    9.85 +@@ -777,7 +785,11 @@
    9.86 +     n = s->nsector;
    9.87 +     if (n > s->req_nb_sectors)
    9.88 +         n = s->req_nb_sectors;
    9.89 +-    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
    9.90 ++    if (bdrv_write(s->bs, sector_num, s->io_buffer, n) != 0) {
    9.91 ++        ide_abort_command(s);
    9.92 ++        ide_set_irq(s);
    9.93 ++        return;
    9.94 ++    }
    9.95 +     s->nsector -= n;
    9.96 +     if (s->nsector == 0) {
    9.97 +         /* no more sector to write */
    9.98 +@@ -823,8 +835,13 @@
    9.99 +         if (len == 0) {
   9.100 +             n = s->io_buffer_size >> 9;
   9.101 +             sector_num = ide_get_sector(s);
   9.102 +-            bdrv_write(s->bs, sector_num, s->io_buffer, 
   9.103 +-                       s->io_buffer_size >> 9);
   9.104 ++            if (bdrv_write(s->bs, sector_num, s->io_buffer, 
   9.105 ++                	   s->io_buffer_size >> 9) != 0) {
   9.106 ++                ide_abort_command(s);
   9.107 ++                ide_set_irq(s);
   9.108 ++                return 0;
   9.109 ++            }
   9.110 ++
   9.111 +             sector_num += n;
   9.112 +             ide_set_sector(s, sector_num);
   9.113 +             s->nsector -= n;
    10.1 --- a/tools/ioemu/patches/ioemu-ia64	Fri Dec 08 07:22:21 2006 -0800
    10.2 +++ b/tools/ioemu/patches/ioemu-ia64	Fri Dec 08 18:31:01 2006 +0000
    10.3 @@ -1,7 +1,7 @@
    10.4  Index: ioemu/hw/iommu.c
    10.5  ===================================================================
    10.6 ---- ioemu.orig/hw/iommu.c	2006-08-17 19:37:36.791476068 +0100
    10.7 -+++ ioemu/hw/iommu.c	2006-08-17 19:48:27.357375720 +0100
    10.8 +--- ioemu.orig/hw/iommu.c	2006-12-08 02:02:07.000000000 +0000
    10.9 ++++ ioemu/hw/iommu.c	2006-12-08 02:02:34.000000000 +0000
   10.10  @@ -82,7 +82,11 @@
   10.11   #define IOPTE_VALID         0x00000002 /* IOPTE is valid */
   10.12   #define IOPTE_WAZ           0x00000001 /* Write as zeros */
   10.13 @@ -16,8 +16,8 @@ Index: ioemu/hw/iommu.c
   10.14   
   10.15  Index: ioemu/cpu-all.h
   10.16  ===================================================================
   10.17 ---- ioemu.orig/cpu-all.h	2006-08-17 19:37:36.791476068 +0100
   10.18 -+++ ioemu/cpu-all.h	2006-08-17 19:48:27.358375609 +0100
   10.19 +--- ioemu.orig/cpu-all.h	2006-12-08 02:02:07.000000000 +0000
   10.20 ++++ ioemu/cpu-all.h	2006-12-08 02:02:34.000000000 +0000
   10.21  @@ -835,6 +835,31 @@
   10.22                   :"=m" (*(volatile long *)addr)
   10.23                   :"dIr" (nr));
   10.24 @@ -52,36 +52,36 @@ Index: ioemu/cpu-all.h
   10.25   /* memory API */
   10.26  Index: ioemu/vl.c
   10.27  ===================================================================
   10.28 ---- ioemu.orig/vl.c	2006-08-17 19:47:08.538087284 +0100
   10.29 -+++ ioemu/vl.c	2006-08-17 19:57:50.666108706 +0100
   10.30 -@@ -6144,6 +6144,11 @@
   10.31 - 
   10.32 -     xc_handle = xc_interface_open();
   10.33 +--- ioemu.orig/vl.c	2006-12-08 02:02:28.000000000 +0000
   10.34 ++++ ioemu/vl.c	2006-12-08 02:02:34.000000000 +0000
   10.35 +@@ -6137,6 +6137,11 @@
   10.36 +             exit(1);
   10.37 +     }
   10.38   
   10.39  +#if defined (__ia64__)
   10.40  +    if (ram_size > MMIO_START)
   10.41  +        ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
   10.42  +#endif
   10.43  +
   10.44 -     nr_pages = ram_size/PAGE_SIZE;
   10.45 -     tmp_nr_pages = nr_pages;
   10.46 +     /* init the memory */
   10.47 +     phys_ram_size = ram_size + vga_ram_size + bios_size;
   10.48   
   10.49  @@ -6161,6 +6166,7 @@
   10.50           exit(-1);
   10.51       }
   10.52   
   10.53  +#if defined(__i386__) || defined(__x86_64__)
   10.54 -     if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
   10.55 -         fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
   10.56 -         exit(-1);
   10.57 -@@ -6191,6 +6197,41 @@
   10.58 +     for ( i = 0; i < tmp_nr_pages; i++)
   10.59 +         page_array[i] = i;
   10.60 + 
   10.61 +@@ -6185,6 +6191,48 @@
   10.62   
   10.63       free(page_array);
   10.64   
   10.65  +#elif defined(__ia64__)
   10.66  +  
   10.67  +    if (xc_ia64_get_pfn_list(xc_handle, domid, page_array,
   10.68 -+                             IO_PAGE_START >> PAGE_SHIFT, 1) != 1) {
   10.69 ++                             IO_PAGE_START >> PAGE_SHIFT, 3) != 3) {
   10.70  +        fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
   10.71  +        exit(-1);
   10.72  +    }
   10.73 @@ -93,6 +93,12 @@ Index: ioemu/vl.c
   10.74  +    fprintf(logfile, "shared page at pfn:%lx, mfn: %016lx\n",
   10.75  +            IO_PAGE_START >> PAGE_SHIFT, page_array[0]);
   10.76  +
   10.77 ++    buffered_io_page =xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   10.78 ++                                       PROT_READ|PROT_WRITE,
   10.79 ++                                       page_array[2]);
   10.80 ++    fprintf(logfile, "Buffered IO page at pfn:%lx, mfn: %016lx\n",
   10.81 ++            BUFFER_IO_PAGE_START >> PAGE_SHIFT, page_array[2]);
   10.82 ++
   10.83  +    if (xc_ia64_get_pfn_list(xc_handle, domid,
   10.84  +                             page_array, 0, nr_pages) != nr_pages) {
   10.85  +        fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
   10.86 @@ -100,9 +106,9 @@ Index: ioemu/vl.c
   10.87  +    }
   10.88  +
   10.89  +    if (ram_size > MMIO_START) {	
   10.90 -+        for (i = 0 ; i < MEM_G >> PAGE_SHIFT; i++)
   10.91 -+            page_array[MMIO_START >> PAGE_SHIFT + i] =
   10.92 -+                page_array[IO_PAGE_START >> PAGE_SHIFT + 1];
   10.93 ++        for (i = 0 ; i < (MEM_G >> PAGE_SHIFT); i++)
   10.94 ++            page_array[(MMIO_START >> PAGE_SHIFT) + i] =
   10.95 ++                page_array[(IO_PAGE_START >> PAGE_SHIFT) + 1];
   10.96  +    }
   10.97  +
   10.98  +    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
   10.99 @@ -112,52 +118,15 @@ Index: ioemu/vl.c
  10.100  +        fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
  10.101  +        exit(-1);
  10.102  +    }
  10.103 ++    free(page_array);
  10.104  +#endif
  10.105   #else  /* !CONFIG_DM */
  10.106   
  10.107       phys_ram_base = qemu_vmalloc(phys_ram_size);
  10.108 -Index: ioemu/target-i386-dm/exec-dm.c
  10.109 -===================================================================
  10.110 ---- ioemu.orig/target-i386-dm/exec-dm.c	2006-08-17 19:37:36.792475957 +0100
  10.111 -+++ ioemu/target-i386-dm/exec-dm.c	2006-08-17 19:48:27.361375278 +0100
  10.112 -@@ -341,6 +341,23 @@
  10.113 -     return io_mem_read[io_index >> IO_MEM_SHIFT];
  10.114 - }
  10.115 - 
  10.116 -+#ifdef __ia64__
  10.117 -+/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
  10.118 -+ * So to emulate right behavior that guest OS is assumed, we need to flush
  10.119 -+ * I/D cache here.
  10.120 -+ */
  10.121 -+static void sync_icache(unsigned long address, int len)
  10.122 -+{
  10.123 -+    int l;
  10.124 -+
  10.125 -+    for(l = 0; l < (len + 32); l += 32)
  10.126 -+        __ia64_fc(address + l);
  10.127 -+
  10.128 -+    ia64_sync_i();
  10.129 -+    ia64_srlz_i();
  10.130 -+}
  10.131 -+#endif 
  10.132 -+
  10.133 - /* physical memory access (slow version, mainly for debug) */
  10.134 - #if defined(CONFIG_USER_ONLY)
  10.135 - void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
  10.136 -@@ -432,6 +449,9 @@
  10.137 -                 /* RAM case */
  10.138 -                 ptr = phys_ram_base + addr1;
  10.139 -                 memcpy(ptr, buf, l);
  10.140 -+#ifdef __ia64__
  10.141 -+                sync_icache((unsigned long)ptr, l);
  10.142 -+#endif 
  10.143 -             }
  10.144 -         } else {
  10.145 -             if (io_index) {
  10.146  Index: ioemu/exec-all.h
  10.147  ===================================================================
  10.148 ---- ioemu.orig/exec-all.h	2006-08-17 19:37:36.791476068 +0100
  10.149 -+++ ioemu/exec-all.h	2006-08-17 19:48:27.362375167 +0100
  10.150 +--- ioemu.orig/exec-all.h	2006-12-08 02:02:07.000000000 +0000
  10.151 ++++ ioemu/exec-all.h	2006-12-08 02:02:34.000000000 +0000
  10.152  @@ -462,12 +462,13 @@
  10.153   }
  10.154   #endif
  10.155 @@ -177,9 +146,9 @@ Index: ioemu/exec-all.h
  10.156   
  10.157  Index: ioemu/target-i386-dm/cpu.h
  10.158  ===================================================================
  10.159 ---- ioemu.orig/target-i386-dm/cpu.h	2006-08-17 19:37:36.792475957 +0100
  10.160 -+++ ioemu/target-i386-dm/cpu.h	2006-08-17 19:48:27.362375167 +0100
  10.161 -@@ -80,7 +80,11 @@
  10.162 +--- ioemu.orig/target-i386-dm/cpu.h	2006-12-08 02:02:07.000000000 +0000
  10.163 ++++ ioemu/target-i386-dm/cpu.h	2006-12-08 02:02:34.000000000 +0000
  10.164 +@@ -78,7 +78,11 @@
  10.165   /* helper2.c */
  10.166   int main_loop(void);
  10.167   
  10.168 @@ -194,7 +163,7 @@ Index: ioemu/target-i386-dm/cpu.h
  10.169  Index: ioemu/ia64_intrinsic.h
  10.170  ===================================================================
  10.171  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
  10.172 -+++ ioemu/ia64_intrinsic.h	2006-08-17 19:48:27.363375057 +0100
  10.173 ++++ ioemu/ia64_intrinsic.h	2006-12-08 02:02:34.000000000 +0000
  10.174  @@ -0,0 +1,276 @@
  10.175  +#ifndef IA64_INTRINSIC_H
  10.176  +#define IA64_INTRINSIC_H
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/ioemu/patches/limit-fdc-sector-size-to-16K	Fri Dec 08 18:31:01 2006 +0000
    11.3 @@ -0,0 +1,32 @@
    11.4 +# HG changeset patch
    11.5 +# User kfraser@localhost.localdomain
    11.6 +# Node ID f711b87ba951e608287abd0de028c6f0d83400a9
    11.7 +# Parent  f3ee62b7fb5299c89d442845e0883bcfab78c067
    11.8 +[QEMU] fdc: Limit sector size to 16K
    11.9 +
   11.10 +In fdctrl_start_transfer the sector size field (fifo[5]) is not
   11.11 +checked for overflows.  This allows an arbitrarily large sector size
   11.12 +to be used, which can in turn result in a negative data_len field that
   11.13 +is then used for DMA transfers.
   11.14 +
   11.15 +This can lead to the corrpuption of qemu state because some subsequent
   11.16 +checks on the transfer length is conducted using signed integers.
   11.17 +
   11.18 +This patch limits the value fifo[5] to 7 which is the standard limit
   11.19 +on floppy sector size.
   11.20 +
   11.21 +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
   11.22 +
   11.23 +Index: ioemu/hw/fdc.c
   11.24 +===================================================================
   11.25 +--- ioemu.orig/hw/fdc.c	2006-12-08 18:21:36.000000000 +0000
   11.26 ++++ ioemu/hw/fdc.c	2006-12-08 18:22:57.000000000 +0000
   11.27 +@@ -898,7 +898,7 @@
   11.28 +         fdctrl->data_len = fdctrl->fifo[8];
   11.29 +     } else {
   11.30 + 	int tmp;
   11.31 +-        fdctrl->data_len = 128 << fdctrl->fifo[5];
   11.32 ++        fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
   11.33 +         tmp = (cur_drv->last_sect - ks + 1);
   11.34 +         if (fdctrl->fifo[0] & 0x80)
   11.35 +             tmp += cur_drv->last_sect;
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/ioemu/patches/ne2000-bounds-checks	Fri Dec 08 18:31:01 2006 +0000
    12.3 @@ -0,0 +1,113 @@
    12.4 +# HG changeset patch
    12.5 +# User kaf24@localhost.localdomain
    12.6 +# Node ID 66fe61db9e69e03e12d0c4086683bebfb4a67780
    12.7 +# Parent  1940ee13f9d6ab1be2c614a0fbf7769536a056d2
    12.8 +[QEMU] ne2000: Stop memory access beyond buffer
    12.9 +
   12.10 +As a program that runs in dom0 which serves users from guests,
   12.11 +the qemu drivers need to be vigilant to the input that comes
   12.12 +from the guests since they may be malicious.
   12.13 +
   12.14 +As it is there are multiple ways to get ne2000 to read/write
   12.15 +memory beyond the 48K buffer that it has allocated for each
   12.16 +adapter.
   12.17 +
   12.18 +This patch checks the addresses and prevents this from occuring.
   12.19 +
   12.20 +The boundary is checked each time since it's changed for every
   12.21 +packet received while the other parameters are only changed
   12.22 +(by the guest) during setup.
   12.23 +
   12.24 +Signed-off: Herbert Xu <herbert@gondor.apana.org.au>
   12.25 +
   12.26 +Index: ioemu/hw/ne2000.c
   12.27 +===================================================================
   12.28 +--- ioemu.orig/hw/ne2000.c	2006-12-08 18:20:45.000000000 +0000
   12.29 ++++ ioemu/hw/ne2000.c	2006-12-08 18:20:53.000000000 +0000
   12.30 +@@ -137,6 +137,7 @@
   12.31 +     uint8_t curpag;
   12.32 +     uint8_t mult[8]; /* multicast mask array */
   12.33 +     int irq;
   12.34 ++    int tainted;
   12.35 +     PCIDevice *pci_dev;
   12.36 +     VLANClientState *vc;
   12.37 +     uint8_t macaddr[6];
   12.38 +@@ -226,6 +227,27 @@
   12.39 + 
   12.40 + #define MIN_BUF_SIZE 60
   12.41 + 
   12.42 ++static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr)
   12.43 ++{
   12.44 ++    addr <<= 8;
   12.45 ++    return addr < s->stop && addr >= s->start;
   12.46 ++}
   12.47 ++
   12.48 ++static inline int ne2000_check_state(NE2000State *s)
   12.49 ++{
   12.50 ++    if (!s->tainted)
   12.51 ++        return 0;
   12.52 ++
   12.53 ++    if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE)
   12.54 ++        return -EINVAL;
   12.55 ++
   12.56 ++    if (!ne2000_valid_ring_addr(s, s->curpag))
   12.57 ++        return -EINVAL;
   12.58 ++
   12.59 ++    s->tainted = 0;
   12.60 ++    return 0;
   12.61 ++}
   12.62 ++
   12.63 + static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
   12.64 + {
   12.65 +     NE2000State *s = opaque;
   12.66 +@@ -239,6 +261,12 @@
   12.67 +     printf("NE2000: received len=%d\n", size);
   12.68 + #endif
   12.69 + 
   12.70 ++    if (ne2000_check_state(s))
   12.71 ++        return;
   12.72 ++
   12.73 ++    if (!ne2000_valid_ring_addr(s, s->boundary))
   12.74 ++        return;
   12.75 ++
   12.76 +     if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
   12.77 +         return;
   12.78 +     
   12.79 +@@ -359,9 +387,11 @@
   12.80 +         switch(offset) {
   12.81 +         case EN0_STARTPG:
   12.82 +             s->start = val << 8;
   12.83 ++            s->tainted = 1;
   12.84 +             break;
   12.85 +         case EN0_STOPPG:
   12.86 +             s->stop = val << 8;
   12.87 ++            s->tainted = 1;
   12.88 +             break;
   12.89 +         case EN0_BOUNDARY:
   12.90 +             s->boundary = val;
   12.91 +@@ -406,6 +436,7 @@
   12.92 +             break;
   12.93 +         case EN1_CURPAG:
   12.94 +             s->curpag = val;
   12.95 ++            s->tainted = 1;
   12.96 +             break;
   12.97 +         case EN1_MULT ... EN1_MULT + 7:
   12.98 +             s->mult[offset - EN1_MULT] = val;
   12.99 +@@ -509,7 +540,7 @@
  12.100 + {
  12.101 +     addr &= ~1; /* XXX: check exact behaviour if not even */
  12.102 +     if (addr < 32 || 
  12.103 +-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
  12.104 ++        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
  12.105 +         cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
  12.106 +     }
  12.107 + }
  12.108 +@@ -539,7 +570,7 @@
  12.109 + {
  12.110 +     addr &= ~1; /* XXX: check exact behaviour if not even */
  12.111 +     if (addr < 32 || 
  12.112 +-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
  12.113 ++        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
  12.114 +         return le32_to_cpupu((uint32_t *)(s->mem + addr));
  12.115 +     } else {
  12.116 +         return 0xffffffff;
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/ioemu/patches/nodelay-serial-over-tcp	Fri Dec 08 18:31:01 2006 +0000
    13.3 @@ -0,0 +1,29 @@
    13.4 +# HG changeset patch
    13.5 +# User PeterJohnston <peter.johnston@xensource.com>
    13.6 +# Node ID b8cc9ffda0a3dc449b026c72c97f78dea2e6f114
    13.7 +# Parent  a8d2b1393b769048c7b62822e45bef27eef80fb6
    13.8 +[QEMU] Add TCP_NODELAY to tcp connections exporting serial ports.
    13.9 +
   13.10 +Signed-off-by: Steven Smith <sos22@cam.ac.uk>
   13.11 +
   13.12 +Index: ioemu/vl.c
   13.13 +===================================================================
   13.14 +--- ioemu.orig/vl.c	2006-12-08 18:21:56.000000000 +0000
   13.15 ++++ ioemu/vl.c	2006-12-08 18:22:42.000000000 +0000
   13.16 +@@ -2530,6 +2530,7 @@
   13.17 +     int is_waitconnect = 1;
   13.18 +     const char *ptr;
   13.19 +     struct sockaddr_in saddr;
   13.20 ++    int opt;
   13.21 + 
   13.22 +     if (parse_host_port(&saddr, host_str) < 0)
   13.23 +         goto fail;
   13.24 +@@ -2598,6 +2599,8 @@
   13.25 +             }
   13.26 +         }
   13.27 +         s->fd = fd;
   13.28 ++	opt = 1;
   13.29 ++	setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
   13.30 +         if (s->connected)
   13.31 +             tcp_chr_connect(chr);
   13.32 +         else
    14.1 --- a/tools/ioemu/patches/qemu-bootorder	Fri Dec 08 07:22:21 2006 -0800
    14.2 +++ b/tools/ioemu/patches/qemu-bootorder	Fri Dec 08 18:31:01 2006 +0000
    14.3 @@ -1,7 +1,7 @@
    14.4  Index: ioemu/vl.c
    14.5  ===================================================================
    14.6 ---- ioemu.orig/vl.c	2006-10-24 14:33:47.000000000 +0100
    14.7 -+++ ioemu/vl.c	2006-10-24 14:33:47.000000000 +0100
    14.8 +--- ioemu.orig/vl.c	2006-12-08 02:02:38.000000000 +0000
    14.9 ++++ ioemu/vl.c	2006-12-08 02:02:38.000000000 +0000
   14.10  @@ -125,7 +125,7 @@
   14.11   struct sockaddr_in vnclisten_addr;
   14.12   const char* keyboard_layout = NULL;
   14.13 @@ -11,7 +11,7 @@ Index: ioemu/vl.c
   14.14   uint64_t ram_size;
   14.15   int pit_min_timer_count = 0;
   14.16   int nb_nics;
   14.17 -@@ -6075,14 +6075,14 @@
   14.18 +@@ -6059,14 +6059,14 @@
   14.19                   break;
   14.20   #endif /* !CONFIG_DM */
   14.21               case QEMU_OPTION_boot:
   14.22 @@ -32,7 +32,7 @@ Index: ioemu/vl.c
   14.23                       exit(1);
   14.24                   }
   14.25                   break;
   14.26 -@@ -6349,6 +6349,7 @@
   14.27 +@@ -6333,6 +6333,7 @@
   14.28           fd_filename[0] == '\0')
   14.29           help();
   14.30       
   14.31 @@ -40,7 +40,7 @@ Index: ioemu/vl.c
   14.32       /* boot to cd by default if no hard disk */
   14.33       if (hd_filename[0] == '\0' && boot_device == 'c') {
   14.34           if (fd_filename[0] != '\0')
   14.35 -@@ -6356,6 +6357,7 @@
   14.36 +@@ -6340,6 +6341,7 @@
   14.37           else
   14.38               boot_device = 'd';
   14.39       }
   14.40 @@ -48,7 +48,7 @@ Index: ioemu/vl.c
   14.41   #endif /* !CONFIG_DM */
   14.42   
   14.43       setvbuf(stdout, NULL, _IOLBF, 0);
   14.44 -@@ -6614,6 +6616,7 @@
   14.45 +@@ -6598,6 +6600,7 @@
   14.46                     ds, fd_filename, snapshot,
   14.47                     kernel_filename, kernel_cmdline, initrd_filename,
   14.48                     timeoffset);
   14.49 @@ -58,8 +58,8 @@ Index: ioemu/vl.c
   14.50       if (usb_enabled) {
   14.51  Index: ioemu/vl.h
   14.52  ===================================================================
   14.53 ---- ioemu.orig/vl.h	2006-10-24 14:33:47.000000000 +0100
   14.54 -+++ ioemu/vl.h	2006-10-24 14:33:47.000000000 +0100
   14.55 +--- ioemu.orig/vl.h	2006-12-08 02:02:38.000000000 +0000
   14.56 ++++ ioemu/vl.h	2006-12-08 02:02:38.000000000 +0000
   14.57  @@ -578,7 +578,7 @@
   14.58   #ifndef QEMU_TOOL
   14.59   
   14.60 @@ -80,8 +80,8 @@ Index: ioemu/vl.h
   14.61                             uint32_t initrd_image, uint32_t initrd_size,
   14.62  Index: ioemu/hw/pc.c
   14.63  ===================================================================
   14.64 ---- ioemu.orig/hw/pc.c	2006-10-24 14:33:47.000000000 +0100
   14.65 -+++ ioemu/hw/pc.c	2006-10-24 14:33:47.000000000 +0100
   14.66 +--- ioemu.orig/hw/pc.c	2006-12-08 02:02:38.000000000 +0000
   14.67 ++++ ioemu/hw/pc.c	2006-12-08 02:02:38.000000000 +0000
   14.68  @@ -158,8 +158,23 @@
   14.69       rtc_set_memory(s, info_ofs + 8, sectors);
   14.70   }
    15.1 --- a/tools/ioemu/patches/qemu-daemonize	Fri Dec 08 07:22:21 2006 -0800
    15.2 +++ b/tools/ioemu/patches/qemu-daemonize	Fri Dec 08 18:31:01 2006 +0000
    15.3 @@ -2,9 +2,9 @@ Changes required because qemu-dm runs da
    15.4  
    15.5  Index: ioemu/vl.c
    15.6  ===================================================================
    15.7 ---- ioemu.orig/vl.c	2006-10-24 14:33:47.000000000 +0100
    15.8 -+++ ioemu/vl.c	2006-10-24 14:33:47.000000000 +0100
    15.9 -@@ -6054,10 +6054,11 @@
   15.10 +--- ioemu.orig/vl.c	2006-12-08 02:00:42.000000000 +0000
   15.11 ++++ ioemu/vl.c	2006-12-08 02:00:42.000000000 +0000
   15.12 +@@ -6038,10 +6038,11 @@
   15.13                   }
   15.14                   break;
   15.15               case QEMU_OPTION_nographic:
    16.1 --- a/tools/ioemu/patches/qemu-dm	Fri Dec 08 07:22:21 2006 -0800
    16.2 +++ b/tools/ioemu/patches/qemu-dm	Fri Dec 08 18:31:01 2006 +0000
    16.3 @@ -1,8 +1,8 @@
    16.4  Index: ioemu/Makefile.target
    16.5  ===================================================================
    16.6 ---- ioemu.orig/Makefile.target	2006-08-06 02:14:04.797460093 +0100
    16.7 -+++ ioemu/Makefile.target	2006-08-06 02:14:09.794902973 +0100
    16.8 -@@ -302,7 +302,7 @@
    16.9 +--- ioemu.orig/Makefile.target	2006-12-08 01:41:05.000000000 +0000
   16.10 ++++ ioemu/Makefile.target	2006-12-08 01:41:10.000000000 +0000
   16.11 +@@ -303,7 +303,7 @@
   16.12   endif
   16.13   
   16.14   # must use static linking to avoid leaving stuff in virtual address space
   16.15 @@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
   16.16   VL_OBJS+=tap-win32.o
   16.17  Index: ioemu/configure
   16.18  ===================================================================
   16.19 ---- ioemu.orig/configure	2006-08-06 02:14:04.797460093 +0100
   16.20 -+++ ioemu/configure	2006-08-06 02:14:09.795902861 +0100
   16.21 +--- ioemu.orig/configure	2006-12-08 01:40:58.000000000 +0000
   16.22 ++++ ioemu/configure	2006-12-08 01:41:10.000000000 +0000
   16.23  @@ -75,8 +75,8 @@
   16.24   bigendian="no"
   16.25   mingw32="no"
   16.26 @@ -37,8 +37,8 @@ Index: ioemu/configure
   16.27     target_user_only="yes"
   16.28  Index: ioemu/cpu-all.h
   16.29  ===================================================================
   16.30 ---- ioemu.orig/cpu-all.h	2006-08-06 02:14:04.797460093 +0100
   16.31 -+++ ioemu/cpu-all.h	2006-08-06 02:14:09.796902750 +0100
   16.32 +--- ioemu.orig/cpu-all.h	2006-12-08 01:40:58.000000000 +0000
   16.33 ++++ ioemu/cpu-all.h	2006-12-08 01:41:10.000000000 +0000
   16.34  @@ -690,7 +690,9 @@
   16.35   void page_set_flags(target_ulong start, target_ulong end, int flags);
   16.36   void page_unprotect_range(target_ulong data, target_ulong data_size);
   16.37 @@ -64,8 +64,8 @@ Index: ioemu/cpu-all.h
   16.38   void cpu_dump_state(CPUState *env, FILE *f, 
   16.39  Index: ioemu/disas.h
   16.40  ===================================================================
   16.41 ---- ioemu.orig/disas.h	2006-08-06 02:14:04.797460093 +0100
   16.42 -+++ ioemu/disas.h	2006-08-06 02:14:09.796902750 +0100
   16.43 +--- ioemu.orig/disas.h	2006-12-08 01:40:58.000000000 +0000
   16.44 ++++ ioemu/disas.h	2006-12-08 01:41:10.000000000 +0000
   16.45  @@ -1,6 +1,7 @@
   16.46   #ifndef _QEMU_DISAS_H
   16.47   #define _QEMU_DISAS_H
   16.48 @@ -83,8 +83,8 @@ Index: ioemu/disas.h
   16.49   #endif /* _QEMU_DISAS_H */
   16.50  Index: ioemu/exec-all.h
   16.51  ===================================================================
   16.52 ---- ioemu.orig/exec-all.h	2006-08-06 02:14:04.798459982 +0100
   16.53 -+++ ioemu/exec-all.h	2006-08-06 02:14:09.796902750 +0100
   16.54 +--- ioemu.orig/exec-all.h	2006-12-08 01:40:58.000000000 +0000
   16.55 ++++ ioemu/exec-all.h	2006-12-08 01:41:10.000000000 +0000
   16.56  @@ -509,7 +509,7 @@
   16.57   
   16.58   extern int tb_invalidated_flag;
   16.59 @@ -105,8 +105,8 @@ Index: ioemu/exec-all.h
   16.60       return addr;
   16.61  Index: ioemu/hw/pc.c
   16.62  ===================================================================
   16.63 ---- ioemu.orig/hw/pc.c	2006-08-06 02:14:04.797460093 +0100
   16.64 -+++ ioemu/hw/pc.c	2006-08-06 02:14:09.797902638 +0100
   16.65 +--- ioemu.orig/hw/pc.c	2006-12-08 01:40:58.000000000 +0000
   16.66 ++++ ioemu/hw/pc.c	2006-12-08 01:41:10.000000000 +0000
   16.67  @@ -73,6 +73,7 @@
   16.68       }
   16.69   }
   16.70 @@ -184,8 +184,8 @@ Index: ioemu/hw/pc.c
   16.71           if (serial_hds[i]) {
   16.72  Index: ioemu/hw/vga_int.h
   16.73  ===================================================================
   16.74 ---- ioemu.orig/hw/vga_int.h	2006-08-06 02:14:04.797460093 +0100
   16.75 -+++ ioemu/hw/vga_int.h	2006-08-06 02:14:09.797902638 +0100
   16.76 +--- ioemu.orig/hw/vga_int.h	2006-12-08 01:40:58.000000000 +0000
   16.77 ++++ ioemu/hw/vga_int.h	2006-12-08 01:41:10.000000000 +0000
   16.78  @@ -28,7 +28,7 @@
   16.79   #define ST01_DISP_ENABLE    0x01
   16.80   
   16.81 @@ -197,8 +197,8 @@ Index: ioemu/hw/vga_int.h
   16.82   #define VBE_DISPI_MAX_YRES              1200
   16.83  Index: ioemu/monitor.c
   16.84  ===================================================================
   16.85 ---- ioemu.orig/monitor.c	2006-08-06 02:14:04.798459982 +0100
   16.86 -+++ ioemu/monitor.c	2006-08-06 02:14:49.574468309 +0100
   16.87 +--- ioemu.orig/monitor.c	2006-12-08 01:40:58.000000000 +0000
   16.88 ++++ ioemu/monitor.c	2006-12-08 01:41:10.000000000 +0000
   16.89  @@ -68,6 +68,12 @@
   16.90   
   16.91   void term_flush(void)
   16.92 @@ -429,8 +429,8 @@ Index: ioemu/monitor.c
   16.93   {
   16.94  Index: ioemu/vl.c
   16.95  ===================================================================
   16.96 ---- ioemu.orig/vl.c	2006-08-06 02:14:04.797460093 +0100
   16.97 -+++ ioemu/vl.c	2006-08-06 02:14:09.802902081 +0100
   16.98 +--- ioemu.orig/vl.c	2006-12-08 01:40:58.000000000 +0000
   16.99 ++++ ioemu/vl.c	2006-12-08 01:41:10.000000000 +0000
  16.100  @@ -422,12 +422,15 @@
  16.101   void hw_error(const char *fmt, ...)
  16.102   {
    17.1 --- a/tools/ioemu/patches/qemu-no-apic	Fri Dec 08 07:22:21 2006 -0800
    17.2 +++ b/tools/ioemu/patches/qemu-no-apic	Fri Dec 08 18:31:01 2006 +0000
    17.3 @@ -1,8 +1,8 @@
    17.4  Index: ioemu/Makefile.target
    17.5  ===================================================================
    17.6 ---- ioemu.orig/Makefile.target	2006-08-06 02:21:42.270461924 +0100
    17.7 -+++ ioemu/Makefile.target	2006-08-06 02:22:26.380544784 +0100
    17.8 -@@ -355,7 +355,7 @@
    17.9 +--- ioemu.orig/Makefile.target	2006-12-08 01:41:11.000000000 +0000
   17.10 ++++ ioemu/Makefile.target	2006-12-08 01:41:12.000000000 +0000
   17.11 +@@ -356,7 +356,7 @@
   17.12   # Hardware support
   17.13   VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
   17.14   VL_OBJS+= fdc.o mc146818rtc.o serial.o i8254.o pcspk.o pc.o
   17.15 @@ -13,8 +13,8 @@ Index: ioemu/Makefile.target
   17.16   endif
   17.17  Index: ioemu/hw/pc.c
   17.18  ===================================================================
   17.19 ---- ioemu.orig/hw/pc.c	2006-08-06 02:22:01.524315611 +0100
   17.20 -+++ ioemu/hw/pc.c	2006-08-06 02:22:11.875161758 +0100
   17.21 +--- ioemu.orig/hw/pc.c	2006-12-08 01:41:12.000000000 +0000
   17.22 ++++ ioemu/hw/pc.c	2006-12-08 01:41:12.000000000 +0000
   17.23  @@ -39,7 +39,9 @@
   17.24   static fdctrl_t *floppy_controller;
   17.25   static RTCState *rtc_state;
    18.1 --- a/tools/ioemu/patches/qemu-pci	Fri Dec 08 07:22:21 2006 -0800
    18.2 +++ b/tools/ioemu/patches/qemu-pci	Fri Dec 08 18:31:01 2006 +0000
    18.3 @@ -1,7 +1,7 @@
    18.4  Index: ioemu/hw/pci.c
    18.5  ===================================================================
    18.6 ---- ioemu.orig/hw/pci.c	2006-09-21 11:31:14.000000000 +0100
    18.7 -+++ ioemu/hw/pci.c	2006-09-21 11:31:32.000000000 +0100
    18.8 +--- ioemu.orig/hw/pci.c	2006-12-08 02:02:05.000000000 +0000
    18.9 ++++ ioemu/hw/pci.c	2006-12-08 18:16:55.000000000 +0000
   18.10  @@ -286,6 +286,7 @@
   18.11               case 0x0b:
   18.12               case 0x0e:
   18.13 @@ -31,8 +31,8 @@ Index: ioemu/hw/pci.c
   18.14           addr++;
   18.15  Index: ioemu/hw/rtl8139.c
   18.16  ===================================================================
   18.17 ---- ioemu.orig/hw/rtl8139.c	2006-09-21 11:31:14.000000000 +0100
   18.18 -+++ ioemu/hw/rtl8139.c	2006-09-21 11:31:32.000000000 +0100
   18.19 +--- ioemu.orig/hw/rtl8139.c	2006-12-08 02:02:05.000000000 +0000
   18.20 ++++ ioemu/hw/rtl8139.c	2006-12-08 18:16:47.000000000 +0000
   18.21  @@ -3423,6 +3423,8 @@
   18.22       pci_conf[0x0e] = 0x00; /* header_type */
   18.23       pci_conf[0x3d] = 1;    /* interrupt pin 0 */
   18.24 @@ -44,8 +44,8 @@ Index: ioemu/hw/rtl8139.c
   18.25   
   18.26  Index: ioemu/hw/usb-uhci.c
   18.27  ===================================================================
   18.28 ---- ioemu.orig/hw/usb-uhci.c	2006-09-21 11:31:14.000000000 +0100
   18.29 -+++ ioemu/hw/usb-uhci.c	2006-09-21 11:31:32.000000000 +0100
   18.30 +--- ioemu.orig/hw/usb-uhci.c	2006-12-08 02:02:05.000000000 +0000
   18.31 ++++ ioemu/hw/usb-uhci.c	2006-12-08 02:02:38.000000000 +0000
   18.32  @@ -659,6 +659,8 @@
   18.33       pci_conf[0x0e] = 0x00; // header_type
   18.34       pci_conf[0x3d] = 4; // interrupt pin 3
   18.35 @@ -55,3 +55,21 @@ Index: ioemu/hw/usb-uhci.c
   18.36       
   18.37       for(i = 0; i < NB_PORTS; i++) {
   18.38           qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
   18.39 +Index: ioemu/vl.h
   18.40 +===================================================================
   18.41 +--- ioemu.orig/vl.h	2006-12-08 18:16:47.000000000 +0000
   18.42 ++++ ioemu/vl.h	2006-12-08 18:16:55.000000000 +0000
   18.43 +@@ -650,8 +650,11 @@
   18.44 + #define PCI_MAX_LAT		0x3f	/* 8 bits */
   18.45 + 
   18.46 + struct PCIDevice {
   18.47 +-    /* PCI config space */
   18.48 +-    uint8_t config[256];
   18.49 ++    /*
   18.50 ++     * PCI config space. The 4 extra bytes are a safety buffer for guest
   18.51 ++     * word/dword writes that can extend past byte 0xff.
   18.52 ++     */
   18.53 ++    uint8_t config[256+4];
   18.54 + 
   18.55 +     /* the following fields are read only */
   18.56 +     PCIBus *bus;
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/ioemu/patches/qemu-serial-fixes	Fri Dec 08 18:31:01 2006 +0000
    19.3 @@ -0,0 +1,133 @@
    19.4 +# HG changeset patch
    19.5 +# User kfraser@localhost.localdomain
    19.6 +# Node ID c33272c2571c7bab7056d8228490700d1df405f9
    19.7 +# Parent  b3d94f4ddffefed8a5cb8dd65a60da9491d460e7
    19.8 +[HVM] Fix Qemu-dm serial issues:
    19.9 + 1. Retry transmit via a polling timer if a byte cannot be written
   19.10 +    immediately to its destination.
   19.11 + 2. Turn off output processing of raw serial lines.
   19.12 +
   19.13 +Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
   19.14 +Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
   19.15 +Signed-off-by: Keir Fraser <keir@xensource.com>
   19.16 +
   19.17 +Index: ioemu/vl.c
   19.18 +===================================================================
   19.19 +--- ioemu.orig/vl.c	2006-12-08 01:28:59.000000000 +0000
   19.20 ++++ ioemu/vl.c	2006-12-08 01:28:59.000000000 +0000
   19.21 +@@ -1684,7 +1684,7 @@
   19.22 + 
   19.23 +     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
   19.24 +                           |INLCR|IGNCR|ICRNL|IXON);
   19.25 +-    tty.c_oflag |= OPOST;
   19.26 ++    tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */
   19.27 +     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
   19.28 +     tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS);
   19.29 +     switch(data_bits) {
   19.30 +Index: ioemu/hw/serial.c
   19.31 +===================================================================
   19.32 +--- ioemu.orig/hw/serial.c	2006-12-08 01:28:17.000000000 +0000
   19.33 ++++ ioemu/hw/serial.c	2006-12-08 01:29:10.000000000 +0000
   19.34 +@@ -73,6 +73,11 @@
   19.35 + #define UART_LSR_OE	0x02	/* Overrun error indicator */
   19.36 + #define UART_LSR_DR	0x01	/* Receiver data ready */
   19.37 + 
   19.38 ++/* Maximum retries for a single byte transmit. */
   19.39 ++#define WRITE_MAX_SINGLE_RETRIES 3
   19.40 ++/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */
   19.41 ++#define WRITE_MAX_TOTAL_RETRIES 10
   19.42 ++
   19.43 + struct SerialState {
   19.44 +     uint8_t divider;
   19.45 +     uint8_t rbr; /* receive register */
   19.46 +@@ -93,6 +98,19 @@
   19.47 +     int last_break_enable;
   19.48 +     target_ulong base;
   19.49 +     int it_shift;
   19.50 ++
   19.51 ++    /*
   19.52 ++     * If a character transmitted via UART cannot be written to its
   19.53 ++     * destination immediately we remember it here and retry a few times via
   19.54 ++     * a polling timer.
   19.55 ++     *  - write_single_retries: Number of write retries for current byte.
   19.56 ++     *  - write_total_retries:  Number of write retries for back-to-back
   19.57 ++     *                          unsuccessful transmits.
   19.58 ++     */
   19.59 ++    int write_single_retries;
   19.60 ++    int write_total_retries;
   19.61 ++    char write_chr;
   19.62 ++    QEMUTimer *write_retry_timer;
   19.63 + };
   19.64 + 
   19.65 + static void serial_update_irq(SerialState *s)
   19.66 +@@ -204,10 +222,37 @@
   19.67 +     tokens_avail--;
   19.68 + }
   19.69 + 
   19.70 ++static void serial_chr_write(void *opaque)
   19.71 ++{
   19.72 ++    SerialState *s = opaque;
   19.73 ++
   19.74 ++    /* Cancel any outstanding retry if this is a new byte. */
   19.75 ++    qemu_del_timer(s->write_retry_timer);
   19.76 ++
   19.77 ++    /* Retry every 100ms for 300ms total. */
   19.78 ++    if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
   19.79 ++        s->write_total_retries++; 
   19.80 ++        if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES)
   19.81 ++            fprintf(stderr, "serial: write error\n");
   19.82 ++        else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) {
   19.83 ++            qemu_mod_timer(s->write_retry_timer,
   19.84 ++                           qemu_get_clock(vm_clock) + ticks_per_sec / 10);
   19.85 ++            return;
   19.86 ++        }
   19.87 ++    } else {
   19.88 ++        s->write_total_retries = 0;  /* if successful then reset counter */
   19.89 ++    }
   19.90 ++
   19.91 ++    /* Success: Notify guest that THR is empty. */
   19.92 ++    s->thr_ipending = 1;
   19.93 ++    s->lsr |= UART_LSR_THRE;
   19.94 ++    s->lsr |= UART_LSR_TEMT;
   19.95 ++    serial_update_irq(s);
   19.96 ++}
   19.97 ++
   19.98 + static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
   19.99 + {
  19.100 +     SerialState *s = opaque;
  19.101 +-    unsigned char ch;
  19.102 +     
  19.103 +     addr &= 7;
  19.104 + #ifdef DEBUG_SERIAL
  19.105 +@@ -223,12 +268,9 @@
  19.106 +             s->thr_ipending = 0;
  19.107 +             s->lsr &= ~UART_LSR_THRE;
  19.108 +             serial_update_irq(s);
  19.109 +-            ch = val;
  19.110 +-            qemu_chr_write(s->chr, &ch, 1);
  19.111 +-            s->thr_ipending = 1;
  19.112 +-            s->lsr |= UART_LSR_THRE;
  19.113 +-            s->lsr |= UART_LSR_TEMT;
  19.114 +-            serial_update_irq(s);
  19.115 ++            s->write_chr = val;
  19.116 ++            s->write_single_retries = 0;
  19.117 ++            serial_chr_write(s);
  19.118 +         }
  19.119 +         break;
  19.120 +     case 1:
  19.121 +@@ -424,6 +466,7 @@
  19.122 +     s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
  19.123 +     s->iir = UART_IIR_NO_INT;
  19.124 +     s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
  19.125 ++    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
  19.126 + 
  19.127 +     register_savevm("serial", base, 1, serial_save, serial_load, s);
  19.128 + 
  19.129 +@@ -511,6 +554,7 @@
  19.130 +     s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
  19.131 +     s->base = base;
  19.132 +     s->it_shift = it_shift;
  19.133 ++    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
  19.134 + 
  19.135 +     register_savevm("serial", base, 1, serial_save, serial_load, s);
  19.136 + 
    20.1 --- a/tools/ioemu/patches/qemu-target-i386-dm	Fri Dec 08 07:22:21 2006 -0800
    20.2 +++ b/tools/ioemu/patches/qemu-target-i386-dm	Fri Dec 08 18:31:01 2006 +0000
    20.3 @@ -1,7 +1,7 @@
    20.4  Index: ioemu/Makefile.target
    20.5  ===================================================================
    20.6 ---- ioemu.orig/Makefile.target	2006-10-24 13:47:23.000000000 +0100
    20.7 -+++ ioemu/Makefile.target	2006-10-24 14:30:56.000000000 +0100
    20.8 +--- ioemu.orig/Makefile.target	2006-12-08 01:41:10.000000000 +0000
    20.9 ++++ ioemu/Makefile.target	2006-12-08 01:41:11.000000000 +0000
   20.10  @@ -62,6 +62,8 @@
   20.11   QEMU_SYSTEM=qemu-fast
   20.12   endif
   20.13 @@ -11,7 +11,7 @@ Index: ioemu/Makefile.target
   20.14   ifdef CONFIG_USER_ONLY
   20.15   PROGS=$(QEMU_USER)
   20.16   else
   20.17 -@@ -291,6 +293,9 @@
   20.18 +@@ -292,6 +294,9 @@
   20.19   OBJS+=gdbstub.o
   20.20   endif
   20.21   
   20.22 @@ -21,7 +21,7 @@ Index: ioemu/Makefile.target
   20.23   all: $(PROGS)
   20.24   
   20.25   $(QEMU_USER): $(OBJS)
   20.26 -@@ -349,7 +354,7 @@
   20.27 +@@ -350,7 +355,7 @@
   20.28   ifeq ($(TARGET_BASE_ARCH), i386)
   20.29   # Hardware support
   20.30   VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
   20.31 @@ -32,8 +32,8 @@ Index: ioemu/Makefile.target
   20.32   DEFINES += -DHAS_AUDIO
   20.33  Index: ioemu/configure
   20.34  ===================================================================
   20.35 ---- ioemu.orig/configure	2006-10-24 13:47:23.000000000 +0100
   20.36 -+++ ioemu/configure	2006-10-24 14:29:34.000000000 +0100
   20.37 +--- ioemu.orig/configure	2006-12-08 01:41:10.000000000 +0000
   20.38 ++++ ioemu/configure	2006-12-08 01:41:11.000000000 +0000
   20.39  @@ -373,6 +373,8 @@
   20.40       if [ "$user" = "yes" ] ; then
   20.41           target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user $target_list"
   20.42 @@ -45,8 +45,8 @@ Index: ioemu/configure
   20.43   fi
   20.44  Index: ioemu/monitor.c
   20.45  ===================================================================
   20.46 ---- ioemu.orig/monitor.c	2006-10-24 13:47:23.000000000 +0100
   20.47 -+++ ioemu/monitor.c	2006-10-24 14:30:56.000000000 +0100
   20.48 +--- ioemu.orig/monitor.c	2006-12-08 01:41:10.000000000 +0000
   20.49 ++++ ioemu/monitor.c	2006-12-08 01:41:11.000000000 +0000
   20.50  @@ -1262,6 +1262,10 @@
   20.51         "", "show profiling information", },
   20.52       { "capture", "", do_info_capture,
   20.53 @@ -60,8 +60,8 @@ Index: ioemu/monitor.c
   20.54   
   20.55  Index: ioemu/vl.c
   20.56  ===================================================================
   20.57 ---- ioemu.orig/vl.c	2006-10-24 13:47:23.000000000 +0100
   20.58 -+++ ioemu/vl.c	2006-10-24 14:30:56.000000000 +0100
   20.59 +--- ioemu.orig/vl.c	2006-12-08 01:41:10.000000000 +0000
   20.60 ++++ ioemu/vl.c	2006-12-08 01:41:11.000000000 +0000
   20.61  @@ -87,7 +87,7 @@
   20.62   
   20.63   #include "exec-all.h"
   20.64 @@ -98,8 +98,8 @@ Index: ioemu/vl.c
   20.65   {
   20.66  Index: ioemu/vl.h
   20.67  ===================================================================
   20.68 ---- ioemu.orig/vl.h	2006-10-24 13:47:23.000000000 +0100
   20.69 -+++ ioemu/vl.h	2006-10-24 14:30:56.000000000 +0100
   20.70 +--- ioemu.orig/vl.h	2006-12-08 01:40:58.000000000 +0000
   20.71 ++++ ioemu/vl.h	2006-12-08 01:41:11.000000000 +0000
   20.72  @@ -37,6 +37,8 @@
   20.73   #include <unistd.h>
   20.74   #include <fcntl.h>
   20.75 @@ -132,8 +132,8 @@ Index: ioemu/vl.h
   20.76  Index: ioemu/target-i386-dm/cpu.h
   20.77  ===================================================================
   20.78  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
   20.79 -+++ ioemu/target-i386-dm/cpu.h	2006-10-24 14:30:56.000000000 +0100
   20.80 -@@ -0,0 +1,86 @@
   20.81 ++++ ioemu/target-i386-dm/cpu.h	2006-12-08 01:41:11.000000000 +0000
   20.82 +@@ -0,0 +1,84 @@
   20.83  +/*
   20.84  + * i386 virtual CPU header
   20.85  + * 
   20.86 @@ -191,8 +191,6 @@ Index: ioemu/target-i386-dm/cpu.h
   20.87  +    int interrupt_request;
   20.88  +
   20.89  +    CPU_COMMON
   20.90 -+
   20.91 -+    int send_event;
   20.92  +} CPUX86State;
   20.93  +
   20.94  +CPUX86State *cpu_x86_init(void);
   20.95 @@ -223,8 +221,8 @@ Index: ioemu/target-i386-dm/cpu.h
   20.96  Index: ioemu/target-i386-dm/exec-dm.c
   20.97  ===================================================================
   20.98  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
   20.99 -+++ ioemu/target-i386-dm/exec-dm.c	2006-10-24 14:30:56.000000000 +0100
  20.100 -@@ -0,0 +1,516 @@
  20.101 ++++ ioemu/target-i386-dm/exec-dm.c	2006-12-08 01:41:11.000000000 +0000
  20.102 +@@ -0,0 +1,546 @@
  20.103  +/*
  20.104  + *  virtual page mapping and translated block handling
  20.105  + * 
  20.106 @@ -259,6 +257,8 @@ Index: ioemu/target-i386-dm/exec-dm.c
  20.107  +#include <unistd.h>
  20.108  +#include <inttypes.h>
  20.109  +
  20.110 ++#include <xen/hvm/e820.h>
  20.111 ++
  20.112  +#include "cpu.h"
  20.113  +#include "exec-all.h"
  20.114  +
  20.115 @@ -568,6 +568,23 @@ Index: ioemu/target-i386-dm/exec-dm.c
  20.116  +    return io_mem_read[io_index >> IO_MEM_SHIFT];
  20.117  +}
  20.118  +
  20.119 ++#ifdef __ia64__
  20.120 ++/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
  20.121 ++ * So to emulate right behavior that guest OS is assumed, we need to flush
  20.122 ++ * I/D cache here.
  20.123 ++ */
  20.124 ++static void sync_icache(unsigned long address, int len)
  20.125 ++{
  20.126 ++    int l;
  20.127 ++
  20.128 ++    for(l = 0; l < (len + 32); l += 32)
  20.129 ++        __ia64_fc(address + l);
  20.130 ++
  20.131 ++    ia64_sync_i();
  20.132 ++    ia64_srlz_i();
  20.133 ++}
  20.134 ++#endif 
  20.135 ++
  20.136  +/* physical memory access (slow version, mainly for debug) */
  20.137  +#if defined(CONFIG_USER_ONLY)
  20.138  +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
  20.139 @@ -617,22 +634,36 @@ Index: ioemu/target-i386-dm/exec-dm.c
  20.140  +        return 0;
  20.141  +}
  20.142  +
  20.143 ++static inline int paddr_is_ram(target_phys_addr_t addr)
  20.144 ++{
  20.145 ++    /* Is this guest physical address RAM-backed? */
  20.146 ++#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__))
  20.147 ++    if (ram_size <= HVM_BELOW_4G_RAM_END)
  20.148 ++        /* RAM is contiguous */
  20.149 ++        return (addr < ram_size);
  20.150 ++    else
  20.151 ++        /* There is RAM below and above the MMIO hole */
  20.152 ++        return ((addr < HVM_BELOW_4G_MMIO_START) ||
  20.153 ++                ((addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH)
  20.154 ++                 && (addr < ram_size + HVM_BELOW_4G_MMIO_LENGTH)));
  20.155 ++#else
  20.156 ++    return (addr < ram_size);
  20.157 ++#endif
  20.158 ++}
  20.159 ++
  20.160  +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
  20.161  +                            int len, int is_write)
  20.162  +{
  20.163  +    int l, io_index;
  20.164  +    uint8_t *ptr;
  20.165  +    uint32_t val;
  20.166 -+    target_phys_addr_t page;
  20.167 -+    unsigned long pd;
  20.168  +    
  20.169  +    while (len > 0) {
  20.170 -+        page = addr & TARGET_PAGE_MASK;
  20.171 -+        l = (page + TARGET_PAGE_SIZE) - addr;
  20.172 ++        /* How much can we copy before the next page boundary? */
  20.173 ++        l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 
  20.174  +        if (l > len)
  20.175  +            l = len;
  20.176  +	
  20.177 -+        pd = page;
  20.178  +        io_index = iomem_index(addr);
  20.179  +        if (is_write) {
  20.180  +            if (io_index) {
  20.181 @@ -652,13 +683,12 @@ Index: ioemu/target-i386-dm/exec-dm.c
  20.182  +                    io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
  20.183  +                    l = 1;
  20.184  +                }
  20.185 -+            } else {
  20.186 -+                unsigned long addr1;
  20.187 -+
  20.188 -+                addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
  20.189 -+                /* RAM case */
  20.190 -+                ptr = phys_ram_base + addr1;
  20.191 -+                memcpy(ptr, buf, l);
  20.192 ++            } else if (paddr_is_ram(addr)) {
  20.193 ++                /* Reading from RAM */
  20.194 ++                memcpy(phys_ram_base + addr, buf, l);
  20.195 ++#ifdef __ia64__
  20.196 ++                sync_icache((unsigned long)(phys_ram_base + addr), l);
  20.197 ++#endif 
  20.198  +            }
  20.199  +        } else {
  20.200  +            if (io_index) {
  20.201 @@ -678,14 +708,12 @@ Index: ioemu/target-i386-dm/exec-dm.c
  20.202  +                    stb_raw(buf, val);
  20.203  +                    l = 1;
  20.204  +                }
  20.205 -+            } else if (addr < ram_size) {
  20.206 -+                /* RAM case */
  20.207 -+                ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
  20.208 -+                    (addr & ~TARGET_PAGE_MASK);
  20.209 -+                memcpy(buf, ptr, l);
  20.210 ++            } else if (paddr_is_ram(addr)) {
  20.211 ++                /* Reading from RAM */
  20.212 ++                memcpy(buf, phys_ram_base + addr, l);
  20.213  +            } else {
  20.214 -+                /* unreported MMIO space */
  20.215 -+                memset(buf, 0xff, len);
  20.216 ++                /* Neither RAM nor known MMIO space */
  20.217 ++                memset(buf, 0xff, len); 
  20.218  +            }
  20.219  +        }
  20.220  +        len -= l;
  20.221 @@ -744,8 +772,8 @@ Index: ioemu/target-i386-dm/exec-dm.c
  20.222  Index: ioemu/target-i386-dm/helper2.c
  20.223  ===================================================================
  20.224  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
  20.225 -+++ ioemu/target-i386-dm/helper2.c	2006-10-24 14:31:01.000000000 +0100
  20.226 -@@ -0,0 +1,469 @@
  20.227 ++++ ioemu/target-i386-dm/helper2.c	2006-12-08 01:41:11.000000000 +0000
  20.228 +@@ -0,0 +1,488 @@
  20.229  +/*
  20.230  + *  i386 helpers (without register variable usage)
  20.231  + *
  20.232 @@ -918,10 +946,10 @@ Index: ioemu/target-i386-dm/helper2.c
  20.233  +    for (i = 0; i < vcpus; i++) {
  20.234  +        req = &(shared_page->vcpu_iodata[i].vp_ioreq);
  20.235  +        term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
  20.236 -+        term_printf("  req state: %x, pvalid: %x, addr: %"PRIx64", "
  20.237 ++        term_printf("  req state: %x, ptr: %x, addr: %"PRIx64", "
  20.238  +                    "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
  20.239 -+                    req->state, req->pdata_valid, req->addr,
  20.240 -+                    req->u.data, req->count, req->size);
  20.241 ++                    req->state, req->data_is_ptr, req->addr,
  20.242 ++                    req->data, req->count, req->size);
  20.243  +        term_printf("  IO totally occurred on this vcpu: %"PRIx64"\n",
  20.244  +                    req->io_count);
  20.245  +    }
  20.246 @@ -934,18 +962,19 @@ Index: ioemu/target-i386-dm/helper2.c
  20.247  +
  20.248  +    req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
  20.249  +
  20.250 -+    if (req->state == STATE_IOREQ_READY) {
  20.251 -+        req->state = STATE_IOREQ_INPROCESS;
  20.252 -+        rmb();
  20.253 -+        return req;
  20.254 ++    if (req->state != STATE_IOREQ_READY) {
  20.255 ++        fprintf(logfile, "I/O request not ready: "
  20.256 ++                "%x, ptr: %x, port: %"PRIx64", "
  20.257 ++                "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
  20.258 ++                req->state, req->data_is_ptr, req->addr,
  20.259 ++                req->data, req->count, req->size);
  20.260 ++        return NULL;
  20.261  +    }
  20.262  +
  20.263 -+    fprintf(logfile, "False I/O request ... in-service already: "
  20.264 -+            "%x, pvalid: %x, port: %"PRIx64", "
  20.265 -+            "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
  20.266 -+            req->state, req->pdata_valid, req->addr,
  20.267 -+            req->u.data, req->count, req->size);
  20.268 -+    return NULL;
  20.269 ++    rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
  20.270 ++
  20.271 ++    req->state = STATE_IOREQ_INPROCESS;
  20.272 ++    return req;
  20.273  +}
  20.274  +
  20.275  +//use poll to get the port notification
  20.276 @@ -1030,26 +1059,26 @@ Index: ioemu/target-i386-dm/helper2.c
  20.277  +    sign = req->df ? -1 : 1;
  20.278  +
  20.279  +    if (req->dir == IOREQ_READ) {
  20.280 -+        if (!req->pdata_valid) {
  20.281 -+            req->u.data = do_inp(env, req->addr, req->size);
  20.282 ++        if (!req->data_is_ptr) {
  20.283 ++            req->data = do_inp(env, req->addr, req->size);
  20.284  +        } else {
  20.285  +            unsigned long tmp;
  20.286  +
  20.287  +            for (i = 0; i < req->count; i++) {
  20.288  +                tmp = do_inp(env, req->addr, req->size);
  20.289 -+                write_physical((target_phys_addr_t) req->u.pdata
  20.290 ++                write_physical((target_phys_addr_t) req->data
  20.291  +                  + (sign * i * req->size),
  20.292  +                  req->size, &tmp);
  20.293  +            }
  20.294  +        }
  20.295  +    } else if (req->dir == IOREQ_WRITE) {
  20.296 -+        if (!req->pdata_valid) {
  20.297 -+            do_outp(env, req->addr, req->size, req->u.data);
  20.298 ++        if (!req->data_is_ptr) {
  20.299 ++            do_outp(env, req->addr, req->size, req->data);
  20.300  +        } else {
  20.301  +            for (i = 0; i < req->count; i++) {
  20.302  +                unsigned long tmp;
  20.303  +
  20.304 -+                read_physical((target_phys_addr_t) req->u.pdata
  20.305 ++                read_physical((target_phys_addr_t) req->data
  20.306  +                  + (sign * i * req->size),
  20.307  +                  req->size, &tmp);
  20.308  +                do_outp(env, req->addr, req->size, tmp);
  20.309 @@ -1064,18 +1093,18 @@ Index: ioemu/target-i386-dm/helper2.c
  20.310  +
  20.311  +    sign = req->df ? -1 : 1;
  20.312  +
  20.313 -+    if (!req->pdata_valid) {
  20.314 ++    if (!req->data_is_ptr) {
  20.315  +        if (req->dir == IOREQ_READ) {
  20.316  +            for (i = 0; i < req->count; i++) {
  20.317  +                read_physical(req->addr
  20.318  +                  + (sign * i * req->size),
  20.319 -+                  req->size, &req->u.data);
  20.320 ++                  req->size, &req->data);
  20.321  +            }
  20.322  +        } else if (req->dir == IOREQ_WRITE) {
  20.323  +            for (i = 0; i < req->count; i++) {
  20.324  +                write_physical(req->addr
  20.325  +                  + (sign * i * req->size),
  20.326 -+                  req->size, &req->u.data);
  20.327 ++                  req->size, &req->data);
  20.328  +            }
  20.329  +        }
  20.330  +    } else {
  20.331 @@ -1086,13 +1115,13 @@ Index: ioemu/target-i386-dm/helper2.c
  20.332  +                read_physical(req->addr
  20.333  +                  + (sign * i * req->size),
  20.334  +                  req->size, &tmp);
  20.335 -+                write_physical((target_phys_addr_t )req->u.pdata
  20.336 ++                write_physical((target_phys_addr_t )req->data
  20.337  +                  + (sign * i * req->size),
  20.338  +                  req->size, &tmp);
  20.339  +            }
  20.340  +        } else if (req->dir == IOREQ_WRITE) {
  20.341  +            for (i = 0; i < req->count; i++) {
  20.342 -+                read_physical((target_phys_addr_t) req->u.pdata
  20.343 ++                read_physical((target_phys_addr_t) req->data
  20.344  +                  + (sign * i * req->size),
  20.345  +                  req->size, &tmp);
  20.346  +                write_physical(req->addr
  20.347 @@ -1107,45 +1136,60 @@ Index: ioemu/target-i386-dm/helper2.c
  20.348  +{
  20.349  +    unsigned long tmp1, tmp2;
  20.350  +
  20.351 -+    if (req->pdata_valid != 0)
  20.352 ++    if (req->data_is_ptr != 0)
  20.353  +        hw_error("expected scalar value");
  20.354  +
  20.355  +    read_physical(req->addr, req->size, &tmp1);
  20.356  +    if (req->dir == IOREQ_WRITE) {
  20.357 -+        tmp2 = tmp1 & (unsigned long) req->u.data;
  20.358 ++        tmp2 = tmp1 & (unsigned long) req->data;
  20.359  +        write_physical(req->addr, req->size, &tmp2);
  20.360  +    }
  20.361 -+    req->u.data = tmp1;
  20.362 ++    req->data = tmp1;
  20.363 ++}
  20.364 ++
  20.365 ++void cpu_ioreq_add(CPUState *env, ioreq_t *req)
  20.366 ++{
  20.367 ++    unsigned long tmp1, tmp2;
  20.368 ++
  20.369 ++    if (req->data_is_ptr != 0)
  20.370 ++        hw_error("expected scalar value");
  20.371 ++
  20.372 ++    read_physical(req->addr, req->size, &tmp1);
  20.373 ++    if (req->dir == IOREQ_WRITE) {
  20.374 ++        tmp2 = tmp1 + (unsigned long) req->data;
  20.375 ++        write_physical(req->addr, req->size, &tmp2);
  20.376 ++    }
  20.377 ++    req->data = tmp1;
  20.378  +}
  20.379  +
  20.380  +void cpu_ioreq_or(CPUState *env, ioreq_t *req)
  20.381  +{
  20.382  +    unsigned long tmp1, tmp2;
  20.383  +
  20.384 -+    if (req->pdata_valid != 0)
  20.385 ++    if (req->data_is_ptr != 0)
  20.386  +        hw_error("expected scalar value");
  20.387  +
  20.388  +    read_physical(req->addr, req->size, &tmp1);
  20.389  +    if (req->dir == IOREQ_WRITE) {
  20.390 -+        tmp2 = tmp1 | (unsigned long) req->u.data;
  20.391 ++        tmp2 = tmp1 | (unsigned long) req->data;
  20.392  +        write_physical(req->addr, req->size, &tmp2);
  20.393  +    }
  20.394 -+    req->u.data = tmp1;
  20.395 ++    req->data = tmp1;
  20.396  +}
  20.397  +
  20.398  +void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
  20.399  +{
  20.400  +    unsigned long tmp1, tmp2;
  20.401  +
  20.402 -+    if (req->pdata_valid != 0)
  20.403 ++    if (req->data_is_ptr != 0)
  20.404  +        hw_error("expected scalar value");
  20.405  +
  20.406  +    read_physical(req->addr, req->size, &tmp1);
  20.407  +    if (req->dir == IOREQ_WRITE) {
  20.408 -+        tmp2 = tmp1 ^ (unsigned long) req->u.data;
  20.409 ++        tmp2 = tmp1 ^ (unsigned long) req->data;
  20.410  +        write_physical(req->addr, req->size, &tmp2);
  20.411  +    }
  20.412 -+    req->u.data = tmp1;
  20.413 ++    req->data = tmp1;
  20.414  +}
  20.415  +
  20.416  +void cpu_handle_ioreq(void *opaque)
  20.417 @@ -1154,9 +1198,9 @@ Index: ioemu/target-i386-dm/helper2.c
  20.418  +    ioreq_t *req = cpu_get_ioreq();
  20.419  +
  20.420  +    if (req) {
  20.421 -+        if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
  20.422 ++        if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) {
  20.423  +            if (req->size != 4)
  20.424 -+                req->u.data &= (1UL << (8 * req->size))-1;
  20.425 ++                req->data &= (1UL << (8 * req->size))-1;
  20.426  +        }
  20.427  +
  20.428  +        switch (req->type) {
  20.429 @@ -1169,6 +1213,9 @@ Index: ioemu/target-i386-dm/helper2.c
  20.430  +        case IOREQ_TYPE_AND:
  20.431  +            cpu_ioreq_and(env, req);
  20.432  +            break;
  20.433 ++        case IOREQ_TYPE_ADD:
  20.434 ++            cpu_ioreq_add(env, req);
  20.435 ++            break;
  20.436  +        case IOREQ_TYPE_OR:
  20.437  +            cpu_ioreq_or(env, req);
  20.438  +            break;
  20.439 @@ -1179,12 +1226,19 @@ Index: ioemu/target-i386-dm/helper2.c
  20.440  +            hw_error("Invalid ioreq type 0x%x\n", req->type);
  20.441  +        }
  20.442  +
  20.443 -+        /* No state change if state = STATE_IORESP_HOOK */
  20.444 -+        if (req->state == STATE_IOREQ_INPROCESS) {
  20.445 -+            mb();
  20.446 -+            req->state = STATE_IORESP_READY;
  20.447 ++        if (req->state != STATE_IOREQ_INPROCESS) {
  20.448 ++            fprintf(logfile, "Badness in I/O request ... not in service?!: "
  20.449 ++                    "%x, ptr: %x, port: %"PRIx64", "
  20.450 ++                    "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
  20.451 ++                    req->state, req->data_is_ptr, req->addr,
  20.452 ++                    req->data, req->count, req->size);
  20.453 ++            destroy_hvm_domain();
  20.454 ++            return;
  20.455  +        }
  20.456 -+        env->send_event = 1;
  20.457 ++
  20.458 ++        wmb(); /* Update ioreq contents /then/ update state. */
  20.459 ++        req->state = STATE_IORESP_READY;
  20.460 ++        xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
  20.461  +    }
  20.462  +}
  20.463  +
  20.464 @@ -1197,8 +1251,6 @@ Index: ioemu/target-i386-dm/helper2.c
  20.465  +
  20.466  +    qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
  20.467  +
  20.468 -+    env->send_event = 0;
  20.469 -+
  20.470  +    while (1) {
  20.471  +        if (vm_running) {
  20.472  +            if (shutdown_requested)
  20.473 @@ -1207,19 +1259,14 @@ Index: ioemu/target-i386-dm/helper2.c
  20.474  +
  20.475  +        /* Wait up to 10 msec. */
  20.476  +        main_loop_wait(10);
  20.477 -+
  20.478 -+        if (env->send_event) {
  20.479 -+            env->send_event = 0;
  20.480 -+            xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
  20.481 -+        }
  20.482  +    }
  20.483  +    return 0;
  20.484  +}
  20.485  Index: ioemu/target-i386-dm/i8259-dm.c
  20.486  ===================================================================
  20.487  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
  20.488 -+++ ioemu/target-i386-dm/i8259-dm.c	2006-10-24 13:47:23.000000000 +0100
  20.489 -@@ -0,0 +1,107 @@
  20.490 ++++ ioemu/target-i386-dm/i8259-dm.c	2006-12-08 01:41:11.000000000 +0000
  20.491 +@@ -0,0 +1,67 @@
  20.492  +/* Xen 8259 stub for interrupt controller emulation
  20.493  + * 
  20.494  + * Copyright (c) 2003-2004 Fabrice Bellard
  20.495 @@ -1244,58 +1291,18 @@ Index: ioemu/target-i386-dm/i8259-dm.c
  20.496  + * THE SOFTWARE.
  20.497  + */
  20.498  +#include "vl.h"
  20.499 -+
  20.500 -+/* debug PIC */
  20.501 -+//#define DEBUG_PIC
  20.502 -+
  20.503 -+//#define DEBUG_IRQ_LATENCY
  20.504 -+//#define DEBUG_IRQ_COUNT
  20.505 -+
  20.506  +#include "xenctrl.h"
  20.507  +#include <xen/hvm/ioreq.h>
  20.508  +#include <stdio.h>
  20.509  +#include "cpu.h"
  20.510  +#include "cpu-all.h"
  20.511  +
  20.512 -+extern shared_iopage_t *shared_page;
  20.513 -+
  20.514  +struct PicState2 {
  20.515  +};
  20.516  +
  20.517  +void pic_set_irq_new(void *opaque, int irq, int level)
  20.518  +{
  20.519 -+    /* PicState2 *s = opaque; */
  20.520 -+    global_iodata_t  *gio;
  20.521 -+    int  mask;
  20.522 -+
  20.523 -+    gio = &shared_page->sp_global;
  20.524 -+    mask = 1 << irq;
  20.525 -+    if ( gio->pic_elcr & mask ) {
  20.526 -+        /* level */
  20.527 -+       if ( level ) {
  20.528 -+           atomic_clear_bit(irq, &gio->pic_clear_irr);
  20.529 -+           atomic_set_bit(irq, &gio->pic_irr);
  20.530 -+           cpu_single_env->send_event = 1;
  20.531 -+       }
  20.532 -+       else {
  20.533 -+           atomic_clear_bit(irq, &gio->pic_irr);
  20.534 -+           atomic_set_bit(irq, &gio->pic_clear_irr);
  20.535 -+           cpu_single_env->send_event = 1;
  20.536 -+       }
  20.537 -+    }
  20.538 -+    else {
  20.539 -+       /* edge */
  20.540 -+       if ( level ) {
  20.541 -+           if ( (mask & gio->pic_last_irr) == 0 ) { 
  20.542 -+               atomic_set_bit(irq, &gio->pic_irr);
  20.543 -+               atomic_set_bit(irq, &gio->pic_last_irr);
  20.544 -+               cpu_single_env->send_event = 1;
  20.545 -+           }
  20.546 -+       }
  20.547 -+       else {
  20.548 -+           atomic_clear_bit(irq, &gio->pic_last_irr);
  20.549 -+       }
  20.550 -+    }
  20.551 ++    xc_hvm_set_irq_level(xc_handle, domid, irq, level);
  20.552  +}
  20.553  +
  20.554  +/* obsolete function */
  20.555 @@ -1330,17 +1337,22 @@ Index: ioemu/target-i386-dm/i8259-dm.c
  20.556  Index: ioemu/target-i386-dm/qemu-dm.debug
  20.557  ===================================================================
  20.558  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
  20.559 -+++ ioemu/target-i386-dm/qemu-dm.debug	2006-10-24 13:47:23.000000000 +0100
  20.560 -@@ -0,0 +1,5 @@
  20.561 ++++ ioemu/target-i386-dm/qemu-dm.debug	2006-12-08 01:41:11.000000000 +0000
  20.562 +@@ -0,0 +1,10 @@
  20.563  +#!/bin/sh
  20.564  +
  20.565 ++if [ "`arch`" = "x86_64" ]; then
  20.566 ++    LIBDIR="lib64"
  20.567 ++else
  20.568 ++    LIBDIR="lib"
  20.569 ++fi
  20.570  +echo $* > /tmp/args
  20.571  +echo $DISPLAY >> /tmp/args
  20.572 -+exec /usr/lib/xen/bin/qemu-dm $*
  20.573 ++exec /usr/$LIBDIR/xen/bin/qemu-dm $*
  20.574  Index: ioemu/target-i386-dm/qemu-ifup
  20.575  ===================================================================
  20.576  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
  20.577 -+++ ioemu/target-i386-dm/qemu-ifup	2006-10-24 13:47:23.000000000 +0100
  20.578 ++++ ioemu/target-i386-dm/qemu-ifup	2006-12-08 01:41:11.000000000 +0000
  20.579  @@ -0,0 +1,10 @@
  20.580  +#!/bin/sh
  20.581  +
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/ioemu/patches/remove-pci-bridge-setup	Fri Dec 08 18:31:01 2006 +0000
    21.3 @@ -0,0 +1,289 @@
    21.4 +# HG changeset patch
    21.5 +# User kfraser@localhost.localdomain
    21.6 +# Node ID a8d31d5ce2589762c3226185deeca3afca47a698
    21.7 +# Parent  b8cc9ffda0a3dc449b026c72c97f78dea2e6f114
    21.8 +[HVM] Move PCI and PCI-ISA bridge setup to hvmloader.
    21.9 +Signed-off-by: Keir Fraser <keir@xensource.com>
   21.10 +
   21.11 +Index: ioemu/target-i386-dm/piix_pci-dm.c
   21.12 +===================================================================
   21.13 +--- ioemu.orig/target-i386-dm/piix_pci-dm.c	2006-12-08 18:22:35.000000000 +0000
   21.14 ++++ ioemu/target-i386-dm/piix_pci-dm.c	2006-12-08 18:22:50.000000000 +0000
   21.15 +@@ -84,12 +84,6 @@
   21.16 + 
   21.17 + static PCIDevice *piix3_dev;
   21.18 + 
   21.19 +-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
   21.20 +-{
   21.21 +-    /* This is the barber's pole mapping used by Xen. */
   21.22 +-    return (irq_num + (pci_dev->devfn >> 3)) & 3;
   21.23 +-}
   21.24 +-
   21.25 + static void piix3_write_config(PCIDevice *d, 
   21.26 +                                uint32_t address, uint32_t val, int len)
   21.27 + {
   21.28 +@@ -114,12 +108,9 @@
   21.29 +     uint8_t *pci_conf = d->config;
   21.30 + 
   21.31 +     pci_conf[0x04] = 0x07; // master, memory and I/O
   21.32 +-    pci_conf[0x05] = 0x00;
   21.33 +-    pci_conf[0x06] = 0x00;
   21.34 +     pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
   21.35 +     pci_conf[0x4c] = 0x4d;
   21.36 +     pci_conf[0x4e] = 0x03;
   21.37 +-    pci_conf[0x4f] = 0x00;
   21.38 +     pci_conf[0x60] = 0x80;
   21.39 +     pci_conf[0x61] = 0x80;
   21.40 +     pci_conf[0x62] = 0x80;
   21.41 +@@ -129,22 +120,9 @@
   21.42 +     pci_conf[0x76] = 0x0c;
   21.43 +     pci_conf[0x77] = 0x0c;
   21.44 +     pci_conf[0x78] = 0x02;
   21.45 +-    pci_conf[0x79] = 0x00;
   21.46 +-    pci_conf[0x80] = 0x00;
   21.47 +-    pci_conf[0x82] = 0x00;
   21.48 +     pci_conf[0xa0] = 0x08;
   21.49 +     pci_conf[0xa0] = 0x08;
   21.50 +-    pci_conf[0xa2] = 0x00;
   21.51 +-    pci_conf[0xa3] = 0x00;
   21.52 +-    pci_conf[0xa4] = 0x00;
   21.53 +-    pci_conf[0xa5] = 0x00;
   21.54 +-    pci_conf[0xa6] = 0x00;
   21.55 +-    pci_conf[0xa7] = 0x00;
   21.56 +     pci_conf[0xa8] = 0x0f;
   21.57 +-    pci_conf[0xaa] = 0x00;
   21.58 +-    pci_conf[0xab] = 0x00;
   21.59 +-    pci_conf[0xac] = 0x00;
   21.60 +-    pci_conf[0xae] = 0x00;
   21.61 + }
   21.62 + 
   21.63 + int piix3_init(PCIBus *bus)
   21.64 +@@ -171,227 +149,4 @@
   21.65 +     return d->devfn;
   21.66 + }
   21.67 + 
   21.68 +-/***********************************************************/
   21.69 +-/* XXX: the following should be moved to the PC BIOS */
   21.70 +-
   21.71 +-static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
   21.72 +-{
   21.73 +-    return cpu_inb(NULL, addr);
   21.74 +-}
   21.75 +-
   21.76 +-static void isa_outb(uint32_t val, uint32_t addr)
   21.77 +-{
   21.78 +-    cpu_outb(NULL, addr, val);
   21.79 +-}
   21.80 +-
   21.81 +-static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
   21.82 +-{
   21.83 +-    return cpu_inw(NULL, addr);
   21.84 +-}
   21.85 +-
   21.86 +-static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
   21.87 +-{
   21.88 +-    cpu_outw(NULL, addr, val);
   21.89 +-}
   21.90 +-
   21.91 +-static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
   21.92 +-{
   21.93 +-    return cpu_inl(NULL, addr);
   21.94 +-}
   21.95 +-
   21.96 +-static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
   21.97 +-{
   21.98 +-    cpu_outl(NULL, addr, val);
   21.99 +-}
  21.100 +-
  21.101 +-static uint32_t pci_bios_io_addr;
  21.102 +-static uint32_t pci_bios_mem_addr;
  21.103 +-/* host irqs corresponding to PCI irqs A-D */
  21.104 +-static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
  21.105 +-
  21.106 +-static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
  21.107 +-{
  21.108 +-    PCIBus *s = d->bus;
  21.109 +-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  21.110 +-    pci_data_write(s, addr, val, 4);
  21.111 +-}
  21.112 +-
  21.113 +-static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
  21.114 +-{
  21.115 +-    PCIBus *s = d->bus;
  21.116 +-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  21.117 +-    pci_data_write(s, addr, val, 2);
  21.118 +-}
  21.119 +-
  21.120 +-static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
  21.121 +-{
  21.122 +-    PCIBus *s = d->bus;
  21.123 +-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  21.124 +-    pci_data_write(s, addr, val, 1);
  21.125 +-}
  21.126 +-
  21.127 +-static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
  21.128 +-{
  21.129 +-    PCIBus *s = d->bus;
  21.130 +-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  21.131 +-    return pci_data_read(s, addr, 4);
  21.132 +-}
  21.133 +-
  21.134 +-static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
  21.135 +-{
  21.136 +-    PCIBus *s = d->bus;
  21.137 +-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  21.138 +-    return pci_data_read(s, addr, 2);
  21.139 +-}
  21.140 +-
  21.141 +-static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
  21.142 +-{
  21.143 +-    PCIBus *s = d->bus;
  21.144 +-    addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  21.145 +-    return pci_data_read(s, addr, 1);
  21.146 +-}
  21.147 +-
  21.148 +-static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
  21.149 +-{
  21.150 +-    PCIIORegion *r;
  21.151 +-    uint16_t cmd;
  21.152 +-    uint32_t ofs;
  21.153 +-
  21.154 +-    if ( region_num == PCI_ROM_SLOT ) {
  21.155 +-        ofs = 0x30;
  21.156 +-    }else{
  21.157 +-        ofs = 0x10 + region_num * 4;
  21.158 +-    }
  21.159 +-
  21.160 +-    pci_config_writel(d, ofs, addr);
  21.161 +-    r = &d->io_regions[region_num];
  21.162 +-
  21.163 +-    /* enable memory mappings */
  21.164 +-    cmd = pci_config_readw(d, PCI_COMMAND);
  21.165 +-    if ( region_num == PCI_ROM_SLOT )
  21.166 +-        cmd |= 2;
  21.167 +-    else if (r->type & PCI_ADDRESS_SPACE_IO)
  21.168 +-        cmd |= 1;
  21.169 +-    else
  21.170 +-        cmd |= 2;
  21.171 +-    pci_config_writew(d, PCI_COMMAND, cmd);
  21.172 +-}
  21.173 +-
  21.174 +-static void pci_bios_init_device(PCIDevice *d)
  21.175 +-{
  21.176 +-    int class;
  21.177 +-    PCIIORegion *r;
  21.178 +-    uint32_t *paddr;
  21.179 +-    int i, pin, pic_irq, vendor_id, device_id;
  21.180 +-
  21.181 +-    class = pci_config_readw(d, PCI_CLASS_DEVICE);
  21.182 +-    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
  21.183 +-    device_id = pci_config_readw(d, PCI_DEVICE_ID);
  21.184 +-    switch(class) {
  21.185 +-    case 0x0101:
  21.186 +-        if (vendor_id == 0x8086 && device_id == 0x7010) {
  21.187 +-            /* PIIX3 IDE */
  21.188 +-            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
  21.189 +-            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
  21.190 +-            goto default_map;
  21.191 +-        } else {
  21.192 +-            /* IDE: we map it as in ISA mode */
  21.193 +-            pci_set_io_region_addr(d, 0, 0x1f0);
  21.194 +-            pci_set_io_region_addr(d, 1, 0x3f4);
  21.195 +-            pci_set_io_region_addr(d, 2, 0x170);
  21.196 +-            pci_set_io_region_addr(d, 3, 0x374);
  21.197 +-        }
  21.198 +-        break;
  21.199 +-    case 0x0680:
  21.200 +-        if (vendor_id == 0x8086 && device_id == 0x7113) {
  21.201 +-            /*
  21.202 +-             * PIIX4 ACPI PM.
  21.203 +-             * Special device with special PCI config space. No ordinary BARs.
  21.204 +-             */
  21.205 +-            pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
  21.206 +-            pci_config_writew(d, 0x22, 0x0000);
  21.207 +-            pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
  21.208 +-            pci_config_writew(d, 0x3d, 0x0001);
  21.209 +-        }
  21.210 +-        break;
  21.211 +-    case 0x0300:
  21.212 +-        if (vendor_id != 0x1234)
  21.213 +-            goto default_map;
  21.214 +-        /* VGA: map frame buffer to default Bochs VBE address */
  21.215 +-        pci_set_io_region_addr(d, 0, 0xE0000000);
  21.216 +-        break;
  21.217 +-    case 0x0800:
  21.218 +-        /* PIC */
  21.219 +-        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
  21.220 +-        device_id = pci_config_readw(d, PCI_DEVICE_ID);
  21.221 +-        if (vendor_id == 0x1014) {
  21.222 +-            /* IBM */
  21.223 +-            if (device_id == 0x0046 || device_id == 0xFFFF) {
  21.224 +-                /* MPIC & MPIC2 */
  21.225 +-                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
  21.226 +-            }
  21.227 +-        }
  21.228 +-        break;
  21.229 +-    case 0xff00:
  21.230 +-        if (vendor_id == 0x0106b &&
  21.231 +-            (device_id == 0x0017 || device_id == 0x0022)) {
  21.232 +-            /* macio bridge */
  21.233 +-            pci_set_io_region_addr(d, 0, 0x80800000);
  21.234 +-        }
  21.235 +-        break;
  21.236 +-    default:
  21.237 +-    default_map:
  21.238 +-        /* default memory mappings */
  21.239 +-        for(i = 0; i < PCI_NUM_REGIONS; i++) {
  21.240 +-            r = &d->io_regions[i];
  21.241 +-            if (r->size) {
  21.242 +-                if (r->type & PCI_ADDRESS_SPACE_IO)
  21.243 +-                    paddr = &pci_bios_io_addr;
  21.244 +-                else
  21.245 +-                    paddr = &pci_bios_mem_addr;
  21.246 +-                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
  21.247 +-                pci_set_io_region_addr(d, i, *paddr);
  21.248 +-                *paddr += r->size;
  21.249 +-            }
  21.250 +-        }
  21.251 +-        break;
  21.252 +-    }
  21.253 +-
  21.254 +-    /* map the interrupt */
  21.255 +-    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
  21.256 +-    if (pin != 0) {
  21.257 +-        pin = pci_slot_get_pirq(d, pin - 1);
  21.258 +-        pic_irq = pci_irqs[pin];
  21.259 +-        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
  21.260 +-    }
  21.261 +-}
  21.262 +-
  21.263 +-/*
  21.264 +- * This function initializes the PCI devices as a normal PCI BIOS
  21.265 +- * would do. It is provided just in case the BIOS has no support for
  21.266 +- * PCI.
  21.267 +- */
  21.268 +-void pci_bios_init(void)
  21.269 +-{
  21.270 +-    int i, irq;
  21.271 +-    uint8_t elcr[2];
  21.272 +-
  21.273 +-    pci_bios_io_addr = 0xc000;
  21.274 +-    pci_bios_mem_addr = HVM_BELOW_4G_MMIO_START;
  21.275 +-
  21.276 +-    /* activate IRQ mappings */
  21.277 +-    elcr[0] = 0x00;
  21.278 +-    elcr[1] = 0x00;
  21.279 +-    for(i = 0; i < 4; i++) {
  21.280 +-        irq = pci_irqs[i];
  21.281 +-        /* set to trigger level */
  21.282 +-        elcr[irq >> 3] |= (1 << (irq & 7));
  21.283 +-        /* activate irq remapping in PIIX */
  21.284 +-        pci_config_writeb(piix3_dev, 0x60 + i, irq);
  21.285 +-    }
  21.286 +-    isa_outb(elcr[0], 0x4d0);
  21.287 +-    isa_outb(elcr[1], 0x4d1);
  21.288 +-
  21.289 +-    pci_for_each_device(pci_bios_init_device);
  21.290 +-}
  21.291 +-
  21.292 ++void pci_bios_init(void) {}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/ioemu/patches/rtl8139-bound-chaining	Fri Dec 08 18:31:01 2006 +0000
    22.3 @@ -0,0 +1,36 @@
    22.4 +# HG changeset patch
    22.5 +# User kfraser@localhost.localdomain
    22.6 +# Node ID 075f4ffdbbce5527ba525a515abe320703d17a0e
    22.7 +# Parent  51edd3c6a4d861db6ce1c9a02251ed49213c3002
    22.8 +[QEMU] rtl8139: Disallow chaining above 64K
    22.9 +
   22.10 +As it stands the 8139C+ TX chaining is only bounded by realloc failure.
   22.11 +This is contrary to how the real hardware operates.  It also has DoS
   22.12 +potential when ioemu runs in dom0.
   22.13 +
   22.14 +This patch makes any attempt to chain a frame beyond 64K fail
   22.15 +immediately.
   22.16 +
   22.17 +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
   22.18 +
   22.19 +Index: ioemu/hw/rtl8139.c
   22.20 +===================================================================
   22.21 +--- ioemu.orig/hw/rtl8139.c	2006-12-08 18:21:36.000000000 +0000
   22.22 ++++ ioemu/hw/rtl8139.c	2006-12-08 18:22:22.000000000 +0000
   22.23 +@@ -1999,12 +1999,12 @@
   22.24 +         DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len));
   22.25 +     }
   22.26 + 
   22.27 +-    while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
   22.28 ++    if (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
   22.29 +     {
   22.30 +-        s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
   22.31 +-        s->cplus_txbuffer = realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
   22.32 ++	free(s->cplus_txbuffer);
   22.33 ++	s->cplus_txbuffer = NULL;
   22.34 + 
   22.35 +-        DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len));
   22.36 ++	DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space exceeded: %d\n", s->cplus_txbuffer_offset + txsize));
   22.37 +     }
   22.38 + 
   22.39 +     if (!s->cplus_txbuffer)
    23.1 --- a/tools/ioemu/patches/series	Fri Dec 08 07:22:21 2006 -0800
    23.2 +++ b/tools/ioemu/patches/series	Fri Dec 08 18:31:01 2006 +0000
    23.3 @@ -53,3 +53,17 @@ serial-port-rate-limit
    23.4  hypervisor-rtc
    23.5  ide-cd-dma
    23.6  vnc-password
    23.7 +ne2000-bounds-checks
    23.8 +xenstore-device-info-functions
    23.9 +tpm-tis-device
   23.10 +qemu-serial-fixes
   23.11 +vnc-japan-keymap
   23.12 +rtl8139-bound-chaining
   23.13 +fix-interrupt-routing
   23.14 +nodelay-serial-over-tcp
   23.15 +remove-pci-bridge-setup
   23.16 +limit-fdc-sector-size-to-16K
   23.17 +usb-uhci-buffer-size
   23.18 +vnc-monitor-shift-key-processing
   23.19 +ide-error-reporting
   23.20 +vnc-numpad-handling
    24.1 --- a/tools/ioemu/patches/shared-vram	Fri Dec 08 07:22:21 2006 -0800
    24.2 +++ b/tools/ioemu/patches/shared-vram	Fri Dec 08 18:31:01 2006 +0000
    24.3 @@ -1,7 +1,7 @@
    24.4  Index: ioemu/hw/cirrus_vga.c
    24.5  ===================================================================
    24.6 ---- ioemu.orig/hw/cirrus_vga.c	2006-08-17 19:37:36.372522620 +0100
    24.7 -+++ ioemu/hw/cirrus_vga.c	2006-08-17 19:49:52.157002909 +0100
    24.8 +--- ioemu.orig/hw/cirrus_vga.c	2006-12-08 01:57:54.000000000 +0000
    24.9 ++++ ioemu/hw/cirrus_vga.c	2006-12-08 02:00:04.000000000 +0000
   24.10  @@ -28,6 +28,9 @@
   24.11    */
   24.12   #include "vl.h"
   24.13 @@ -176,8 +176,8 @@ Index: ioemu/hw/cirrus_vga.c
   24.14   }
   24.15  Index: ioemu/hw/pc.c
   24.16  ===================================================================
   24.17 ---- ioemu.orig/hw/pc.c	2006-08-17 19:49:50.229215988 +0100
   24.18 -+++ ioemu/hw/pc.c	2006-08-17 19:49:52.158002799 +0100
   24.19 +--- ioemu.orig/hw/pc.c	2006-12-08 02:00:04.000000000 +0000
   24.20 ++++ ioemu/hw/pc.c	2006-12-08 02:00:04.000000000 +0000
   24.21  @@ -790,14 +790,14 @@
   24.22       if (cirrus_vga_enabled) {
   24.23           if (pci_enabled) {
   24.24 @@ -198,8 +198,8 @@ Index: ioemu/hw/pc.c
   24.25   
   24.26  Index: ioemu/hw/vga.c
   24.27  ===================================================================
   24.28 ---- ioemu.orig/hw/vga.c	2006-08-17 19:49:37.764593706 +0100
   24.29 -+++ ioemu/hw/vga.c	2006-08-17 19:49:52.159002688 +0100
   24.30 +--- ioemu.orig/hw/vga.c	2006-12-08 02:00:04.000000000 +0000
   24.31 ++++ ioemu/hw/vga.c	2006-12-08 02:00:04.000000000 +0000
   24.32  @@ -1858,6 +1858,7 @@
   24.33       /* TODO: add vbe support if enabled */
   24.34   }
   24.35 @@ -251,8 +251,8 @@ Index: ioemu/hw/vga.c
   24.36   
   24.37  Index: ioemu/hw/vga_int.h
   24.38  ===================================================================
   24.39 ---- ioemu.orig/hw/vga_int.h	2006-08-17 19:37:36.372522620 +0100
   24.40 -+++ ioemu/hw/vga_int.h	2006-08-17 19:49:52.159002688 +0100
   24.41 +--- ioemu.orig/hw/vga_int.h	2006-12-08 01:57:54.000000000 +0000
   24.42 ++++ ioemu/hw/vga_int.h	2006-12-08 02:00:04.000000000 +0000
   24.43  @@ -169,5 +169,6 @@
   24.44                                unsigned int color0, unsigned int color1,
   24.45                                unsigned int color_xor);
   24.46 @@ -262,9 +262,9 @@ Index: ioemu/hw/vga_int.h
   24.47   extern const uint8_t gr_mask[16];
   24.48  Index: ioemu/vl.c
   24.49  ===================================================================
   24.50 ---- ioemu.orig/vl.c	2006-08-17 19:49:50.231215767 +0100
   24.51 -+++ ioemu/vl.c	2006-08-17 19:49:52.162002356 +0100
   24.52 -@@ -5693,6 +5693,78 @@
   24.53 +--- ioemu.orig/vl.c	2006-12-08 02:00:04.000000000 +0000
   24.54 ++++ ioemu/vl.c	2006-12-08 02:00:27.000000000 +0000
   24.55 +@@ -5693,6 +5693,62 @@
   24.56   
   24.57   #define MAX_NET_CLIENTS 32
   24.58   
   24.59 @@ -303,9 +303,6 @@ Index: ioemu/vl.c
   24.60  +                   unsigned long nr_pages, unsigned int address_bits,
   24.61  +                   xen_pfn_t *extent_start)
   24.62  +{
   24.63 -+#if 0
   24.64 -+    int i;
   24.65 -+#endif
   24.66  +    xc_dominfo_t info;
   24.67  +    int err = 0;
   24.68  +
   24.69 @@ -324,19 +321,6 @@ Index: ioemu/vl.c
   24.70  +        return -1;
   24.71  +    }
   24.72  +
   24.73 -+    err = xc_domain_translate_gpfn_list(xc_handle, domid, nr_pages,
   24.74 -+                                        extent_start, extent_start);
   24.75 -+    if (err) {
   24.76 -+        fprintf(stderr, "Failed to translate gpfn list\n");
   24.77 -+        return -1;
   24.78 -+    }
   24.79 -+
   24.80 -+#if 0 /* Generates lots of log file output - turn on for debugging */
   24.81 -+    for (i = 0; i < nr_pages; i++)
   24.82 -+        fprintf(stderr, "set_map result i %x result %lx\n", i,
   24.83 -+                extent_start[i]);
   24.84 -+#endif
   24.85 -+
   24.86  +    return 0;
   24.87  +}
   24.88  +
   24.89 @@ -345,8 +329,8 @@ Index: ioemu/vl.c
   24.90   #ifdef CONFIG_GDBSTUB
   24.91  Index: ioemu/vl.h
   24.92  ===================================================================
   24.93 ---- ioemu.orig/vl.h	2006-08-17 19:49:44.492850031 +0100
   24.94 -+++ ioemu/vl.h	2006-08-17 19:49:52.163002246 +0100
   24.95 +--- ioemu.orig/vl.h	2006-12-08 02:00:04.000000000 +0000
   24.96 ++++ ioemu/vl.h	2006-12-08 02:00:04.000000000 +0000
   24.97  @@ -145,6 +145,13 @@
   24.98   
   24.99   void main_loop_wait(int timeout);
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/tools/ioemu/patches/tpm-tis-device	Fri Dec 08 18:31:01 2006 +0000
    25.3 @@ -0,0 +1,1182 @@
    25.4 +# HG changeset patch
    25.5 +# User kaf24@localhost.localdomain
    25.6 +# Node ID d60b709724f48397b95da3d56299213cae391789
    25.7 +# Parent  bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2
    25.8 +[QEMU] Add a TIS device model compliant to the 1.2 TPM specification.
    25.9 +It implements all registers necessary to make the Linux TIS driver
   25.10 +work (tpm_tis.c). All of the basic registers supported by this type of
   25.11 +device are implemented. Also the locality selection has been
   25.12 +implemented, but has not been tested. The legacy registers as
   25.13 +described in the specification are not supported.
   25.14 +
   25.15 +Current caveat: The device has so far not yet been integrated with the
   25.16 +virtual TPM available in the repository. It will require changes to
   25.17 +the virtual TPM spawned by the vTPM manager to offer an additional message
   25.18 +interface. The TIS interface itself then needs to have an additional
   25.19 +transport implemented. (see vTPMTransmit array).
   25.20 +
   25.21 +The relevant specification for the device model can be found here:
   25.22 +https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
   25.23 +
   25.24 +Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
   25.25 +
   25.26 +Index: ioemu/Makefile.target
   25.27 +===================================================================
   25.28 +--- ioemu.orig/Makefile.target	2006-12-08 18:20:53.000000000 +0000
   25.29 ++++ ioemu/Makefile.target	2006-12-08 18:21:18.000000000 +0000
   25.30 +@@ -369,6 +369,7 @@
   25.31 + VL_OBJS+= piix4acpi.o
   25.32 + VL_OBJS+= xenstore.o
   25.33 + VL_OBJS+= xen_platform.o
   25.34 ++VL_OBJS+= tpm_tis.o
   25.35 + DEFINES += -DHAS_AUDIO
   25.36 + endif
   25.37 + ifeq ($(TARGET_BASE_ARCH), ppc)
   25.38 +Index: ioemu/hw/pc.c
   25.39 +===================================================================
   25.40 +--- ioemu.orig/hw/pc.c	2006-12-08 18:20:52.000000000 +0000
   25.41 ++++ ioemu/hw/pc.c	2006-12-08 18:21:18.000000000 +0000
   25.42 +@@ -875,6 +875,9 @@
   25.43 +         }
   25.44 +     }
   25.45 + 
   25.46 ++    if (has_tpm_device())
   25.47 ++        tpm_tis_init(&pic_set_irq_new, isa_pic, 11);
   25.48 ++
   25.49 +     kbd_init();
   25.50 +     DMA_init(0);
   25.51 + #ifdef HAS_AUDIO
   25.52 +Index: ioemu/hw/tpm_tis.c
   25.53 +===================================================================
   25.54 +--- /dev/null	1970-01-01 00:00:00.000000000 +0000
   25.55 ++++ ioemu/hw/tpm_tis.c	2006-12-08 18:21:18.000000000 +0000
   25.56 +@@ -0,0 +1,1114 @@
   25.57 ++/*
   25.58 ++ * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
   25.59 ++ *
   25.60 ++ * Copyright (C) 2006 IBM Corporation
   25.61 ++ *
   25.62 ++ * Author: Stefan Berger <stefanb@us.ibm.com>
   25.63 ++ *         David Safford <safford@us.ibm.com>
   25.64 ++ *
   25.65 ++ * This program is free software; you can redistribute it and/or
   25.66 ++ * modify it under the terms of the GNU General Public License as
   25.67 ++ * published by the Free Software Foundation, version 2 of the
   25.68 ++ * License.
   25.69 ++ *
   25.70 ++ *
   25.71 ++ * Implementation of the TIS interface according to specs at
   25.72 ++ * https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
   25.73 ++ *
   25.74 ++ */
   25.75 ++
   25.76 ++#include <sys/types.h>
   25.77 ++#include <sys/stat.h>
   25.78 ++#include <sys/socket.h>
   25.79 ++#include <sys/un.h>
   25.80 ++#include <fcntl.h>
   25.81 ++#include <errno.h>
   25.82 ++#include "vl.h"
   25.83 ++
   25.84 ++//#define DEBUG_TPM
   25.85 ++
   25.86 ++#define TPM_MAX_PKT	              4096
   25.87 ++
   25.88 ++#define VTPM_BAD_INSTANCE             (uint32_t)0xffffffff
   25.89 ++
   25.90 ++#define TIS_ADDR_BASE                 0xFED40000
   25.91 ++
   25.92 ++/* tis registers */
   25.93 ++#define TPM_REG_ACCESS                0x00
   25.94 ++#define TPM_REG_INT_ENABLE            0x08
   25.95 ++#define TPM_REG_INT_VECTOR            0x0c
   25.96 ++#define TPM_REG_INT_STATUS            0x10
   25.97 ++#define TPM_REG_INTF_CAPABILITY       0x14
   25.98 ++#define TPM_REG_STS                   0x18
   25.99 ++#define TPM_REG_DATA_FIFO             0x24
  25.100 ++#define TPM_REG_DID_VID               0xf00
  25.101 ++#define TPM_REG_RID                   0xf04
  25.102 ++
  25.103 ++#define STS_VALID                    (1 << 7)
  25.104 ++#define STS_COMMAND_READY            (1 << 6)
  25.105 ++#define STS_TPM_GO                   (1 << 5)
  25.106 ++#define STS_DATA_AVAILABLE           (1 << 4)
  25.107 ++#define STS_EXPECT                   (1 << 3)
  25.108 ++#define STS_RESPONSE_RETRY           (1 << 1)
  25.109 ++
  25.110 ++#define ACCESS_TPM_REG_VALID_STS     (1 << 7)
  25.111 ++#define ACCESS_ACTIVE_LOCALITY       (1 << 5)
  25.112 ++#define ACCESS_BEEN_SEIZED           (1 << 4)
  25.113 ++#define ACCESS_SEIZE                 (1 << 3)
  25.114 ++#define ACCESS_PENDING_REQUEST       (1 << 2)
  25.115 ++#define ACCESS_REQUEST_USE           (1 << 1)
  25.116 ++#define ACCESS_TPM_ESTABLISHMENT     (1 << 0)
  25.117 ++
  25.118 ++#define INT_ENABLED                  (1 << 31)
  25.119 ++#define INT_DATA_AVAILABLE           (1 << 0)
  25.120 ++#define INT_LOCALITY_CHANGED         (1 << 2)
  25.121 ++#define INT_COMMAND_READY            (1 << 7)
  25.122 ++
  25.123 ++#define INTERRUPTS_SUPPORTED         (INT_LOCALITY_CHANGED | \
  25.124 ++                                      INT_DATA_AVAILABLE   | \
  25.125 ++                                      INT_COMMAND_READY)
  25.126 ++#define CAPABILITIES_SUPPORTED       ((1 << 4) |            \
  25.127 ++                                      INTERRUPTS_SUPPORTED)
  25.128 ++
  25.129 ++enum {
  25.130 ++  STATE_IDLE = 0,
  25.131 ++  STATE_READY,
  25.132 ++  STATE_COMPLETION,
  25.133 ++  STATE_EXECUTION,
  25.134 ++  STATE_RECEPTION
  25.135 ++};
  25.136 ++
  25.137 ++#define NUM_LOCALITIES   5
  25.138 ++#define NO_LOCALITY      0xff
  25.139 ++
  25.140 ++#define IS_VALID_LOC(x) ((x) < NUM_LOCALITIES)
  25.141 ++
  25.142 ++#define TPM_DID          0x0001
  25.143 ++#define TPM_VID          0x0001
  25.144 ++#define TPM_RID          0x0001
  25.145 ++
  25.146 ++/* if the connection to the vTPM should be closed after a successfully
  25.147 ++   received response; set to '0' to allow keeping the connection */
  25.148 ++#define FORCE_CLOSE      0
  25.149 ++
  25.150 ++/* local data structures */
  25.151 ++
  25.152 ++typedef struct TPMTx {
  25.153 ++    int fd[2];
  25.154 ++} tpmTx;
  25.155 ++
  25.156 ++typedef struct TPMBuffer {
  25.157 ++    uint8_t instance[4];      /* instance number in network byte order */
  25.158 ++    uint8_t buf[TPM_MAX_PKT];
  25.159 ++} __attribute__((packed)) tpmBuffer;
  25.160 ++
  25.161 ++/* locality data */
  25.162 ++typedef struct TPMLocal {
  25.163 ++    uint32_t state;
  25.164 ++    uint8_t access;
  25.165 ++    uint8_t sts;
  25.166 ++    uint32_t inte;
  25.167 ++    uint32_t ints;
  25.168 ++} tpmLoc;
  25.169 ++
  25.170 ++/* overall state of the TPM interface; 's' marks as save upon suspension */
  25.171 ++typedef struct TPMState {
  25.172 ++    uint32_t offset;            /* s */
  25.173 ++    tpmBuffer buffer;           /* s */
  25.174 ++    uint8_t active_loc;         /* s */
  25.175 ++    uint8_t aborting_locty;
  25.176 ++    uint8_t next_locty;
  25.177 ++    uint8_t irq_pending;        /* s */
  25.178 ++    tpmLoc loc[NUM_LOCALITIES]; /* s */
  25.179 ++    QEMUTimer *poll_timer;
  25.180 ++    SetIRQFunc *set_irq;
  25.181 ++    void *irq_opaque;
  25.182 ++    int irq;
  25.183 ++    int poll_attempts;
  25.184 ++    uint32_t vtpm_instance;  /* vtpm inst. number; determined from xenstore*/
  25.185 ++    int Transmitlayer;
  25.186 ++    tpmTx tpmTx;
  25.187 ++} tpmState;
  25.188 ++
  25.189 ++
  25.190 ++/* local prototypes */
  25.191 ++static int TPM_Send(tpmState *s, tpmBuffer *buffer, char *msg);
  25.192 ++static int TPM_Receive(tpmState *s, tpmBuffer *buffer);
  25.193 ++static uint32_t vtpm_instance_from_xenstore(void);
  25.194 ++static void tis_poll_timer(void *opaque);
  25.195 ++static void tis_prep_next_interrupt(tpmState *s);
  25.196 ++static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask);
  25.197 ++static void close_vtpm_channel(tpmState *s, int force);
  25.198 ++static void open_vtpm_channel(tpmState *s);
  25.199 ++static void tis_attempt_receive(tpmState *s, uint8_t locty);
  25.200 ++
  25.201 ++/* transport layer functions: local sockets */
  25.202 ++static int create_local_socket(tpmState *s, uint32_t vtpm_instance);
  25.203 ++static int write_local_socket(tpmState *s, const tpmBuffer *);
  25.204 ++static int read_local_socket(tpmState *s, tpmBuffer *);
  25.205 ++static int close_local_socket(tpmState *s, int force);
  25.206 ++static int has_channel_local_socket(tpmState *s);
  25.207 ++#define LOCAL_SOCKET_PATH      "/var/vtpm/vtpm_all.socket"
  25.208 ++
  25.209 ++
  25.210 ++#define NUM_TRANSPORTS 1
  25.211 ++
  25.212 ++struct vTPM_transmit {
  25.213 ++    int (*open) (tpmState *s, uint32_t vtpm_instance);
  25.214 ++    int (*write) (tpmState *s, const tpmBuffer *);
  25.215 ++    int (*read) (tpmState *s, tpmBuffer *);
  25.216 ++    int (*close) (tpmState *s, int);
  25.217 ++    int (*has_channel) (tpmState *s);
  25.218 ++} vTPMTransmit[NUM_TRANSPORTS] = {
  25.219 ++    { .open = create_local_socket,
  25.220 ++      .write = write_local_socket,
  25.221 ++      .read = read_local_socket,
  25.222 ++      .close = close_local_socket,
  25.223 ++      .has_channel = has_channel_local_socket,
  25.224 ++    }
  25.225 ++};
  25.226 ++
  25.227 ++
  25.228 ++#define IS_COMM_WITH_VTPM(s)                            \
  25.229 ++     ((s)->Transmitlayer >= 0 &&                        \
  25.230 ++      vTPMTransmit[(s)->Transmitlayer].has_channel(s))
  25.231 ++
  25.232 ++
  25.233 ++/**********************************************************************
  25.234 ++ helper functions
  25.235 ++ *********************************************************************/
  25.236 ++
  25.237 ++static inline uint32_t tpm_get_size_from_buffer(const uint8_t *buffer)
  25.238 ++{
  25.239 ++    uint32_t len = (buffer[4] << 8) + buffer[5];
  25.240 ++    return len;
  25.241 ++}
  25.242 ++
  25.243 ++static inline void tpm_initialize_instance(tpmState *s, uint32_t instance)
  25.244 ++{
  25.245 ++    s->buffer.instance[0] = (instance >> 24) & 0xff;
  25.246 ++    s->buffer.instance[1] = (instance >> 16) & 0xff;
  25.247 ++    s->buffer.instance[2] = (instance >>  8) & 0xff;
  25.248 ++    s->buffer.instance[3] = (instance >>  0) & 0xff;
  25.249 ++}
  25.250 ++
  25.251 ++/*
  25.252 ++ * open communication channel with a vTPM
  25.253 ++ */
  25.254 ++static void open_vtpm_channel(tpmState *s)
  25.255 ++{
  25.256 ++    int idx;
  25.257 ++    /* search a usable transmit layer */
  25.258 ++    for (idx = 0; idx < NUM_TRANSPORTS; idx++) {
  25.259 ++        if (1 == vTPMTransmit[idx].open(s, s->vtpm_instance)) {
  25.260 ++            /* found one */
  25.261 ++            s->Transmitlayer = idx;
  25.262 ++            break;
  25.263 ++        }
  25.264 ++    }
  25.265 ++}
  25.266 ++
  25.267 ++/*
  25.268 ++ * close the communication channel with the vTPM
  25.269 ++ */
  25.270 ++static inline void close_vtpm_channel(tpmState *s, int force)
  25.271 ++{
  25.272 ++    if (1 == vTPMTransmit[s->Transmitlayer].close(s, force)) {
  25.273 ++        s->Transmitlayer = -1;
  25.274 ++    }
  25.275 ++}
  25.276 ++
  25.277 ++static inline uint8_t locality_from_addr(target_phys_addr_t addr)
  25.278 ++{
  25.279 ++    return (uint8_t)((addr >> 12) & 0x7);
  25.280 ++}
  25.281 ++
  25.282 ++
  25.283 ++/**********************************************************************
  25.284 ++    low-level transmission layer methods
  25.285 ++ *********************************************************************/
  25.286 ++
  25.287 ++/*
  25.288 ++ * the 'open' method that creates the filedescriptor for communicating
  25.289 ++ * only one is needed for reading and writing
  25.290 ++ */
  25.291 ++static int create_local_socket(tpmState *s, uint32_t vtpm_instance)
  25.292 ++{
  25.293 ++    int success = 1;
  25.294 ++    if (s->tpmTx.fd[0] < 0) {
  25.295 ++        s->tpmTx.fd[0] = socket(PF_LOCAL, SOCK_STREAM, 0);
  25.296 ++
  25.297 ++        if (has_channel_local_socket(s)) {
  25.298 ++            struct sockaddr_un addr;
  25.299 ++            memset(&addr, 0x0, sizeof(addr));
  25.300 ++            addr.sun_family = AF_LOCAL;
  25.301 ++            strcpy(addr.sun_path, LOCAL_SOCKET_PATH);
  25.302 ++            if (connect(s->tpmTx.fd[0],
  25.303 ++                        (struct sockaddr *)&addr,
  25.304 ++                        sizeof(addr)) != 0) {
  25.305 ++                close_local_socket(s, 1);
  25.306 ++                success = 0;
  25.307 ++            } else {
  25.308 ++                /* put filedescriptor in non-blocking mode for polling */
  25.309 ++                int flags = fcntl(s->tpmTx.fd[0], F_GETFL);
  25.310 ++                fcntl(s->tpmTx.fd[0], F_SETFL, flags | O_NONBLOCK);
  25.311 ++            }
  25.312 ++#ifdef DEBUG_TPM
  25.313 ++            if (success)
  25.314 ++                fprintf(logfile,"Successfully connected using local socket "
  25.315 ++                                LOCAL_SOCKET_PATH ".\n");
  25.316 ++            else
  25.317 ++                fprintf(logfile,"Could not connect to local socket "
  25.318 ++                                LOCAL_SOCKET_PATH ".\n");
  25.319 ++#endif
  25.320 ++        } else {
  25.321 ++            success = 0;
  25.322 ++        }
  25.323 ++    }
  25.324 ++    return success;
  25.325 ++}
  25.326 ++
  25.327 ++/*
  25.328 ++ * the 'write' method for sending requests to the vTPM
  25.329 ++ * four bytes with the vTPM instance number are prepended to each request
  25.330 ++ */
  25.331 ++static int write_local_socket(tpmState *s, const tpmBuffer *buffer)
  25.332 ++{
  25.333 ++    uint32_t size = tpm_get_size_from_buffer(buffer->buf);
  25.334 ++    int len;
  25.335 ++
  25.336 ++    len = write(s->tpmTx.fd[0],
  25.337 ++                buffer->instance,
  25.338 ++                sizeof(buffer->instance) + size);
  25.339 ++    if (len == sizeof(buffer->instance) + size) {
  25.340 ++        return len;
  25.341 ++    } else {
  25.342 ++        return -1;
  25.343 ++    }
  25.344 ++}
  25.345 ++
  25.346 ++/*
  25.347 ++ * the 'read' method for receiving of responses from the TPM
  25.348 ++ * this function expects that four bytes with the instance number
  25.349 ++ * are received from the vTPM
  25.350 ++ */
  25.351 ++static int read_local_socket(tpmState *s, tpmBuffer *buffer)
  25.352 ++{
  25.353 ++    int off;
  25.354 ++#ifdef DEBUG_TPM
  25.355 ++    fprintf(logfile, "Reading from fd %d\n", s->tpmTx.fd[0]);
  25.356 ++#endif
  25.357 ++    off = read(s->tpmTx.fd[0],
  25.358 ++               buffer->instance,
  25.359 ++               sizeof(buffer->instance)+TPM_MAX_PKT);
  25.360 ++#ifdef DEBUG_TPM
  25.361 ++    fprintf(logfile, "Read %d bytes\n", off);
  25.362 ++#endif
  25.363 ++    return off;
  25.364 ++}
  25.365 ++
  25.366 ++/*
  25.367 ++ * the 'close' method
  25.368 ++ * shut down communication with the vTPM
  25.369 ++ * 'force' = 1 indicates that the socket *must* be closed
  25.370 ++ * 'force' = 0 indicates that a connection may be maintained
  25.371 ++ */
  25.372 ++static int close_local_socket(tpmState *s, int force)
  25.373 ++{
  25.374 ++    if (force) {
  25.375 ++        close(s->tpmTx.fd[0]);
  25.376 ++#ifdef DEBUG_TPM
  25.377 ++        fprintf(logfile,"Closed connection with fd %d\n",s->tpmTx.fd[0]);
  25.378 ++#endif
  25.379 ++        s->tpmTx.fd[0] = -1;
  25.380 ++        return 1; /* socket was closed */
  25.381 ++    }
  25.382 ++#ifdef DEBUG_TPM
  25.383 ++    fprintf(logfile,"Keeping connection with fd %d\n",s->tpmTx.fd[0]);
  25.384 ++#endif
  25.385 ++    return 0;
  25.386 ++}
  25.387 ++
  25.388 ++/*
  25.389 ++ * the 'has_channel' method that checks whether there's a communication
  25.390 ++ * channel with the vTPM
  25.391 ++ */
  25.392 ++static int has_channel_local_socket(tpmState *s)
  25.393 ++{
  25.394 ++    return (s->tpmTx.fd[0] > 0);
  25.395 ++}
  25.396 ++
  25.397 ++/**********************************************************************/
  25.398 ++
  25.399 ++/*
  25.400 ++ * read a byte of response data
  25.401 ++ */
  25.402 ++static uint32_t tpm_data_read(tpmState *s, uint8_t locty)
  25.403 ++{
  25.404 ++    uint32_t ret, len;
  25.405 ++
  25.406 ++    /* try to receive data, if none are there it is ok */
  25.407 ++    tis_attempt_receive(s, locty);
  25.408 ++
  25.409 ++    if (s->loc[locty].state != STATE_COMPLETION) {
  25.410 ++        return 0xff;
  25.411 ++    }
  25.412 ++
  25.413 ++    len = tpm_get_size_from_buffer(s->buffer.buf);
  25.414 ++    ret = s->buffer.buf[s->offset++];
  25.415 ++    if (s->offset >= len) {
  25.416 ++        s->loc[locty].sts = STS_VALID ;
  25.417 ++        s->offset = 0;
  25.418 ++    }
  25.419 ++#ifdef DEBUG_TPM
  25.420 ++    fprintf(logfile,"tpm_data_read byte x%02x   [%d]\n",ret,s->offset-1);
  25.421 ++#endif
  25.422 ++    return ret;
  25.423 ++}
  25.424 ++
  25.425 ++
  25.426 ++
  25.427 ++/* raise an interrupt if allowed */
  25.428 ++static void tis_raise_irq(tpmState *s, uint8_t locty, uint32_t irqmask)
  25.429 ++{
  25.430 ++    if (!s->irq_pending &&
  25.431 ++        (s->loc[locty].inte & INT_ENABLED) &&
  25.432 ++        (s->loc[locty].inte & irqmask)) {
  25.433 ++        if ((irqmask & s->loc[locty].ints) == 0) {
  25.434 ++#ifdef DEBUG_TPM
  25.435 ++            fprintf(logfile,"Raising IRQ for flag %08x\n",irqmask);
  25.436 ++#endif
  25.437 ++            s->set_irq(s->irq_opaque, s->irq, 1);
  25.438 ++            s->irq_pending = 1;
  25.439 ++            s->loc[locty].ints |= irqmask;
  25.440 ++        }
  25.441 ++    }
  25.442 ++}
  25.443 ++
  25.444 ++/* abort execution of command */
  25.445 ++static void tis_abort(tpmState *s)
  25.446 ++{
  25.447 ++    s->offset = 0;
  25.448 ++    s->active_loc = s->next_locty;
  25.449 ++
  25.450 ++    /*
  25.451 ++     * Need to react differently depending on who's aborting now and
  25.452 ++     * which locality will become active afterwards.
  25.453 ++     */
  25.454 ++    if (s->aborting_locty == s->next_locty) {
  25.455 ++        s->loc[s->aborting_locty].state = STATE_READY;
  25.456 ++        s->loc[s->aborting_locty].sts   = STS_COMMAND_READY;
  25.457 ++        tis_raise_irq(s, s->aborting_locty, INT_COMMAND_READY);
  25.458 ++    }
  25.459 ++
  25.460 ++    /* locality after abort is another one than the current one */
  25.461 ++    if (s->aborting_locty != s->next_locty && s->next_locty != NO_LOCALITY) {
  25.462 ++        s->loc[s->aborting_locty].access &= ~ACCESS_ACTIVE_LOCALITY;
  25.463 ++        s->loc[s->next_locty].access     |=  ACCESS_ACTIVE_LOCALITY;
  25.464 ++        tis_raise_irq(s, s->next_locty, INT_LOCALITY_CHANGED);
  25.465 ++    }
  25.466 ++
  25.467 ++    s->aborting_locty = NO_LOCALITY; /* nobody's aborting a command anymore */
  25.468 ++
  25.469 ++    qemu_del_timer(s->poll_timer);
  25.470 ++}
  25.471 ++
  25.472 ++/* abort current command */
  25.473 ++static void tis_prep_abort(tpmState *s, uint8_t locty, uint8_t newlocty)
  25.474 ++{
  25.475 ++    s->aborting_locty = locty; /* current locality */
  25.476 ++    s->next_locty = newlocty;  /* locality after successful abort */
  25.477 ++
  25.478 ++    /*
  25.479 ++     * only abort a command using an interrupt if currently executing
  25.480 ++     * a command AND if there's a valid connection to the vTPM.
  25.481 ++     */
  25.482 ++    if (s->loc[locty].state == STATE_EXECUTION &&
  25.483 ++        IS_COMM_WITH_VTPM(s)) {
  25.484 ++        /* start timer and inside the timer wait for the result */
  25.485 ++        s->poll_attempts = 0;
  25.486 ++        tis_prep_next_interrupt(s);
  25.487 ++    } else {
  25.488 ++        tis_abort(s);
  25.489 ++    }
  25.490 ++}
  25.491 ++
  25.492 ++
  25.493 ++/*
  25.494 ++ * Try to receive a response from the vTPM
  25.495 ++ */
  25.496 ++static void tis_attempt_receive(tpmState *s, uint8_t locty)
  25.497 ++{
  25.498 ++    /*
  25.499 ++     * Attempt to read from the vTPM here if
  25.500 ++     * - not aborting a command
  25.501 ++     * - command has been sent and state is 'EXECUTION' now
  25.502 ++     * - no data are already available (data have already been read)
  25.503 ++     * - there's a communication path to the vTPM established
  25.504 ++     */
  25.505 ++    if (!IS_VALID_LOC(s->aborting_locty)) {
  25.506 ++        if (s->loc[locty].state == STATE_EXECUTION) {
  25.507 ++            if (0 == (s->loc[locty].sts & STS_DATA_AVAILABLE)){
  25.508 ++                if (IS_COMM_WITH_VTPM(s)) {
  25.509 ++                    int n = TPM_Receive(s, &s->buffer);
  25.510 ++                    if (n > 0) {
  25.511 ++                        s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
  25.512 ++                        s->loc[locty].state = STATE_COMPLETION;
  25.513 ++                        close_vtpm_channel(s, FORCE_CLOSE);
  25.514 ++                        tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
  25.515 ++                    }
  25.516 ++                }
  25.517 ++            }
  25.518 ++        }
  25.519 ++    }
  25.520 ++}
  25.521 ++
  25.522 ++/*
  25.523 ++ * Read a register of the TIS interface
  25.524 ++ * See specs pages 33-63 for description of the registers
  25.525 ++ */
  25.526 ++static uint32_t tis_mem_readl(void *opaque, target_phys_addr_t addr)
  25.527 ++{
  25.528 ++    tpmState *s = (tpmState *)opaque;
  25.529 ++    uint16_t offset = addr & 0xffc;
  25.530 ++    uint8_t shift = (addr & 0x3) * 8;
  25.531 ++    uint32_t val = 0;
  25.532 ++    uint8_t locty = locality_from_addr(addr);
  25.533 ++
  25.534 ++    if (offset == TPM_REG_ACCESS) {
  25.535 ++        if (s->active_loc == locty) {
  25.536 ++            s->loc[locty].access |= (1 << 5);
  25.537 ++         } else {
  25.538 ++            s->loc[locty].access &= ~(1 << 5);
  25.539 ++        }
  25.540 ++        val = s->loc[locty].access;
  25.541 ++    } else
  25.542 ++    if (offset == TPM_REG_INT_ENABLE) {
  25.543 ++        val = s->loc[locty].inte;
  25.544 ++    } else
  25.545 ++    if (offset == TPM_REG_INT_VECTOR) {
  25.546 ++        val = s->irq;
  25.547 ++    } else
  25.548 ++    if (offset == TPM_REG_INT_STATUS) {
  25.549 ++        tis_attempt_receive(s, locty);
  25.550 ++        val = s->loc[locty].ints;
  25.551 ++    } else
  25.552 ++    if (offset == TPM_REG_INTF_CAPABILITY) {
  25.553 ++        val = CAPABILITIES_SUPPORTED;
  25.554 ++    } else
  25.555 ++    if (offset == TPM_REG_STS) { /* status register */
  25.556 ++        tis_attempt_receive(s, locty);
  25.557 ++        val = (sizeof(s->buffer.buf) - s->offset) << 8 | s->loc[locty].sts;
  25.558 ++    } else
  25.559 ++    if (offset == TPM_REG_DATA_FIFO) {
  25.560 ++      val = tpm_data_read(s, locty);
  25.561 ++    } else
  25.562 ++    if (offset == TPM_REG_DID_VID) {
  25.563 ++        val = (TPM_DID << 16) | TPM_VID;
  25.564 ++    } else
  25.565 ++    if (offset == TPM_REG_RID) {
  25.566 ++         val = TPM_RID;
  25.567 ++    }
  25.568 ++
  25.569 ++    if (shift)
  25.570 ++        val >>= shift;
  25.571 ++
  25.572 ++#ifdef DEBUG_TPM
  25.573 ++    fprintf(logfile," read(%08x) = %08x\n",
  25.574 ++            addr,
  25.575 ++            val);
  25.576 ++#endif
  25.577 ++
  25.578 ++    return val;
  25.579 ++}
  25.580 ++
  25.581 ++/*
  25.582 ++ * Write a value to a register of the TIS interface
  25.583 ++ * See specs pages 33-63 for description of the registers
  25.584 ++ */
  25.585 ++static void tis_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  25.586 ++{
  25.587 ++    tpmState* s=(tpmState*)opaque;
  25.588 ++    uint16_t off = addr & 0xfff;
  25.589 ++    uint8_t locty = locality_from_addr(addr);
  25.590 ++    int n, c;
  25.591 ++    uint32_t len;
  25.592 ++
  25.593 ++#ifdef DEBUG_TPM
  25.594 ++    fprintf(logfile,"write(%08x) = %08x\n",
  25.595 ++            addr,
  25.596 ++            val);
  25.597 ++#endif
  25.598 ++
  25.599 ++    if (off == TPM_REG_ACCESS) {
  25.600 ++        if (val & ACCESS_ACTIVE_LOCALITY) {
  25.601 ++            /* give up locality if currently owned */
  25.602 ++            if (s->active_loc == locty) {
  25.603 ++                uint8_t newlocty = NO_LOCALITY;
  25.604 ++                s->loc[locty].access &= ~(ACCESS_PENDING_REQUEST);
  25.605 ++                /* anybody wants the locality ? */
  25.606 ++                for (c = NUM_LOCALITIES - 1; c >= 0; c--) {
  25.607 ++                    if (s->loc[c].access & ACCESS_REQUEST_USE) {
  25.608 ++                        s->loc[c].access |= ACCESS_TPM_REG_VALID_STS;
  25.609 ++                        s->loc[c].access &= ~ACCESS_REQUEST_USE;
  25.610 ++                        newlocty = c;
  25.611 ++                        break;
  25.612 ++                    }
  25.613 ++                }
  25.614 ++                tis_prep_abort(s, locty, newlocty);
  25.615 ++            }
  25.616 ++        }
  25.617 ++        if (val & ACCESS_BEEN_SEIZED) {
  25.618 ++            /* clear the flag */
  25.619 ++            s->loc[locty].access &= ~ACCESS_BEEN_SEIZED;
  25.620 ++        }
  25.621 ++        if (val & ACCESS_SEIZE) {
  25.622 ++            if (locty > s->active_loc && IS_VALID_LOC(s->active_loc)) {
  25.623 ++                s->loc[s->active_loc].access |= ACCESS_BEEN_SEIZED;
  25.624 ++                s->loc[locty].access = ACCESS_TPM_REG_VALID_STS;
  25.625 ++                tis_prep_abort(s, s->active_loc, locty);
  25.626 ++            }
  25.627 ++        }
  25.628 ++        if (val & ACCESS_REQUEST_USE) {
  25.629 ++            if (IS_VALID_LOC(s->active_loc)) {
  25.630 ++                /* locality election */
  25.631 ++                s->loc[s->active_loc].access |= ACCESS_PENDING_REQUEST;
  25.632 ++            } else {
  25.633 ++                /* no locality active -> make this one active now */
  25.634 ++                s->loc[locty].access |= ACCESS_ACTIVE_LOCALITY;
  25.635 ++                s->active_loc = locty;
  25.636 ++                tis_raise_irq(s, locty, INT_LOCALITY_CHANGED);
  25.637 ++            }
  25.638 ++        }
  25.639 ++    } else
  25.640 ++    if (off == TPM_REG_INT_ENABLE) {
  25.641 ++        s->loc[locty].inte = (val & (INT_ENABLED | (0x3 << 3) |
  25.642 ++                                     INTERRUPTS_SUPPORTED));
  25.643 ++    } else
  25.644 ++    if (off == TPM_REG_INT_STATUS) {
  25.645 ++        /* clearing of interrupt flags */
  25.646 ++        if ((val & INTERRUPTS_SUPPORTED) &&
  25.647 ++            (s->loc[locty].ints & INTERRUPTS_SUPPORTED)) {
  25.648 ++            s->set_irq(s->irq_opaque, s->irq, 0);
  25.649 ++            s->irq_pending = 0;
  25.650 ++        }
  25.651 ++        s->loc[locty].ints &= ~(val & INTERRUPTS_SUPPORTED);
  25.652 ++    } else
  25.653 ++    if (off == TPM_REG_STS) {
  25.654 ++        if (val & STS_COMMAND_READY) {
  25.655 ++            if (s->loc[locty].state == STATE_IDLE) {
  25.656 ++                s->loc[locty].sts   = STS_COMMAND_READY;
  25.657 ++                s->loc[locty].state = STATE_READY;
  25.658 ++                tis_raise_irq(s, locty, INT_COMMAND_READY);
  25.659 ++            } else if (s->loc[locty].state == STATE_COMPLETION ||
  25.660 ++                       s->loc[locty].state == STATE_EXECUTION  ||
  25.661 ++                       s->loc[locty].state == STATE_RECEPTION) {
  25.662 ++                /* abort currently running command */
  25.663 ++                tis_prep_abort(s, locty, locty);
  25.664 ++            }
  25.665 ++        }
  25.666 ++        if (val & STS_TPM_GO) {
  25.667 ++            n = TPM_Send(s, &s->buffer,"tpm_data_write");
  25.668 ++            if (n > 0) {
  25.669 ++                /* sending of data was successful */
  25.670 ++                s->offset = 0;
  25.671 ++                s->loc[locty].state = STATE_EXECUTION;
  25.672 ++                if (s->loc[locty].inte & (INT_ENABLED | INT_DATA_AVAILABLE)) {
  25.673 ++                    s->poll_attempts = 0;
  25.674 ++                    tis_prep_next_interrupt(s);
  25.675 ++                }
  25.676 ++            }
  25.677 ++        }
  25.678 ++        if (val & STS_RESPONSE_RETRY) {
  25.679 ++            s->offset = 0;
  25.680 ++        }
  25.681 ++    } else if (off == TPM_REG_DATA_FIFO) {
  25.682 ++        /* data fifo */
  25.683 ++        if (s->loc[locty].state == STATE_IDLE ||
  25.684 ++            s->loc[locty].state == STATE_EXECUTION ||
  25.685 ++            s->loc[locty].state == STATE_COMPLETION) {
  25.686 ++            /* drop the byte */
  25.687 ++        } else {
  25.688 ++#ifdef TPM_DEBUG
  25.689 ++        fprintf(logfile,"Byte to send to TPM: %02x\n", val);
  25.690 ++#endif
  25.691 ++            s->loc[locty].state = STATE_RECEPTION;
  25.692 ++
  25.693 ++            if (s->offset < sizeof(s->buffer.buf))
  25.694 ++                s->buffer.buf[s->offset++] = (uint8_t)val;
  25.695 ++
  25.696 ++            if (s->offset > 5) {
  25.697 ++                /* we have a packet length - see if we have all of it */
  25.698 ++                len = tpm_get_size_from_buffer(s->buffer.buf);
  25.699 ++                if (len > s->offset) {
  25.700 ++                    s->loc[locty].sts = STS_EXPECT | STS_VALID;
  25.701 ++                } else {
  25.702 ++                    s->loc[locty].sts = STS_VALID;
  25.703 ++                }
  25.704 ++            }
  25.705 ++        }
  25.706 ++    }
  25.707 ++}
  25.708 ++
  25.709 ++/*
  25.710 ++ * Prepare the next interrupt for example after a command has
  25.711 ++ * been sent out for the purpose of receiving the response.
  25.712 ++ * Depending on how many interrupts (used for polling on the fd) have
  25.713 ++ * already been schedule, this function determines the delta in time
  25.714 ++ * to the next interrupt. This accomodates for commands that finish
  25.715 ++ * quickly.
  25.716 ++ */
  25.717 ++static void tis_prep_next_interrupt(tpmState *s)
  25.718 ++{
  25.719 ++    int64_t expiration;
  25.720 ++    int rate = 5; /* 5 times per second */
  25.721 ++
  25.722 ++    /*
  25.723 ++       poll often at the beginning for quickly finished commands,
  25.724 ++       then back off
  25.725 ++     */
  25.726 ++    if (s->poll_attempts < 5) {
  25.727 ++        rate = 20;
  25.728 ++    } else if (s->poll_attempts < 10) {
  25.729 ++        rate = 10;
  25.730 ++    }
  25.731 ++
  25.732 ++    expiration = qemu_get_clock(vm_clock) + (ticks_per_sec / rate);
  25.733 ++    qemu_mod_timer(s->poll_timer, expiration);
  25.734 ++    s->poll_attempts++;
  25.735 ++}
  25.736 ++
  25.737 ++
  25.738 ++/*
  25.739 ++ * The polling routine called when the 'timer interrupt' fires.
  25.740 ++ * Tries to receive a command from the vTPM.
  25.741 ++ */
  25.742 ++static void tis_poll_timer(void *opaque)
  25.743 ++{
  25.744 ++    tpmState* s=(tpmState*)opaque;
  25.745 ++    uint8_t locty = s->active_loc;
  25.746 ++
  25.747 ++    if (!IS_VALID_LOC(locty) ||
  25.748 ++        (!(s->loc[locty].inte & INT_ENABLED) &&
  25.749 ++          (s->aborting_locty != NO_LOCALITY)) ||
  25.750 ++        !IS_COMM_WITH_VTPM(s)) {
  25.751 ++        /* no more interrupts requested, so no more polling needed */
  25.752 ++        qemu_del_timer(s->poll_timer);
  25.753 ++    }
  25.754 ++
  25.755 ++    if (!IS_COMM_WITH_VTPM(s)) {
  25.756 ++        if (s->aborting_locty != NO_LOCALITY) {
  25.757 ++            tis_abort(s);
  25.758 ++        }
  25.759 ++        return;
  25.760 ++    }
  25.761 ++
  25.762 ++    if (s->aborting_locty != NO_LOCALITY) {
  25.763 ++        int n = TPM_Receive(s, &s->buffer);
  25.764 ++#ifdef DEBUG_TPM
  25.765 ++        fprintf(logfile,"Receiving for abort.\n");
  25.766 ++#endif
  25.767 ++        if (n > 0) {
  25.768 ++            close_vtpm_channel(s, FORCE_CLOSE);
  25.769 ++            tis_abort(s);
  25.770 ++#ifdef DEBUG_TPM
  25.771 ++            fprintf(logfile,"Abort is complete.\n");
  25.772 ++#endif
  25.773 ++        } else {
  25.774 ++            tis_prep_next_interrupt(s);
  25.775 ++        }
  25.776 ++    } else if (IS_VALID_LOC(locty)) {
  25.777 ++        if (s->loc[locty].state == STATE_EXECUTION) {
  25.778 ++           /* poll for result */
  25.779 ++            int n = TPM_Receive(s, &s->buffer);
  25.780 ++            if (n > 0) {
  25.781 ++                s->loc[locty].sts = STS_VALID | STS_DATA_AVAILABLE;
  25.782 ++                s->loc[locty].state = STATE_COMPLETION;
  25.783 ++                close_vtpm_channel(s, FORCE_CLOSE);
  25.784 ++                tis_raise_irq(s, locty, INT_DATA_AVAILABLE);
  25.785 ++            } else {
  25.786 ++                /* nothing received */
  25.787 ++                tis_prep_next_interrupt(s);
  25.788 ++            }
  25.789 ++        }
  25.790 ++    }
  25.791 ++}
  25.792 ++
  25.793 ++
  25.794 ++static CPUReadMemoryFunc *tis_readfn[3]={
  25.795 ++    tis_mem_readl,
  25.796 ++    tis_mem_readl,
  25.797 ++    tis_mem_readl
  25.798 ++};
  25.799 ++
  25.800 ++static CPUWriteMemoryFunc *tis_writefn[3]={
  25.801 ++    tis_mem_writel,
  25.802 ++    tis_mem_writel,
  25.803 ++    tis_mem_writel
  25.804 ++};
  25.805 ++
  25.806 ++/*
  25.807 ++ * Save the internal state of this interface for later resumption.
  25.808 ++ * Need to get any outstanding responses from the vTPM back, so
  25.809 ++ * this might delay the suspend for a while.
  25.810 ++ */
  25.811 ++static void tpm_save(QEMUFile* f,void* opaque)
  25.812 ++{
  25.813 ++    tpmState* s=(tpmState*)opaque;
  25.814 ++    int c;
  25.815 ++
  25.816 ++    /* need to wait for outstanding requests to complete */
  25.817 ++    if (IS_COMM_WITH_VTPM(s)) {
  25.818 ++        int repeats = 30; /* 30 seconds; really should be infty */
  25.819 ++        while (repeats > 0 &&
  25.820 ++               !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) {
  25.821 ++            int n = TPM_Receive(s, &s->buffer);
  25.822 ++            if (n > 0) {
  25.823 ++                if (IS_VALID_LOC(s->active_loc)) {
  25.824 ++                    s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
  25.825 ++                }
  25.826 ++                /* close the connection with the vTPM for good */
  25.827 ++                close_vtpm_channel(s, 1);
  25.828 ++                break;
  25.829 ++            }
  25.830 ++            sleep(1);
  25.831 ++        }
  25.832 ++    }
  25.833 ++
  25.834 ++    qemu_put_be32s(f,&s->offset);
  25.835 ++    qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT);
  25.836 ++    qemu_put_8s(f, &s->active_loc);
  25.837 ++    qemu_put_8s(f, &s->irq_pending);
  25.838 ++    for (c = 0; c < NUM_LOCALITIES; c++) {
  25.839 ++        qemu_put_be32s(f, &s->loc[c].state);
  25.840 ++        qemu_put_8s(f, &s->loc[c].access);
  25.841 ++        qemu_put_8s(f, &s->loc[c].sts);
  25.842 ++        qemu_put_be32s(f, &s->loc[c].inte);
  25.843 ++        qemu_put_be32s(f, &s->loc[c].ints);
  25.844 ++    }
  25.845 ++}
  25.846 ++
  25.847 ++/*
  25.848 ++ * load TIS interface state
  25.849 ++ */
  25.850 ++static int tpm_load(QEMUFile* f,void* opaque,int version_id)
  25.851 ++{
  25.852 ++    tpmState* s=(tpmState*)opaque;
  25.853 ++    int c;
  25.854 ++
  25.855 ++    if (version_id != 1)
  25.856 ++        return -EINVAL;
  25.857 ++
  25.858 ++    qemu_get_be32s(f,&s->offset);
  25.859 ++    qemu_get_buffer(f, s->buffer.buf, TPM_MAX_PKT);
  25.860 ++    qemu_get_8s(f, &s->active_loc);
  25.861 ++    qemu_get_8s(f, &s->irq_pending);
  25.862 ++    for (c = 0; c < NUM_LOCALITIES; c++) {
  25.863 ++        qemu_get_be32s(f, &s->loc[c].state);
  25.864 ++        qemu_get_8s(f, &s->loc[c].access);
  25.865 ++        qemu_get_8s(f, &s->loc[c].sts);
  25.866 ++        qemu_get_be32s(f, &s->loc[c].inte);
  25.867 ++        qemu_get_be32s(f, &s->loc[c].ints);
  25.868 ++    }
  25.869 ++
  25.870 ++    /* need to be able to get the instance number from the xenstore */
  25.871 ++    s->vtpm_instance = vtpm_instance_from_xenstore();
  25.872 ++    if (s->vtpm_instance == VTPM_BAD_INSTANCE)
  25.873 ++        return -EINVAL;
  25.874 ++    tpm_initialize_instance(s, s->vtpm_instance);
  25.875 ++
  25.876 ++    return 0;
  25.877 ++}
  25.878 ++
  25.879 ++
  25.880 ++typedef struct LPCtpmState {
  25.881 ++    tpmState tpm;
  25.882 ++    int mem;
  25.883 ++} LPCtpmState;
  25.884 ++
  25.885 ++
  25.886 ++/*
  25.887 ++ * initialize TIS interface
  25.888 ++ */
  25.889 ++void tpm_tis_init(SetIRQFunc *set_irq, void *opaque, int irq)
  25.890 ++{
  25.891 ++    LPCtpmState *d;
  25.892 ++    tpmState *s;
  25.893 ++    int c = 0;
  25.894 ++    uint32_t vtpm_in;
  25.895 ++
  25.896 ++    vtpm_in = vtpm_instance_from_xenstore();
  25.897 ++    /* no valid vtpm instance -> no device */
  25.898 ++    if (vtpm_in == VTPM_BAD_INSTANCE)
  25.899 ++        return;
  25.900 ++
  25.901 ++    d = qemu_mallocz(sizeof(LPCtpmState));
  25.902 ++    d->mem = cpu_register_io_memory(0, tis_readfn, tis_writefn, d);
  25.903 ++
  25.904 ++    if (d->mem == -1) {
  25.905 ++       return;
  25.906 ++    }
  25.907 ++
  25.908 ++    cpu_register_physical_memory(TIS_ADDR_BASE,
  25.909 ++                                 0x1000 * NUM_LOCALITIES, d->mem);
  25.910 ++
  25.911 ++    /* initialize tpmState */
  25.912 ++    s = &d->tpm;
  25.913 ++
  25.914 ++    s->offset = 0;
  25.915 ++    s->active_loc = NO_LOCALITY;
  25.916 ++
  25.917 ++    while (c < NUM_LOCALITIES) {
  25.918 ++        s->loc[c].access = (1 << 7);
  25.919 ++        s->loc[c].sts = 0;
  25.920 ++        s->loc[c].inte = (1 << 3);
  25.921 ++        s->loc[c].ints = 0;
  25.922 ++        s->loc[c].state = STATE_IDLE;
  25.923 ++        c++;
  25.924 ++    }
  25.925 ++    s->poll_timer = qemu_new_timer(vm_clock, tis_poll_timer, s);
  25.926 ++    s->set_irq = set_irq;
  25.927 ++    s->irq_opaque = opaque;
  25.928 ++    s->irq = irq;
  25.929 ++    s->vtpm_instance = vtpm_in;
  25.930 ++    s->Transmitlayer = -1;
  25.931 ++    s->tpmTx.fd[0] = -1;
  25.932 ++    s->tpmTx.fd[1] = -1;
  25.933 ++
  25.934 ++    tpm_initialize_instance(s, s->vtpm_instance);
  25.935 ++    memset(s->buffer.buf,0,sizeof(s->buffer.buf));
  25.936 ++
  25.937 ++    register_savevm("tpm-tis", 0, 1, tpm_save, tpm_load, s);
  25.938 ++}
  25.939 ++
  25.940 ++/****************************************************************************/
  25.941 ++/*  optional verbose logging of data to/from vtpm                           */
  25.942 ++/****************************************************************************/
  25.943 ++#ifdef DEBUG_TPM
  25.944 ++static void showBuff(unsigned char *buff, char *string)
  25.945 ++{
  25.946 ++    uint32_t i, len;
  25.947 ++
  25.948 ++    len = tpm_get_size_from_buffer(buff);
  25.949 ++    fprintf(logfile,"%s length = %d\n", string, len);
  25.950 ++    for (i = 0; i < len; i++) {
  25.951 ++        if (i && !(i % 16)) {
  25.952 ++            fprintf(logfile,"\n");
  25.953 ++        }
  25.954 ++        fprintf(logfile,"%.2X ", buff[i]);
  25.955 ++    }
  25.956 ++    fprintf(logfile,"\n");
  25.957 ++}
  25.958 ++#endif
  25.959 ++
  25.960 ++/****************************************************************************/
  25.961 ++/* Transmit request to TPM and read Response                                */
  25.962 ++/****************************************************************************/
  25.963 ++
  25.964 ++const static unsigned char tpm_failure[] = {
  25.965 ++    0x00, 0x00,
  25.966 ++    0x00, 0x00, 0x00, 0x0a,
  25.967 ++    0x00, 0x00, 0x00, 0x09
  25.968 ++};
  25.969 ++
  25.970 ++
  25.971 ++/*
  25.972 ++ * Send a TPM request.
  25.973 ++ */
  25.974 ++static int TPM_Send(tpmState *s, tpmBuffer *buffer, char *msg)
  25.975 ++{
  25.976 ++    int len;
  25.977 ++    uint32_t size = tpm_get_size_from_buffer(buffer->buf);
  25.978 ++
  25.979 ++    /* try to establish a connection to the vTPM */
  25.980 ++    if ( !IS_COMM_WITH_VTPM(s)) {
  25.981 ++        open_vtpm_channel(s);
  25.982 ++    }
  25.983 ++
  25.984 ++    if ( !IS_COMM_WITH_VTPM(s)) {
  25.985 ++        unsigned char tag = buffer->buf[1];
  25.986 ++
  25.987 ++        /* there's a failure response from the TPM */
  25.988 ++        memcpy(buffer->buf, tpm_failure, sizeof(tpm_failure));
  25.989 ++        buffer->buf[1] = tag + 3;
  25.990 ++        if (IS_VALID_LOC(s->active_loc)) {
  25.991 ++            s->loc[s->active_loc].sts = STS_DATA_AVAILABLE | STS_VALID;
  25.992 ++        }
  25.993 ++#ifdef DEBUG_TPM
  25.994 ++        fprintf(logfile,"No TPM running!\n");
  25.995 ++#endif
  25.996 ++        /* the request went out ok. */
  25.997 ++        return sizeof(buffer->instance) + size;
  25.998 ++    }
  25.999 ++
 25.1000 ++#ifdef DEBUG_TPM
 25.1001 ++    showBuff(buffer->buf, "To TPM");
 25.1002 ++#endif
 25.1003 ++
 25.1004 ++    len = vTPMTransmit[s->Transmitlayer].write(s, buffer);
 25.1005 ++    if (len < 0) {
 25.1006 ++        s->Transmitlayer = -1;
 25.1007 ++    }
 25.1008 ++    return len;
 25.1009 ++}
 25.1010 ++
 25.1011 ++/*
 25.1012 ++ * Try to receive data from the file descriptor. Since it is in
 25.1013 ++ * non-blocking mode it is possible that no data are actually received -
 25.1014 ++ * whatever calls this function needs to try again later.
 25.1015 ++ */
 25.1016 ++static int TPM_Receive(tpmState *s, tpmBuffer *buffer)
 25.1017 ++{
 25.1018 ++    int off;
 25.1019 ++
 25.1020 ++    off = vTPMTransmit[s->Transmitlayer].read(s, buffer);
 25.1021 ++
 25.1022 ++    if (off < 0) {
 25.1023 ++        /* EAGAIN is set in errno due to non-blocking mode */
 25.1024 ++        return -1;
 25.1025 ++    }
 25.1026 ++
 25.1027 ++    if (off == 0) {
 25.1028 ++#ifdef DEBUG_TPM
 25.1029 ++        fprintf(logfile,"TPM GONE? errno=%d\n",errno);
 25.1030 ++#endif
 25.1031 ++        close_vtpm_channel(s, 1);
 25.1032 ++        /* pretend that data are available */
 25.1033 ++        if (IS_VALID_LOC(s->active_loc)) {
 25.1034 ++            s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
 25.1035 ++            s->loc[s->active_loc].state = STATE_COMPLETION;
 25.1036 ++            tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
 25.1037 ++        }
 25.1038 ++        return -1;
 25.1039 ++    }
 25.1040 ++
 25.1041 ++#ifdef DEBUG_TPM
 25.1042 ++    if (off > sizeof(buffer->instance ) + 6) {
 25.1043 ++        uint32_t size = tpm_get_size_from_buffer(buffer->buf);
 25.1044 ++        if (size + sizeof(buffer->instance) != off) {
 25.1045 ++            fprintf(logfile,"TPM: Packet size is bad! %d != %d\n",
 25.1046 ++                    size + sizeof(buffer->instance),
 25.1047 ++                    off);
 25.1048 ++        } else {
 25.1049 ++            uint32_t ret;
 25.1050 ++            showBuff(buffer->buf, "From TPM");
 25.1051 ++            ret = (buffer->buf[8])*256 + buffer->buf[9];
 25.1052 ++            if (ret)
 25.1053 ++                fprintf(logfile,"Receive failed with error %d\n", ret);
 25.1054 ++            else
 25.1055 ++                fprintf(logfile,"Receive succeeded. Got response of length %d (=%d)\n",
 25.1056 ++                       size, off);
 25.1057 ++        }
 25.1058 ++    }
 25.1059 ++#endif
 25.1060 ++
 25.1061 ++    /* assuming reading in one chunk for now */
 25.1062 ++    return off;
 25.1063 ++}
 25.1064 ++
 25.1065 ++
 25.1066 ++/****************************************************************************
 25.1067 ++   Helper functions for reading data from the xenstore such as
 25.1068 ++   reading virtual TPM instance information
 25.1069 ++ ****************************************************************************/
 25.1070 ++int has_tpm_device(void)
 25.1071 ++{
 25.1072 ++    int ret = 0;
 25.1073 ++    struct xs_handle *handle = xs_daemon_open();
 25.1074 ++    if (handle) {
 25.1075 ++        ret = xenstore_domain_has_devtype(handle, "vtpm");
 25.1076 ++        xs_daemon_close(handle);
 25.1077 ++    }
 25.1078 ++    return ret;
 25.1079 ++}
 25.1080 ++
 25.1081 ++
 25.1082 ++/*
 25.1083 ++ * Wait until hotplug scripts have finished then read the vTPM instance
 25.1084 ++ * number from the xenstore.
 25.1085 ++ */
 25.1086 ++static uint32_t vtpm_instance_from_xenstore(void)
 25.1087 ++{
 25.1088 ++    unsigned int num;
 25.1089 ++    uint32_t number = VTPM_BAD_INSTANCE;
 25.1090 ++    int end = 0;
 25.1091 ++    char *token = "tok";
 25.1092 ++    int subscribed = 0;
 25.1093 ++    int ctr = 0;
 25.1094 ++    fd_set readfds;
 25.1095 ++
 25.1096 ++    struct xs_handle *handle = xs_daemon_open();
 25.1097 ++
 25.1098 ++    FD_ZERO(&readfds);
 25.1099 ++
 25.1100 ++    if (handle) {
 25.1101 ++        char **e = xenstore_domain_get_devices(handle, "vtpm", &num);
 25.1102 ++        int fd = xs_fileno(handle);
 25.1103 ++        FD_SET(fd, &readfds);
 25.1104 ++        if (e) {
 25.1105 ++            do {
 25.1106 ++                struct timeval tv = {
 25.1107 ++                    .tv_sec  = 30,
 25.1108 ++                    .tv_usec = 0,
 25.1109 ++                };
 25.1110 ++                /* need to make sure that the hotplug scripts have finished */
 25.1111 ++                char *status = xenstore_read_hotplug_status(handle,
 25.1112 ++                                                            "vtpm",
 25.1113 ++                                                            e[0]);
 25.1114 ++                if (status) {
 25.1115 ++                    if (!strcmp(status, "connected")) {
 25.1116 ++                        char *inst = xenstore_backend_read_variable(handle,
 25.1117 ++                                                                    "vtpm",
 25.1118 ++                                                                    e[0],
 25.1119 ++                                                                   "instance");
 25.1120 ++                        if (1 != (sscanf(inst,"%d",&number)))
 25.1121 ++                            number = VTPM_BAD_INSTANCE;
 25.1122 ++                        free(inst);
 25.1123 ++                    } else {
 25.1124 ++                        fprintf(logfile,
 25.1125 ++                                "bad status '%s' from vtpm hotplug\n",
 25.1126 ++                                status);
 25.1127 ++                    }
 25.1128 ++                    free(status);
 25.1129 ++                    end = 1;
 25.1130 ++                } else {
 25.1131 ++                    /* no status, yet */
 25.1132 ++                    int rc;
 25.1133 ++                    unsigned int nr;
 25.1134 ++                    char **f;
 25.1135 ++
 25.1136 ++                    if (!subscribed) {
 25.1137 ++                        rc = xenstore_subscribe_to_hotplug_status(handle,
 25.1138 ++                                                                  "vtpm",
 25.1139 ++                                                                  e[0],
 25.1140 ++                                                                  token);
 25.1141 ++                        if (rc != 0)
 25.1142 ++                            break;
 25.1143 ++                        subscribed = 1;
 25.1144 ++                    }
 25.1145 ++                    rc = select(fd+1, &readfds, NULL, NULL, &tv);
 25.1146 ++                    /* get what's available -- drain the fd */
 25.1147 ++                    f = xs_read_watch(handle, &nr);
 25.1148 ++                    ctr++;
 25.1149 ++                    free(f);
 25.1150 ++                    if (ctr > 2)
 25.1151 ++                        end = 1;
 25.1152 ++                }
 25.1153 ++            } while (end == 0);
 25.1154 ++            free(e);
 25.1155 ++        }
 25.1156 ++        if (subscribed) {
 25.1157 ++            /* clean up */
 25.1158 ++            xenstore_unsubscribe_from_hotplug_status(handle,
 25.1159 ++                                                     "vtpm",
 25.1160 ++                                                     e[0],
 25.1161 ++                                                     token);
 25.1162 ++        }
 25.1163 ++        xs_daemon_close(handle);
 25.1164 ++    }
 25.1165 ++    if (number == VTPM_BAD_INSTANCE)
 25.1166 ++        fprintf(logfile, "no valid vtpm instance");
 25.1167 ++    else
 25.1168 ++        fprintf(logfile,"vtpm instance:%d\n",number);
 25.1169 ++    return number;
 25.1170 ++}
 25.1171 +Index: ioemu/vl.h
 25.1172 +===================================================================
 25.1173 +--- ioemu.orig/vl.h	2006-12-08 18:20:53.000000000 +0000
 25.1174 ++++ ioemu/vl.h	2006-12-08 18:21:18.000000000 +0000
 25.1175 +@@ -932,6 +932,10 @@
 25.1176 + void piix4_pm_init(PCIBus *bus, int devfn);
 25.1177 + void acpi_bios_init(void);
 25.1178 + 
 25.1179 ++/* tpm_tis.c */
 25.1180 ++int has_tpm_device(void);
 25.1181 ++void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
 25.1182 ++
 25.1183 + /* piix4acpi.c */
 25.1184 + extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
 25.1185 + 
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tools/ioemu/patches/usb-uhci-buffer-size	Fri Dec 08 18:31:01 2006 +0000
    26.3 @@ -0,0 +1,25 @@
    26.4 +# HG changeset patch
    26.5 +# User kfraser@localhost.localdomain
    26.6 +# Node ID f19ddc0ee3e68d5d8a250ba0a20ab7d90ae9a36a
    26.7 +# Parent  f66f7c3a82a7420d80714b0d349ee9a24b50ec28
    26.8 +[QEMU] usb-uhci: Data buffer is too small
    26.9 +
   26.10 +The data buffer is only 1280 bytes long but the user-supplied length
   26.11 +can be as large as 0x7ff.  This patch extends the buffer to 2048
   26.12 +bytes.
   26.13 +
   26.14 +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
   26.15 +
   26.16 +Index: ioemu/hw/usb-uhci.c
   26.17 +===================================================================
   26.18 +--- ioemu.orig/hw/usb-uhci.c	2006-12-08 18:21:36.000000000 +0000
   26.19 ++++ ioemu/hw/usb-uhci.c	2006-12-08 18:23:06.000000000 +0000
   26.20 +@@ -421,7 +421,7 @@
   26.21 + static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
   26.22 + {
   26.23 +     uint8_t pid;
   26.24 +-    uint8_t buf[1280];
   26.25 ++    uint8_t buf[2048];
   26.26 +     int len, max_len, err, ret;
   26.27 + 
   26.28 +     if (td->ctrl & TD_CTRL_IOC) {
    27.1 --- a/tools/ioemu/patches/vnc-access-monitor-vt	Fri Dec 08 07:22:21 2006 -0800
    27.2 +++ b/tools/ioemu/patches/vnc-access-monitor-vt	Fri Dec 08 18:31:01 2006 +0000
    27.3 @@ -1,7 +1,7 @@
    27.4  Index: ioemu/vnc.c
    27.5  ===================================================================
    27.6 ---- ioemu.orig/vnc.c	2006-10-24 14:33:46.000000000 +0100
    27.7 -+++ ioemu/vnc.c	2006-10-24 14:33:46.000000000 +0100
    27.8 +--- ioemu.orig/vnc.c	2006-12-06 23:46:11.000000000 +0000
    27.9 ++++ ioemu/vnc.c	2006-12-06 23:46:11.000000000 +0000
   27.10  @@ -33,6 +33,10 @@
   27.11   #include "vnc_keysym.h"
   27.12   #include "keymaps.c"
   27.13 @@ -22,7 +22,7 @@ Index: ioemu/vnc.c
   27.14   };
   27.15   
   27.16   #define DIRTY_PIXEL_BITS 64
   27.17 -@@ -794,16 +800,80 @@
   27.18 +@@ -796,16 +802,80 @@
   27.19   
   27.20   static void do_key_event(VncState *vs, int down, uint32_t sym)
   27.21   {
    28.1 --- a/tools/ioemu/patches/vnc-backoff-screen-scan	Fri Dec 08 07:22:21 2006 -0800
    28.2 +++ b/tools/ioemu/patches/vnc-backoff-screen-scan	Fri Dec 08 18:31:01 2006 +0000
    28.3 @@ -1,7 +1,7 @@
    28.4  Index: ioemu/vnc.c
    28.5  ===================================================================
    28.6 ---- ioemu.orig/vnc.c	2006-10-24 14:33:17.000000000 +0100
    28.7 -+++ ioemu/vnc.c	2006-10-24 14:33:24.000000000 +0100
    28.8 +--- ioemu.orig/vnc.c	2006-12-06 23:46:12.000000000 +0000
    28.9 ++++ ioemu/vnc.c	2006-12-06 23:46:12.000000000 +0000
   28.10  @@ -28,7 +28,19 @@
   28.11   #include "qemu_socket.h"
   28.12   #include <assert.h>
   28.13 @@ -45,7 +45,7 @@ Index: ioemu/vnc.c
   28.14       int ctl_keys;               /* Ctrl+Alt starts calibration */
   28.15   };
   28.16   
   28.17 -@@ -381,7 +392,7 @@
   28.18 +@@ -383,7 +394,7 @@
   28.19       int y = 0;
   28.20       int pitch = ds->linesize;
   28.21       VncState *vs = ds->opaque;
   28.22 @@ -54,7 +54,7 @@ Index: ioemu/vnc.c
   28.23   
   28.24       if (src_x < vs->visible_x || src_y < vs->visible_y ||
   28.25   	dst_x < vs->visible_x || dst_y < vs->visible_y ||
   28.26 -@@ -391,10 +402,8 @@
   28.27 +@@ -393,10 +404,8 @@
   28.28   	(dst_y + h) > (vs->visible_y + vs->visible_h))
   28.29   	updating_client = 0;
   28.30   
   28.31 @@ -66,7 +66,7 @@ Index: ioemu/vnc.c
   28.32   
   28.33       if (dst_y > src_y) {
   28.34   	y = h - 1;
   28.35 -@@ -446,110 +455,149 @@
   28.36 +@@ -448,110 +457,149 @@
   28.37   static void _vnc_update_client(void *opaque)
   28.38   {
   28.39       VncState *vs = opaque;
   28.40 @@ -299,7 +299,7 @@ Index: ioemu/vnc.c
   28.41   }
   28.42   
   28.43   static void vnc_update_client(void *opaque)
   28.44 -@@ -562,8 +610,10 @@
   28.45 +@@ -564,8 +612,10 @@
   28.46   
   28.47   static void vnc_timer_init(VncState *vs)
   28.48   {
   28.49 @@ -311,7 +311,7 @@ Index: ioemu/vnc.c
   28.50   }
   28.51   
   28.52   static void vnc_dpy_refresh(DisplayState *ds)
   28.53 -@@ -623,7 +673,6 @@
   28.54 +@@ -625,7 +675,6 @@
   28.55   	vs->csock = -1;
   28.56   	buffer_reset(&vs->input);
   28.57   	buffer_reset(&vs->output);
   28.58 @@ -319,7 +319,7 @@ Index: ioemu/vnc.c
   28.59   	return 0;
   28.60       }
   28.61       return ret;
   28.62 -@@ -895,7 +944,6 @@
   28.63 +@@ -897,7 +946,6 @@
   28.64   				       int x_position, int y_position,
   28.65   				       int w, int h)
   28.66   {
   28.67 @@ -327,7 +327,7 @@ Index: ioemu/vnc.c
   28.68       if (!incremental)
   28.69   	framebuffer_set_updated(vs, x_position, y_position, w, h);
   28.70       vs->visible_x = x_position;
   28.71 -@@ -1018,6 +1066,7 @@
   28.72 +@@ -1020,6 +1068,7 @@
   28.73   {
   28.74       int i;
   28.75       uint16_t limit;
   28.76 @@ -335,7 +335,7 @@ Index: ioemu/vnc.c
   28.77   
   28.78       switch (data[0]) {
   28.79       case 0:
   28.80 -@@ -1061,12 +1110,18 @@
   28.81 +@@ -1063,12 +1112,18 @@
   28.82   	if (len == 1)
   28.83   	    return 8;
   28.84   
   28.85 @@ -356,8 +356,8 @@ Index: ioemu/vnc.c
   28.86       case 6:
   28.87  Index: ioemu/vl.c
   28.88  ===================================================================
   28.89 ---- ioemu.orig/vl.c	2006-10-24 14:33:17.000000000 +0100
   28.90 -+++ ioemu/vl.c	2006-10-24 14:33:24.000000000 +0100
   28.91 +--- ioemu.orig/vl.c	2006-12-06 23:46:12.000000000 +0000
   28.92 ++++ ioemu/vl.c	2006-12-06 23:46:12.000000000 +0000
   28.93  @@ -726,6 +726,12 @@
   28.94       }
   28.95   }
   28.96 @@ -373,8 +373,8 @@ Index: ioemu/vl.c
   28.97   void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
   28.98  Index: ioemu/vl.h
   28.99  ===================================================================
  28.100 ---- ioemu.orig/vl.h	2006-10-24 14:33:17.000000000 +0100
  28.101 -+++ ioemu/vl.h	2006-10-24 14:33:24.000000000 +0100
  28.102 +--- ioemu.orig/vl.h	2006-12-06 23:46:12.000000000 +0000
  28.103 ++++ ioemu/vl.h	2006-12-06 23:46:12.000000000 +0000
  28.104  @@ -407,6 +407,7 @@
  28.105   void qemu_free_timer(QEMUTimer *ts);
  28.106   void qemu_del_timer(QEMUTimer *ts);
    29.1 --- a/tools/ioemu/patches/vnc-display-find-unused	Fri Dec 08 07:22:21 2006 -0800
    29.2 +++ b/tools/ioemu/patches/vnc-display-find-unused	Fri Dec 08 18:31:01 2006 +0000
    29.3 @@ -1,8 +1,8 @@
    29.4  Index: ioemu/vnc.c
    29.5  ===================================================================
    29.6 ---- ioemu.orig/vnc.c	2006-10-24 14:31:09.000000000 +0100
    29.7 -+++ ioemu/vnc.c	2006-10-24 14:31:36.000000000 +0100
    29.8 -@@ -1195,7 +1195,7 @@
    29.9 +--- ioemu.orig/vnc.c	2006-12-08 02:02:36.000000000 +0000
   29.10 ++++ ioemu/vnc.c	2006-12-08 02:02:37.000000000 +0000
   29.11 +@@ -1197,7 +1197,7 @@
   29.12       }
   29.13   }
   29.14   
   29.15 @@ -11,7 +11,7 @@ Index: ioemu/vnc.c
   29.16   {
   29.17       struct sockaddr_in addr;
   29.18       int reuse_addr, ret;
   29.19 -@@ -1226,10 +1226,6 @@
   29.20 +@@ -1228,10 +1228,6 @@
   29.21   	exit(1);
   29.22       }
   29.23   
   29.24 @@ -22,7 +22,7 @@ Index: ioemu/vnc.c
   29.25       reuse_addr = 1;
   29.26       ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
   29.27   		     (const char *)&reuse_addr, sizeof(reuse_addr));
   29.28 -@@ -1238,7 +1234,16 @@
   29.29 +@@ -1240,7 +1236,16 @@
   29.30   	exit(1);
   29.31       }
   29.32   
   29.33 @@ -39,7 +39,7 @@ Index: ioemu/vnc.c
   29.34   	fprintf(stderr, "bind() failed\n");
   29.35   	exit(1);
   29.36       }
   29.37 -@@ -1259,6 +1264,8 @@
   29.38 +@@ -1261,6 +1266,8 @@
   29.39       vs->ds->dpy_refresh = vnc_dpy_refresh;
   29.40   
   29.41       vnc_dpy_resize(vs->ds, 640, 400);
   29.42 @@ -50,8 +50,8 @@ Index: ioemu/vnc.c
   29.43   int vnc_start_viewer(int port)
   29.44  Index: ioemu/vl.c
   29.45  ===================================================================
   29.46 ---- ioemu.orig/vl.c	2006-10-24 14:31:09.000000000 +0100
   29.47 -+++ ioemu/vl.c	2006-10-24 14:31:41.000000000 +0100
   29.48 +--- ioemu.orig/vl.c	2006-12-08 02:02:36.000000000 +0000
   29.49 ++++ ioemu/vl.c	2006-12-08 02:02:37.000000000 +0000
   29.50  @@ -121,6 +121,7 @@
   29.51   static DisplayState display_state;
   29.52   int nographic;
   29.53 @@ -84,7 +84,7 @@ Index: ioemu/vl.c
   29.54       
   29.55       /* temporary options */
   29.56       { "usb", 0, QEMU_OPTION_usb },
   29.57 -@@ -5873,6 +5877,7 @@
   29.58 +@@ -5857,6 +5861,7 @@
   29.59       snapshot = 0;
   29.60       nographic = 0;
   29.61       vncviewer = 0;
   29.62 @@ -92,7 +92,7 @@ Index: ioemu/vl.c
   29.63       kernel_filename = NULL;
   29.64       kernel_cmdline = "";
   29.65   #ifdef TARGET_PPC
   29.66 -@@ -6270,6 +6275,11 @@
   29.67 +@@ -6254,6 +6259,11 @@
   29.68               case QEMU_OPTION_vncviewer:
   29.69                   vncviewer++;
   29.70                   break;
   29.71 @@ -104,7 +104,7 @@ Index: ioemu/vl.c
   29.72               }
   29.73           }
   29.74       }
   29.75 -@@ -6483,7 +6493,7 @@
   29.76 +@@ -6468,7 +6478,7 @@
   29.77       if (nographic) {
   29.78           dumb_display_init(ds);
   29.79       } else if (vnc_display != -1) {
   29.80 @@ -115,8 +115,8 @@ Index: ioemu/vl.c
   29.81       } else {
   29.82  Index: ioemu/vl.h
   29.83  ===================================================================
   29.84 ---- ioemu.orig/vl.h	2006-10-24 14:31:09.000000000 +0100
   29.85 -+++ ioemu/vl.h	2006-10-24 14:31:36.000000000 +0100
   29.86 +--- ioemu.orig/vl.h	2006-12-08 02:02:36.000000000 +0000
   29.87 ++++ ioemu/vl.h	2006-12-08 02:02:37.000000000 +0000
   29.88  @@ -785,7 +785,7 @@
   29.89   void cocoa_display_init(DisplayState *ds, int full_screen);
   29.90   
    30.1 --- a/tools/ioemu/patches/vnc-fixes	Fri Dec 08 07:22:21 2006 -0800
    30.2 +++ b/tools/ioemu/patches/vnc-fixes	Fri Dec 08 18:31:01 2006 +0000
    30.3 @@ -1,8 +1,8 @@
    30.4  Index: ioemu/vl.c
    30.5  ===================================================================
    30.6 ---- ioemu.orig/vl.c	2006-10-24 13:47:23.000000000 +0100
    30.7 -+++ ioemu/vl.c	2006-10-24 14:19:36.000000000 +0100
    30.8 -@@ -6534,8 +6534,10 @@
    30.9 +--- ioemu.orig/vl.c	2006-12-08 02:02:36.000000000 +0000
   30.10 ++++ ioemu/vl.c	2006-12-08 02:02:36.000000000 +0000
   30.11 +@@ -6519,8 +6519,10 @@
   30.12           }
   30.13       }
   30.14   
   30.15 @@ -17,8 +17,8 @@ Index: ioemu/vl.c
   30.16       if (use_gdbstub) {
   30.17  Index: ioemu/vnc.c
   30.18  ===================================================================
   30.19 ---- ioemu.orig/vnc.c	2006-10-24 13:47:23.000000000 +0100
   30.20 -+++ ioemu/vnc.c	2006-10-24 14:20:00.000000000 +0100
   30.21 +--- ioemu.orig/vnc.c	2006-12-08 02:02:36.000000000 +0000
   30.22 ++++ ioemu/vnc.c	2006-12-08 02:02:36.000000000 +0000
   30.23  @@ -3,6 +3,7 @@
   30.24    * 
   30.25    * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
   30.26 @@ -92,7 +92,7 @@ Index: ioemu/vnc.c
   30.27   static inline void vnc_set_bit(uint32_t *d, int k)
   30.28   {
   30.29       d[k >> 5] |= 1 << (k & 0x1f);
   30.30 -@@ -139,20 +161,35 @@
   30.31 +@@ -139,20 +161,37 @@
   30.32       }
   30.33       return 0;
   30.34   }
   30.35 @@ -121,6 +121,8 @@ Index: ioemu/vnc.c
   30.36   	mask = ~(0ULL);
   30.37   
   30.38  +    h += y;
   30.39 ++    if (h > vs->ds->height)
   30.40 ++        h = vs->ds->height;
   30.41       for (; y < h; y++)
   30.42  -	vs->dirty_row[y] |= mask;
   30.43  +	row[y] |= mask;
   30.44 @@ -134,7 +136,7 @@ Index: ioemu/vnc.c
   30.45   }
   30.46   
   30.47   static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
   30.48 -@@ -169,16 +206,23 @@
   30.49 +@@ -169,16 +208,23 @@
   30.50   static void vnc_dpy_resize(DisplayState *ds, int w, int h)
   30.51   {
   30.52       VncState *vs = ds->opaque;
   30.53 @@ -160,7 +162,7 @@ Index: ioemu/vnc.c
   30.54       ds->width = w;
   30.55       ds->height = h;
   30.56       ds->linesize = w * vs->depth;
   30.57 -@@ -191,6 +235,10 @@
   30.58 +@@ -191,6 +237,10 @@
   30.59   	vs->width = ds->width;
   30.60   	vs->height = ds->height;
   30.61       }
   30.62 @@ -171,7 +173,7 @@ Index: ioemu/vnc.c
   30.63   }
   30.64   
   30.65   /* fastest code */
   30.66 -@@ -326,8 +374,20 @@
   30.67 +@@ -326,8 +376,20 @@
   30.68       int y = 0;
   30.69       int pitch = ds->linesize;
   30.70       VncState *vs = ds->opaque;
   30.71 @@ -193,7 +195,7 @@ Index: ioemu/vnc.c
   30.72   
   30.73       if (dst_y > src_y) {
   30.74   	y = h - 1;
   30.75 -@@ -349,31 +409,34 @@
   30.76 +@@ -349,31 +411,34 @@
   30.77   	old_row += pitch;
   30.78       }
   30.79   
   30.80 @@ -240,7 +242,7 @@ Index: ioemu/vnc.c
   30.81   {
   30.82       VncState *vs = opaque;
   30.83       int64_t now = qemu_get_clock(rt_clock);
   30.84 -@@ -382,14 +445,18 @@
   30.85 +@@ -382,14 +447,18 @@
   30.86   	int y;
   30.87   	char *row;
   30.88   	char *old_row;
   30.89 @@ -262,7 +264,7 @@ Index: ioemu/vnc.c
   30.90   
   30.91   	/* Walk through the dirty map and eliminate tiles that
   30.92   	   really aren't dirty */
   30.93 -@@ -397,23 +464,25 @@
   30.94 +@@ -397,23 +466,25 @@
   30.95   	old_row = vs->old_data;
   30.96   
   30.97   	for (y = 0; y < vs->ds->height; y++) {
   30.98 @@ -297,7 +299,7 @@ Index: ioemu/vnc.c
   30.99   		}
  30.100   	    }
  30.101   
  30.102 -@@ -421,7 +490,8 @@
  30.103 +@@ -421,7 +492,8 @@
  30.104   	    old_row += vs->ds->linesize;
  30.105   	}
  30.106   
  30.107 @@ -307,7 +309,7 @@ Index: ioemu/vnc.c
  30.108   	    return;
  30.109   
  30.110   	/* Count rectangles */
  30.111 -@@ -431,34 +501,56 @@
  30.112 +@@ -431,34 +503,56 @@
  30.113   	saved_offset = vs->output.offset;
  30.114   	vnc_write_u16(vs, 0);
  30.115   
  30.116 @@ -375,7 +377,7 @@ Index: ioemu/vnc.c
  30.117   }
  30.118   
  30.119   static void vnc_timer_init(VncState *vs)
  30.120 -@@ -469,8 +561,6 @@
  30.121 +@@ -469,8 +563,6 @@
  30.122   
  30.123   static void vnc_dpy_refresh(DisplayState *ds)
  30.124   {
  30.125 @@ -384,7 +386,7 @@ Index: ioemu/vnc.c
  30.126       vga_hw_update();
  30.127   }
  30.128   
  30.129 -@@ -506,7 +596,7 @@
  30.130 +@@ -506,7 +598,7 @@
  30.131   
  30.132   static void buffer_reset(Buffer *buffer)
  30.133   {
  30.134 @@ -393,7 +395,7 @@ Index: ioemu/vnc.c
  30.135   }
  30.136   
  30.137   static void buffer_append(Buffer *buffer, const void *data, size_t len)
  30.138 -@@ -547,12 +637,12 @@
  30.139 +@@ -547,12 +639,12 @@
  30.140       if (!ret)
  30.141   	return;
  30.142   
  30.143 @@ -409,7 +411,7 @@ Index: ioemu/vnc.c
  30.144   }
  30.145   
  30.146   static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
  30.147 -@@ -584,11 +674,11 @@
  30.148 +@@ -584,11 +676,11 @@
  30.149   	    return;
  30.150   
  30.151   	if (!ret) {
  30.152 @@ -424,7 +426,7 @@ Index: ioemu/vnc.c
  30.153       }
  30.154   }
  30.155   
  30.156 -@@ -596,9 +686,9 @@
  30.157 +@@ -596,9 +688,9 @@
  30.158   {
  30.159       buffer_reserve(&vs->output, len);
  30.160   
  30.161 @@ -437,7 +439,7 @@ Index: ioemu/vnc.c
  30.162   
  30.163       buffer_append(&vs->output, data, len);
  30.164   }
  30.165 -@@ -720,22 +810,25 @@
  30.166 +@@ -720,22 +812,25 @@
  30.167       do_key_event(vs, down, sym);
  30.168   }
  30.169   
  30.170 @@ -474,7 +476,7 @@ Index: ioemu/vnc.c
  30.171   
  30.172       qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
  30.173   }
  30.174 -@@ -843,8 +936,6 @@
  30.175 +@@ -843,8 +938,6 @@
  30.176       }
  30.177   
  30.178       vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
  30.179 @@ -483,7 +485,7 @@ Index: ioemu/vnc.c
  30.180   
  30.181       vga_hw_invalidate();
  30.182       vga_hw_update();
  30.183 -@@ -924,6 +1015,8 @@
  30.184 +@@ -924,6 +1017,8 @@
  30.185   {
  30.186       char pad[3] = { 0, 0, 0 };
  30.187   
  30.188 @@ -492,7 +494,7 @@ Index: ioemu/vnc.c
  30.189       vs->width = vs->ds->width;
  30.190       vs->height = vs->ds->height;
  30.191       vnc_write_u16(vs, vs->ds->width);
  30.192 -@@ -1010,11 +1103,11 @@
  30.193 +@@ -1010,11 +1105,11 @@
  30.194   	vnc_write(vs, "RFB 003.003\n", 12);
  30.195   	vnc_flush(vs);
  30.196   	vnc_read_when(vs, protocol_version, 12);
  30.197 @@ -506,7 +508,7 @@ Index: ioemu/vnc.c
  30.198       }
  30.199   }
  30.200   
  30.201 -@@ -1071,17 +1164,15 @@
  30.202 +@@ -1071,17 +1166,15 @@
  30.203   	exit(1);
  30.204       }
  30.205   
  30.206 @@ -529,8 +531,8 @@ Index: ioemu/vnc.c
  30.207   }
  30.208  Index: ioemu/vl.h
  30.209  ===================================================================
  30.210 ---- ioemu.orig/vl.h	2006-10-24 13:47:23.000000000 +0100
  30.211 -+++ ioemu/vl.h	2006-10-24 14:19:36.000000000 +0100
  30.212 +--- ioemu.orig/vl.h	2006-12-08 02:02:36.000000000 +0000
  30.213 ++++ ioemu/vl.h	2006-12-08 02:02:36.000000000 +0000
  30.214  @@ -319,6 +319,7 @@
  30.215   int is_graphic_console(void);
  30.216   CharDriverState *text_console_init(DisplayState *ds);
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/ioemu/patches/vnc-japan-keymap	Fri Dec 08 18:31:01 2006 +0000
    31.3 @@ -0,0 +1,39 @@
    31.4 +# HG changeset patch
    31.5 +# User kasai.takanori@jp.fujitsu.com
    31.6 +# Node ID ea1ffa51b4121d36cffdc90276378a6ed334c2cc
    31.7 +# Parent  edd592c823a520d4072a95ac39beb2012c05321e
    31.8 +Add the Japanese keymap for VNC Server.
    31.9 +
   31.10 +Signed-off-by: Takanori Kasai < kasai.takanori@jp.fujitsu.com >
   31.11 +
   31.12 +Index: ioemu/keymaps/ja
   31.13 +===================================================================
   31.14 +--- ioemu.orig/keymaps/ja	2006-12-08 18:21:36.000000000 +0000
   31.15 ++++ ioemu/keymaps/ja	2006-12-08 18:21:56.000000000 +0000
   31.16 +@@ -102,3 +102,6 @@
   31.17 + Henkan_Mode 0x79
   31.18 + Katakana 0x70
   31.19 + Muhenkan 0x7b
   31.20 ++Henkan_Mode_Real 0x79
   31.21 ++Henkan_Mode_Ultra 0x79
   31.22 ++backslash_ja 0x73
   31.23 +Index: ioemu/vnc_keysym.h
   31.24 +===================================================================
   31.25 +--- ioemu.orig/vnc_keysym.h	2006-12-08 18:21:36.000000000 +0000
   31.26 ++++ ioemu/vnc_keysym.h	2006-12-08 18:21:56.000000000 +0000
   31.27 +@@ -271,5 +271,15 @@
   31.28 + {"Num_Lock", 0xff7f},    /* XK_Num_Lock */
   31.29 + {"Pause", 0xff13},       /* XK_Pause */
   31.30 + {"Escape", 0xff1b},      /* XK_Escape */
   31.31 ++
   31.32 ++    /* localized keys */
   31.33 ++{"BackApostrophe", 0xff21},
   31.34 ++{"Muhenkan", 0xff22},
   31.35 ++{"Katakana", 0xff25},
   31.36 ++{"Zenkaku_Hankaku", 0xff29},
   31.37 ++{"Henkan_Mode_Real", 0xff23},
   31.38 ++{"Henkan_Mode_Ultra", 0xff3e},
   31.39 ++{"backslash_ja", 0xffa5},
   31.40 ++
   31.41 + {0,0},
   31.42 + };
    32.1 --- a/tools/ioemu/patches/vnc-listen-specific-interface	Fri Dec 08 07:22:21 2006 -0800
    32.2 +++ b/tools/ioemu/patches/vnc-listen-specific-interface	Fri Dec 08 18:31:01 2006 +0000
    32.3 @@ -20,8 +20,8 @@ Signed-off-by:  Daniel P. Berrange <berr
    32.4  
    32.5  Index: ioemu/vl.c
    32.6  ===================================================================
    32.7 ---- ioemu.orig/vl.c	2006-10-24 14:33:46.000000000 +0100
    32.8 -+++ ioemu/vl.c	2006-10-24 14:34:28.000000000 +0100
    32.9 +--- ioemu.orig/vl.c	2006-12-08 02:02:37.000000000 +0000
   32.10 ++++ ioemu/vl.c	2006-12-08 02:02:37.000000000 +0000
   32.11  @@ -122,6 +122,7 @@
   32.12   int nographic;
   32.13   int vncviewer;
   32.14 @@ -95,7 +95,7 @@ Index: ioemu/vl.c
   32.15       
   32.16       /* temporary options */
   32.17       { "usb", 0, QEMU_OPTION_usb },
   32.18 -@@ -5905,6 +5915,8 @@
   32.19 +@@ -5889,6 +5899,8 @@
   32.20   
   32.21       nb_nics = 0;
   32.22       /* default mac address of the first network interface */
   32.23 @@ -103,8 +103,8 @@ Index: ioemu/vl.c
   32.24  +    memset(&vnclisten_addr.sin_addr, 0, sizeof(vnclisten_addr.sin_addr));
   32.25       
   32.26       /* init debug */
   32.27 -     sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%d.log", getpid());
   32.28 -@@ -6280,6 +6292,9 @@
   32.29 +     sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%ld.log", (long)getpid());
   32.30 +@@ -6264,6 +6276,9 @@
   32.31                   if (vnc_display == -1)
   32.32                       vnc_display = 0;
   32.33                   break;
   32.34 @@ -114,7 +114,7 @@ Index: ioemu/vl.c
   32.35               }
   32.36           }
   32.37       }
   32.38 -@@ -6493,7 +6508,7 @@
   32.39 +@@ -6478,7 +6493,7 @@
   32.40       if (nographic) {
   32.41           dumb_display_init(ds);
   32.42       } else if (vnc_display != -1) {
   32.43 @@ -125,8 +125,8 @@ Index: ioemu/vl.c
   32.44       } else {
   32.45  Index: ioemu/vl.h
   32.46  ===================================================================
   32.47 ---- ioemu.orig/vl.h	2006-10-24 14:33:46.000000000 +0100
   32.48 -+++ ioemu/vl.h	2006-10-24 14:34:22.000000000 +0100
   32.49 +--- ioemu.orig/vl.h	2006-12-08 02:02:37.000000000 +0000
   32.50 ++++ ioemu/vl.h	2006-12-08 02:02:37.000000000 +0000
   32.51  @@ -37,6 +37,8 @@
   32.52   #include <unistd.h>
   32.53   #include <fcntl.h>
   32.54 @@ -147,9 +147,9 @@ Index: ioemu/vl.h
   32.55   /* ide.c */
   32.56  Index: ioemu/vnc.c
   32.57  ===================================================================
   32.58 ---- ioemu.orig/vnc.c	2006-10-24 14:33:46.000000000 +0100
   32.59 -+++ ioemu/vnc.c	2006-10-24 14:34:22.000000000 +0100
   32.60 -@@ -1195,9 +1195,8 @@
   32.61 +--- ioemu.orig/vnc.c	2006-12-08 02:02:37.000000000 +0000
   32.62 ++++ ioemu/vnc.c	2006-12-08 02:02:37.000000000 +0000
   32.63 +@@ -1197,9 +1197,8 @@
   32.64       }
   32.65   }
   32.66   
   32.67 @@ -160,7 +160,7 @@ Index: ioemu/vnc.c
   32.68       int reuse_addr, ret;
   32.69       VncState *vs;
   32.70   
   32.71 -@@ -1235,11 +1234,10 @@
   32.72 +@@ -1237,11 +1236,10 @@
   32.73       }
   32.74   
   32.75    retry:
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/tools/ioemu/patches/vnc-monitor-shift-key-processing	Fri Dec 08 18:31:01 2006 +0000
    33.3 @@ -0,0 +1,60 @@
    33.4 +# HG changeset patch
    33.5 +# User kfraser@localhost.localdomain
    33.6 +# Node ID 582d21e2d3cd12a13ad4debee9af8bb0f1be413a
    33.7 +# Parent  b7095209e31ae1f52cd4b196225a360543e37a80
    33.8 +[QEMU] Do shift-key processing in QEMU monitor terminal when connected via VNC.
    33.9 +Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
   33.10 +
   33.11 +Index: ioemu/vnc.c
   33.12 +===================================================================
   33.13 +--- ioemu.orig/vnc.c	2006-12-08 18:21:36.000000000 +0000
   33.14 ++++ ioemu/vnc.c	2006-12-08 18:23:12.000000000 +0000
   33.15 +@@ -114,6 +114,7 @@
   33.16 +     int visible_h;
   33.17 + 
   33.18 +     int ctl_keys;               /* Ctrl+Alt starts calibration */
   33.19 ++    int shift_keys;             /* Shift / CapsLock keys */
   33.20 + };
   33.21 + 
   33.22 + #define DIRTY_PIXEL_BITS 64
   33.23 +@@ -870,9 +871,12 @@
   33.24 +     } else if (down) {
   33.25 + 	int qemu_keysym = 0;
   33.26 + 
   33.27 +-	if (sym <= 128) /* normal ascii */
   33.28 ++	if (sym <= 128) { /* normal ascii */
   33.29 ++	    int shifted = vs->shift_keys == 1 || vs->shift_keys == 2;
   33.30 + 	    qemu_keysym = sym;
   33.31 +-	else {
   33.32 ++	    if (sym >= 'a' && sym <= 'z' && shifted)
   33.33 ++	        qemu_keysym -= 'a' - 'A';
   33.34 ++	} else {
   33.35 + 	    switch (sym) {
   33.36 + 	    case XK_Up: qemu_keysym = QEMU_KEY_UP; break;
   33.37 + 	    case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break;
   33.38 +@@ -903,6 +907,10 @@
   33.39 + 	    vs->ctl_keys |= 2;
   33.40 + 	    break;
   33.41 + 
   33.42 ++	case XK_Shift_L:
   33.43 ++	    vs->shift_keys |= 1;
   33.44 ++	    break;
   33.45 ++
   33.46 + 	default:
   33.47 + 	    break;
   33.48 + 	}
   33.49 +@@ -916,6 +924,14 @@
   33.50 + 	    vs->ctl_keys &= ~2;
   33.51 + 	    break;
   33.52 + 
   33.53 ++	case XK_Shift_L:
   33.54 ++	    vs->shift_keys &= ~1;
   33.55 ++	    break;
   33.56 ++
   33.57 ++	case XK_Caps_Lock:
   33.58 ++	    vs->shift_keys ^= 2;
   33.59 ++	    break;
   33.60 ++
   33.61 + 	case XK_1 ... XK_9:
   33.62 + 	    if ((vs->ctl_keys & 3) != 3)
   33.63 + 		break;
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/tools/ioemu/patches/vnc-numpad-handling	Fri Dec 08 18:31:01 2006 +0000
    34.3 @@ -0,0 +1,236 @@
    34.4 +# HG changeset patch
    34.5 +# User Ewan Mellor <ewan@xensource.com>
    34.6 +# Node ID c7f4a89eb054a1ad411da1e4cdc8aeda1a98c4fa
    34.7 +# Parent  565cd8f32c70da8ae7dbaaeb9dff28aa8b6307e1
    34.8 +Fix numpad handling in QEMU's VNC server.  The keymaps that we have include
    34.9 +information on which keys change depending upon the numlock setting, but
   34.10 +this isn't being used.  By forcing numlock on and off as necessary, when
   34.11 +receiving these keysyms through the VNC connection, we ensure that the
   34.12 +server's numlock status is the same as the client's.
   34.13 +
   34.14 +Signed-off-by: Ewan Mellor <ewan@xensource.com>
   34.15 +
   34.16 +Index: ioemu/keymaps.c
   34.17 +===================================================================
   34.18 +--- ioemu.orig/keymaps.c	2006-12-06 23:41:30.000000000 +0000
   34.19 ++++ ioemu/keymaps.c	2006-12-08 18:20:27.000000000 +0000
   34.20 +@@ -36,8 +36,10 @@
   34.21 + #define MAX_EXTRA_COUNT 256
   34.22 + typedef struct {
   34.23 +     uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
   34.24 ++    int keysym2numlock[MAX_NORMAL_KEYCODE];
   34.25 +     struct {
   34.26 + 	int keysym;
   34.27 ++	int numlock;
   34.28 + 	uint16_t keycode;
   34.29 +     } keysym2keycode_extra[MAX_EXTRA_COUNT];
   34.30 +     int extra_count;
   34.31 +@@ -50,6 +52,8 @@
   34.32 +     char file_name[1024];
   34.33 +     char line[1024];
   34.34 +     int len;
   34.35 ++    int *keycode2numlock;
   34.36 ++    int i;
   34.37 + 
   34.38 +     snprintf(file_name, sizeof(file_name),
   34.39 +              "%s/keymaps/%s", bios_dir, language);
   34.40 +@@ -63,6 +67,15 @@
   34.41 + 		"Could not read keymap file: '%s'\n", file_name);
   34.42 + 	return 0;
   34.43 +     }
   34.44 ++
   34.45 ++    /* Allocate a temporary map tracking which keycodes change when numlock is
   34.46 ++       set.  Keycodes are 16 bit, so 65536 is safe. */
   34.47 ++    keycode2numlock = malloc(65536 * sizeof(int));
   34.48 ++    if (!keycode2numlock) {
   34.49 ++        perror("Could not read keymap file");
   34.50 ++	return 0;
   34.51 ++    }
   34.52 ++
   34.53 +     for(;;) {
   34.54 + 	if (fgets(line, 1024, f) == NULL)
   34.55 +             break;
   34.56 +@@ -86,13 +99,19 @@
   34.57 + 		if (keysym == 0) {
   34.58 +                     //		    fprintf(stderr, "Warning: unknown keysym %s\n", line);
   34.59 + 		} else {
   34.60 +-		    const char *rest = end_of_keysym + 1;
   34.61 +-		    int keycode = strtol(rest, NULL, 0);
   34.62 ++		    char *rest = end_of_keysym + 1;
   34.63 ++		    int keycode = strtol(rest, &rest, 0);
   34.64 ++		    int numlock = (rest != NULL &&
   34.65 ++		                   strstr(rest, "numlock") != NULL);
   34.66 ++
   34.67 ++                    keycode2numlock[keycode] = numlock;
   34.68 ++
   34.69 + 		    /* if(keycode&0x80)
   34.70 + 		       keycode=(keycode<<8)^0x80e0; */
   34.71 + 		    if (keysym < MAX_NORMAL_KEYCODE) {
   34.72 + 			//fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
   34.73 + 			k->keysym2keycode[keysym] = keycode;
   34.74 ++			k->keysym2numlock[keysym] = numlock;
   34.75 + 		    } else {
   34.76 + 			if (k->extra_count >= MAX_EXTRA_COUNT) {
   34.77 + 			    fprintf(stderr,
   34.78 +@@ -107,6 +126,8 @@
   34.79 + 				keysym = keysym;
   34.80 + 			    k->keysym2keycode_extra[k->extra_count].
   34.81 + 				keycode = keycode;
   34.82 ++			    k->keysym2keycode_extra[k->extra_count].
   34.83 ++				numlock = numlock;
   34.84 + 			    k->extra_count++;
   34.85 + 			}
   34.86 + 		    }
   34.87 +@@ -115,6 +136,22 @@
   34.88 + 	}
   34.89 +     }
   34.90 +     fclose(f);
   34.91 ++
   34.92 ++    for (i = 0; i < MAX_NORMAL_KEYCODE; i++) {
   34.93 ++        if (k->keysym2numlock[i] != 1) {
   34.94 ++            k->keysym2numlock[i] = -keycode2numlock[k->keysym2keycode[i]];
   34.95 ++        }
   34.96 ++    }
   34.97 ++
   34.98 ++    for (i = 0; i < k->extra_count; i++) {
   34.99 ++        if (k->keysym2keycode_extra[i].numlock != 1) {
  34.100 ++            k->keysym2keycode_extra[i].numlock =
  34.101 ++                -keycode2numlock[k->keysym2keycode_extra[i].keycode];
  34.102 ++        }
  34.103 ++    }
  34.104 ++
  34.105 ++    free(keycode2numlock);
  34.106 ++
  34.107 +     return k;
  34.108 + }
  34.109 + 
  34.110 +@@ -143,3 +180,25 @@
  34.111 +     }
  34.112 +     return 0;
  34.113 + }
  34.114 ++
  34.115 ++/**
  34.116 ++ * Returns 1 if the given keysym requires numlock to be pressed, -1 if it
  34.117 ++ * requires it to be cleared, and 0 otherwise.
  34.118 ++ */
  34.119 ++static int keysym2numlock(void *kbd_layout, int keysym)
  34.120 ++{
  34.121 ++    kbd_layout_t *k = kbd_layout;
  34.122 ++    if (keysym < MAX_NORMAL_KEYCODE) {
  34.123 ++	return k->keysym2numlock[keysym];
  34.124 ++    } else {
  34.125 ++	int i;
  34.126 ++#ifdef XK_ISO_Left_Tab
  34.127 ++	if (keysym == XK_ISO_Left_Tab)
  34.128 ++	    keysym = XK_Tab;
  34.129 ++#endif
  34.130 ++	for (i = 0; i < k->extra_count; i++)
  34.131 ++	    if (k->keysym2keycode_extra[i].keysym == keysym)
  34.132 ++		return k->keysym2keycode_extra[i].numlock;
  34.133 ++    }
  34.134 ++    return 0;
  34.135 ++}
  34.136 +Index: ioemu/vnc.c
  34.137 +===================================================================
  34.138 +--- ioemu.orig/vnc.c	2006-12-08 18:18:26.000000000 +0000
  34.139 ++++ ioemu/vnc.c	2006-12-08 18:19:43.000000000 +0000
  34.140 +@@ -115,6 +115,7 @@
  34.141 + 
  34.142 +     int ctl_keys;               /* Ctrl+Alt starts calibration */
  34.143 +     int shift_keys;             /* Shift / CapsLock keys */
  34.144 ++    int numlock;
  34.145 + };
  34.146 + 
  34.147 + #define DIRTY_PIXEL_BITS 64
  34.148 +@@ -854,14 +855,40 @@
  34.149 +     }
  34.150 + }
  34.151 + 
  34.152 ++static void press_key(VncState *vs, int keycode)
  34.153 ++{
  34.154 ++    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keycode) & 0x7f);
  34.155 ++    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keycode) | 0x80);
  34.156 ++}
  34.157 ++
  34.158 + static void do_key_event(VncState *vs, int down, uint32_t sym)
  34.159 + {
  34.160 +     sym &= 0xFFFF;
  34.161 + 
  34.162 +     if (is_graphic_console()) {
  34.163 + 	int keycode;
  34.164 ++	int numlock;
  34.165 + 
  34.166 + 	keycode = keysym2scancode(vs->kbd_layout, sym);
  34.167 ++	numlock = keysym2numlock(vs->kbd_layout, sym);
  34.168 ++
  34.169 ++        /* If the numlock state needs to change then simulate an additional
  34.170 ++           keypress before sending this one.  This will happen if the user
  34.171 ++           toggles numlock away from the VNC window.
  34.172 ++        */
  34.173 ++	if (numlock == 1) {
  34.174 ++	    if (!vs->numlock) {
  34.175 ++		vs->numlock = 1;
  34.176 ++		press_key(vs, XK_Num_Lock);
  34.177 ++	    }
  34.178 ++	}
  34.179 ++	else if (numlock == -1) {
  34.180 ++	    if (vs->numlock) {
  34.181 ++		vs->numlock = 0;
  34.182 ++		press_key(vs, XK_Num_Lock);
  34.183 ++	    }
  34.184 ++        }
  34.185 ++
  34.186 + 	if (keycode & 0x80)
  34.187 + 	    kbd_put_keycode(0xe0);
  34.188 + 	if (down)
  34.189 +@@ -932,6 +959,10 @@
  34.190 + 	    vs->shift_keys ^= 2;
  34.191 + 	    break;
  34.192 + 
  34.193 ++	case XK_Num_Lock:
  34.194 ++	    vs->numlock = !vs->numlock;
  34.195 ++	    break;
  34.196 ++
  34.197 + 	case XK_1 ... XK_9:
  34.198 + 	    if ((vs->ctl_keys & 3) != 3)
  34.199 + 		break;
  34.200 +@@ -1355,6 +1386,7 @@
  34.201 +     vs->lsock = -1;
  34.202 +     vs->csock = -1;
  34.203 +     vs->depth = 4;
  34.204 ++    vs->numlock = 0;
  34.205 + 
  34.206 +     vs->ds = ds;
  34.207 + 
  34.208 +Index: ioemu/vnc_keysym.h
  34.209 +===================================================================
  34.210 +--- ioemu.orig/vnc_keysym.h	2006-12-08 18:17:01.000000000 +0000
  34.211 ++++ ioemu/vnc_keysym.h	2006-12-08 18:19:43.000000000 +0000
  34.212 +@@ -231,6 +231,19 @@
  34.213 + {"Home", 0xff50},      /* XK_Home */
  34.214 + {"End", 0xff57},       /* XK_End */
  34.215 + {"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
  34.216 ++{"KP_Home", 0xff95},
  34.217 ++{"KP_Left", 0xff96},
  34.218 ++{"KP_Up", 0xff97},
  34.219 ++{"KP_Right", 0xff98},
  34.220 ++{"KP_Down", 0xff99},
  34.221 ++{"KP_Prior", 0xff9a},
  34.222 ++{"KP_Page_Up", 0xff9a},
  34.223 ++{"KP_Next", 0xff9b},
  34.224 ++{"KP_Page_Down", 0xff9b},
  34.225 ++{"KP_End", 0xff9c},
  34.226 ++{"KP_Begin", 0xff9d},
  34.227 ++{"KP_Insert", 0xff9e},
  34.228 ++{"KP_Delete", 0xff9f},
  34.229 + {"F1", 0xffbe},        /* XK_F1 */
  34.230 + {"F2", 0xffbf},        /* XK_F2 */
  34.231 + {"F3", 0xffc0},        /* XK_F3 */
  34.232 +@@ -258,6 +271,7 @@
  34.233 + {"KP_8", 0xffb8},      /* XK_KP_8 */
  34.234 + {"KP_9", 0xffb9},      /* XK_KP_9 */
  34.235 + {"KP_Add", 0xffab},    /* XK_KP_Add */
  34.236 ++{"KP_Separator", 0xffac},/* XK_KP_Separator */
  34.237 + {"KP_Decimal", 0xffae},  /* XK_KP_Decimal */
  34.238 + {"KP_Divide", 0xffaf},   /* XK_KP_Divide */
  34.239 + {"KP_Enter", 0xff8d},    /* XK_KP_Enter */
    35.1 --- a/tools/ioemu/patches/vnc-password	Fri Dec 08 07:22:21 2006 -0800
    35.2 +++ b/tools/ioemu/patches/vnc-password	Fri Dec 08 18:31:01 2006 +0000
    35.3 @@ -15,9 +15,11 @@ The difference is follows.
    35.4  
    35.5  Signed-off-by: Masami Watanabe <masami.watanabe@jp.fujitsu.com>
    35.6  
    35.7 ---- ioemu/Makefile.target	Fri Oct 20 09:32:16 2006 +0100
    35.8 -+++ ioemu/Makefile.target	Fri Oct 20 09:50:09 2006 +0100
    35.9 -@@ -406,6 +406,7 @@ VL_OBJS+=sdl.o
   35.10 +Index: ioemu/Makefile.target
   35.11 +===================================================================
   35.12 +--- ioemu.orig/Makefile.target	2006-12-08 18:20:53.000000000 +0000
   35.13 ++++ ioemu/Makefile.target	2006-12-08 18:20:53.000000000 +0000
   35.14 +@@ -407,6 +407,7 @@
   35.15   VL_OBJS+=sdl.o
   35.16   endif
   35.17   VL_OBJS+=vnc.o
   35.18 @@ -25,29 +27,31 @@ Signed-off-by: Masami Watanabe <masami.w
   35.19   ifdef CONFIG_COCOA
   35.20   VL_OBJS+=cocoa.o
   35.21   COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
   35.22 -@@ -464,6 +465,9 @@ sdl.o: sdl.c keymaps.c sdl_keysym.h
   35.23 - 	$(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
   35.24 - 
   35.25 +@@ -467,6 +468,9 @@
   35.26   vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h
   35.27 -+	$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
   35.28 -+
   35.29 -+d3des.o: d3des.c d3des.h
   35.30   	$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
   35.31   
   35.32 ++d3des.o: d3des.c d3des.h
   35.33 ++	$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
   35.34 ++
   35.35   sdlaudio.o: sdlaudio.c
   35.36 ---- ioemu/vl.c	Fri Oct 20 09:32:16 2006 +0100
   35.37 -+++ ioemu/vl.c	Fri Oct 20 09:50:09 2006 +0100
   35.38 -@@ -170,6 +170,9 @@ time_t timeoffset = 0;
   35.39 + 	$(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
   35.40   
   35.41 +Index: ioemu/vl.c
   35.42 +===================================================================
   35.43 +--- ioemu.orig/vl.c	2006-12-08 18:20:52.000000000 +0000
   35.44 ++++ ioemu/vl.c	2006-12-08 18:20:53.000000000 +0000
   35.45 +@@ -171,6 +171,9 @@
   35.46   char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
   35.47   extern int domid;
   35.48 -+
   35.49 + 
   35.50  +char vncpasswd[64];
   35.51  +unsigned char challenge[AUTHCHALLENGESIZE];
   35.52 - 
   35.53 ++
   35.54   /***********************************************************/
   35.55   /* x86 ISA bus support */
   35.56 -@@ -5911,6 +5914,7 @@ int main(int argc, char **argv)
   35.57 + 
   35.58 +@@ -5895,6 +5898,7 @@
   35.59       vncunused = 0;
   35.60       kernel_filename = NULL;
   35.61       kernel_cmdline = "";
   35.62 @@ -55,7 +59,7 @@ Signed-off-by: Masami Watanabe <masami.w
   35.63   #ifndef CONFIG_DM
   35.64   #ifdef TARGET_PPC
   35.65       cdrom_index = 1;
   35.66 -@@ -6559,6 +6563,10 @@ int main(int argc, char **argv)
   35.67 +@@ -6543,6 +6547,10 @@
   35.68   
   35.69       init_ioports();
   35.70   
   35.71 @@ -66,9 +70,11 @@ Signed-off-by: Masami Watanabe <masami.w
   35.72       /* terminal init */
   35.73       if (nographic) {
   35.74           dumb_display_init(ds);
   35.75 ---- ioemu/vl.h	Fri Oct 20 09:32:16 2006 +0100
   35.76 -+++ ioemu/vl.h	Fri Oct 20 09:50:09 2006 +0100
   35.77 -@@ -1211,6 +1211,7 @@ void xenstore_process_event(void *opaque
   35.78 +Index: ioemu/vl.h
   35.79 +===================================================================
   35.80 +--- ioemu.orig/vl.h	2006-12-08 18:20:52.000000000 +0000
   35.81 ++++ ioemu/vl.h	2006-12-08 18:20:53.000000000 +0000
   35.82 +@@ -1214,6 +1214,7 @@
   35.83   void xenstore_process_event(void *opaque);
   35.84   void xenstore_check_new_media_present(int timeout);
   35.85   void xenstore_write_vncport(int vnc_display);
   35.86 @@ -76,7 +82,7 @@ Signed-off-by: Masami Watanabe <masami.w
   35.87   
   35.88   /* xen_platform.c */
   35.89   void pci_xen_platform_init(PCIBus *bus);
   35.90 -@@ -1222,4 +1223,7 @@ extern char domain_name[];
   35.91 +@@ -1225,4 +1226,7 @@
   35.92   
   35.93   void destroy_hvm_domain(void);
   35.94   
   35.95 @@ -84,8 +90,10 @@ Signed-off-by: Masami Watanabe <masami.w
   35.96  +#define AUTHCHALLENGESIZE 16
   35.97  +
   35.98   #endif /* VL_H */
   35.99 ---- ioemu/vnc.c	Fri Oct 20 09:32:16 2006 +0100
  35.100 -+++ ioemu/vnc.c	Fri Oct 20 09:50:09 2006 +0100
  35.101 +Index: ioemu/vnc.c
  35.102 +===================================================================
  35.103 +--- ioemu.orig/vnc.c	2006-12-08 18:20:52.000000000 +0000
  35.104 ++++ ioemu/vnc.c	2006-12-08 18:20:53.000000000 +0000
  35.105  @@ -44,6 +44,7 @@
  35.106   
  35.107   #include "vnc_keysym.h"
  35.108 @@ -94,7 +102,7 @@ Signed-off-by: Masami Watanabe <masami.w
  35.109   
  35.110   #define XK_MISCELLANY
  35.111   #define XK_LATIN1
  35.112 -@@ -137,6 +138,9 @@ static void vnc_update_client(void *opaq
  35.113 +@@ -137,6 +138,9 @@
  35.114   static void vnc_update_client(void *opaque);
  35.115   static void vnc_client_read(void *opaque);
  35.116   static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
  35.117 @@ -104,7 +112,7 @@ Signed-off-by: Masami Watanabe <masami.w
  35.118   
  35.119   #if 0
  35.120   static inline void vnc_set_bit(uint32_t *d, int k)
  35.121 -@@ -1208,23 +1212,92 @@ static int protocol_client_init(VncState
  35.122 +@@ -1210,23 +1214,92 @@
  35.123       return 0;
  35.124   }
  35.125   
  35.126 @@ -166,9 +174,8 @@ Signed-off-by: Masami Watanabe <masami.w
  35.127   
  35.128  -    vnc_write_u32(vs, 1); /* None */
  35.129  -    vnc_flush(vs);
  35.130 --
  35.131 + 
  35.132  -    vnc_read_when(vs, protocol_client_init, 1);
  35.133 -+
  35.134  +    support = 0;
  35.135  +    if (maj = 3) {
  35.136  +	if (min == 3 || min ==4) {
  35.137 @@ -202,7 +209,7 @@ Signed-off-by: Masami Watanabe <masami.w
  35.138   
  35.139       return 0;
  35.140   }
  35.141 -@@ -1342,3 +1415,32 @@ int vnc_start_viewer(int port)
  35.142 +@@ -1344,3 +1417,32 @@
  35.143   	return pid;
  35.144       }
  35.145   }
  35.146 @@ -235,9 +242,11 @@ Signed-off-by: Masami Watanabe <masami.w
  35.147  +
  35.148  +    return;
  35.149  +}
  35.150 ---- ioemu/xenstore.c	Fri Oct 20 09:32:16 2006 +0100
  35.151 -+++ ioemu/xenstore.c	Fri Oct 20 09:50:09 2006 +0100
  35.152 -@@ -213,3 +213,54 @@ void xenstore_write_vncport(int display)
  35.153 +Index: ioemu/xenstore.c
  35.154 +===================================================================
  35.155 +--- ioemu.orig/xenstore.c	2006-12-08 18:20:52.000000000 +0000
  35.156 ++++ ioemu/xenstore.c	2006-12-08 18:20:53.000000000 +0000
  35.157 +@@ -213,3 +213,54 @@
  35.158       free(portstr);
  35.159       free(buf);
  35.160   }
  35.161 @@ -292,8 +301,10 @@ Signed-off-by: Masami Watanabe <masami.w
  35.162  +
  35.163  +    return rc;
  35.164  +}
  35.165 ---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  35.166 -+++ ioemu/d3des.c	Fri Oct 20 09:50:09 2006 +0100
  35.167 +Index: ioemu/d3des.c
  35.168 +===================================================================
  35.169 +--- /dev/null	1970-01-01 00:00:00.000000000 +0000
  35.170 ++++ ioemu/d3des.c	2006-12-08 18:20:53.000000000 +0000
  35.171  @@ -0,0 +1,434 @@
  35.172  +/*
  35.173  + * This is D3DES (V5.09) by Richard Outerbridge with the double and
  35.174 @@ -729,8 +740,10 @@ Signed-off-by: Masami Watanabe <masami.w
  35.175  + *
  35.176  + * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
  35.177  + **********************************************************************/
  35.178 ---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
  35.179 -+++ ioemu/d3des.h	Fri Oct 20 09:50:09 2006 +0100
  35.180 +Index: ioemu/d3des.h
  35.181 +===================================================================
  35.182 +--- /dev/null	1970-01-01 00:00:00.000000000 +0000
  35.183 ++++ ioemu/d3des.h	2006-12-08 18:20:53.000000000 +0000
  35.184  @@ -0,0 +1,51 @@
  35.185  +/*
  35.186  + * This is D3DES (V5.09) by Richard Outerbridge with the double and
    36.1 --- a/tools/ioemu/patches/vnc-protocol-fixes	Fri Dec 08 07:22:21 2006 -0800
    36.2 +++ b/tools/ioemu/patches/vnc-protocol-fixes	Fri Dec 08 18:31:01 2006 +0000
    36.3 @@ -9,8 +9,8 @@ Signed-off-by: Steven Smith <sos22@cam.a
    36.4  
    36.5  Index: ioemu/vnc.c
    36.6  ===================================================================
    36.7 ---- ioemu.orig/vnc.c	2006-10-24 14:28:05.000000000 +0100
    36.8 -+++ ioemu/vnc.c	2006-10-24 14:30:11.000000000 +0100
    36.9 +--- ioemu.orig/vnc.c	2006-12-06 23:46:11.000000000 +0000
   36.10 ++++ ioemu/vnc.c	2006-12-06 23:46:11.000000000 +0000
   36.11  @@ -26,6 +26,7 @@
   36.12   
   36.13   #include "vl.h"
   36.14 @@ -19,7 +19,7 @@ Index: ioemu/vnc.c
   36.15   
   36.16   #define VNC_REFRESH_INTERVAL (1000 / 30)
   36.17   
   36.18 -@@ -677,8 +678,10 @@
   36.19 +@@ -679,8 +680,10 @@
   36.20   	    memmove(vs->input.buffer, vs->input.buffer + len,
   36.21   		    vs->input.offset - len);
   36.22   	    vs->input.offset -= len;
   36.23 @@ -31,7 +31,7 @@ Index: ioemu/vnc.c
   36.24       }
   36.25   }
   36.26   
   36.27 -@@ -961,8 +964,12 @@
   36.28 +@@ -963,8 +966,12 @@
   36.29   	if (len == 1)
   36.30   	    return 4;
   36.31   
   36.32 @@ -46,7 +46,7 @@ Index: ioemu/vnc.c
   36.33   
   36.34   	limit = read_u16(data, 2);
   36.35   	for (i = 0; i < limit; i++) {
   36.36 -@@ -996,8 +1003,12 @@
   36.37 +@@ -998,8 +1005,12 @@
   36.38   	if (len == 1)
   36.39   	    return 8;
   36.40   
    37.1 --- a/tools/ioemu/patches/vnc-start-vncviewer	Fri Dec 08 07:22:21 2006 -0800
    37.2 +++ b/tools/ioemu/patches/vnc-start-vncviewer	Fri Dec 08 18:31:01 2006 +0000
    37.3 @@ -1,8 +1,8 @@
    37.4  Index: ioemu/vnc.c
    37.5  ===================================================================
    37.6 ---- ioemu.orig/vnc.c	2006-10-24 14:33:46.000000000 +0100
    37.7 -+++ ioemu/vnc.c	2006-10-24 14:33:46.000000000 +0100
    37.8 -@@ -1187,3 +1187,25 @@
    37.9 +--- ioemu.orig/vnc.c	2006-12-08 02:02:36.000000000 +0000
   37.10 ++++ ioemu/vnc.c	2006-12-08 02:02:36.000000000 +0000
   37.11 +@@ -1189,3 +1189,25 @@
   37.12   
   37.13       vnc_dpy_resize(vs->ds, 640, 400);
   37.14   }
   37.15 @@ -30,8 +30,8 @@ Index: ioemu/vnc.c
   37.16  +}
   37.17  Index: ioemu/vl.c
   37.18  ===================================================================
   37.19 ---- ioemu.orig/vl.c	2006-10-24 14:33:46.000000000 +0100
   37.20 -+++ ioemu/vl.c	2006-10-24 14:33:46.000000000 +0100
   37.21 +--- ioemu.orig/vl.c	2006-12-08 02:02:36.000000000 +0000
   37.22 ++++ ioemu/vl.c	2006-12-08 02:02:36.000000000 +0000
   37.23  @@ -120,6 +120,7 @@
   37.24   int bios_size;
   37.25   static DisplayState display_state;
   37.26 @@ -64,7 +64,7 @@ Index: ioemu/vl.c
   37.27       
   37.28       /* temporary options */
   37.29       { "usb", 0, QEMU_OPTION_usb },
   37.30 -@@ -5868,6 +5872,7 @@
   37.31 +@@ -5852,6 +5856,7 @@
   37.32   #endif
   37.33       snapshot = 0;
   37.34       nographic = 0;
   37.35 @@ -72,7 +72,7 @@ Index: ioemu/vl.c
   37.36       kernel_filename = NULL;
   37.37       kernel_cmdline = "";
   37.38   #ifdef TARGET_PPC
   37.39 -@@ -6262,6 +6267,9 @@
   37.40 +@@ -6246,6 +6251,9 @@
   37.41               case QEMU_OPTION_acpi:
   37.42                   acpi_enabled = 1;
   37.43                   break;
   37.44 @@ -82,7 +82,7 @@ Index: ioemu/vl.c
   37.45               }
   37.46           }
   37.47       }
   37.48 -@@ -6476,6 +6484,8 @@
   37.49 +@@ -6461,6 +6469,8 @@
   37.50           dumb_display_init(ds);
   37.51       } else if (vnc_display != -1) {
   37.52   	vnc_display_init(ds, vnc_display);
   37.53 @@ -93,8 +93,8 @@ Index: ioemu/vl.c
   37.54           sdl_display_init(ds, full_screen);
   37.55  Index: ioemu/vl.h
   37.56  ===================================================================
   37.57 ---- ioemu.orig/vl.h	2006-10-24 14:33:46.000000000 +0100
   37.58 -+++ ioemu/vl.h	2006-10-24 14:33:46.000000000 +0100
   37.59 +--- ioemu.orig/vl.h	2006-12-08 02:02:36.000000000 +0000
   37.60 ++++ ioemu/vl.h	2006-12-08 02:02:36.000000000 +0000
   37.61  @@ -786,6 +786,7 @@
   37.62   
   37.63   /* vnc.c */
    38.1 --- a/tools/ioemu/patches/vnc-title-domain-name	Fri Dec 08 07:22:21 2006 -0800
    38.2 +++ b/tools/ioemu/patches/vnc-title-domain-name	Fri Dec 08 18:31:01 2006 +0000
    38.3 @@ -1,8 +1,8 @@
    38.4  Index: ioemu/vnc.c
    38.5  ===================================================================
    38.6 ---- ioemu.orig/vnc.c	2006-10-24 14:33:46.000000000 +0100
    38.7 -+++ ioemu/vnc.c	2006-10-24 14:33:46.000000000 +0100
    38.8 -@@ -1024,6 +1024,7 @@
    38.9 +--- ioemu.orig/vnc.c	2006-12-06 23:46:11.000000000 +0000
   38.10 ++++ ioemu/vnc.c	2006-12-06 23:46:11.000000000 +0000
   38.11 +@@ -1026,6 +1026,7 @@
   38.12   
   38.13   static int protocol_client_init(VncState *vs, char *data, size_t len)
   38.14   {
   38.15 @@ -10,7 +10,7 @@ Index: ioemu/vnc.c
   38.16       char pad[3] = { 0, 0, 0 };
   38.17   
   38.18       vga_hw_update();
   38.19 -@@ -1071,8 +1072,10 @@
   38.20 +@@ -1073,8 +1074,10 @@
   38.21   	
   38.22       vnc_write(vs, pad, 3);           /* padding */
   38.23   
    39.1 --- a/tools/ioemu/patches/xen-build	Fri Dec 08 07:22:21 2006 -0800
    39.2 +++ b/tools/ioemu/patches/xen-build	Fri Dec 08 18:31:01 2006 +0000
    39.3 @@ -1,7 +1,7 @@
    39.4  Index: ioemu/Makefile
    39.5  ===================================================================
    39.6 ---- ioemu.orig/Makefile	2006-10-24 14:37:25.000000000 +0100
    39.7 -+++ ioemu/Makefile	2006-10-24 14:37:28.000000000 +0100
    39.8 +--- ioemu.orig/Makefile	2006-12-08 01:26:04.000000000 +0000
    39.9 ++++ ioemu/Makefile	2006-12-08 01:26:06.000000000 +0000
   39.10  @@ -1,11 +1,14 @@
   39.11   # Makefile for QEMU.
   39.12   
   39.13 @@ -85,8 +85,8 @@ Index: ioemu/Makefile
   39.14   info: qemu-doc.info qemu-tech.info
   39.15  Index: ioemu/Makefile.target
   39.16  ===================================================================
   39.17 ---- ioemu.orig/Makefile.target	2006-10-24 14:37:25.000000000 +0100
   39.18 -+++ ioemu/Makefile.target	2006-10-24 14:40:25.000000000 +0100
   39.19 +--- ioemu.orig/Makefile.target	2006-12-08 01:26:04.000000000 +0000
   39.20 ++++ ioemu/Makefile.target	2006-12-08 01:41:05.000000000 +0000
   39.21  @@ -1,5 +1,8 @@
   39.22   include config.mak
   39.23   
   39.24 @@ -120,9 +120,13 @@ Index: ioemu/Makefile.target
   39.25   #CFLAGS+=-Werror
   39.26   LDFLAGS=-g
   39.27   LIBS=
   39.28 -@@ -167,6 +177,9 @@
   39.29 +@@ -165,8 +175,12 @@
   39.30 + 
   39.31 + #########################################################
   39.32   
   39.33 - DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
   39.34 +-DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
   39.35 ++DEFINES+=-D_GNU_SOURCE
   39.36 ++#-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
   39.37   LIBS+=-lm
   39.38  +LIBS+=-L../../libxc -lxenctrl -lxenguest
   39.39  +LIBS+=-L../../xenstore -lxenstore
   39.40 @@ -130,7 +134,7 @@ Index: ioemu/Makefile.target
   39.41   ifndef CONFIG_USER_ONLY
   39.42   LIBS+=-lz
   39.43   endif
   39.44 -@@ -281,7 +294,7 @@
   39.45 +@@ -281,7 +295,7 @@
   39.46   all: $(PROGS)
   39.47   
   39.48   $(QEMU_USER): $(OBJS)
   39.49 @@ -139,7 +143,7 @@ Index: ioemu/Makefile.target
   39.50   ifeq ($(ARCH),alpha)
   39.51   # Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
   39.52   # the address space (31 bit so sign extending doesn't matter)
   39.53 -@@ -528,10 +541,16 @@
   39.54 +@@ -528,10 +542,16 @@
   39.55   clean:
   39.56   	rm -f *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o
   39.57   
   39.58 @@ -159,8 +163,8 @@ Index: ioemu/Makefile.target
   39.59   include .depend
   39.60  Index: ioemu/configure
   39.61  ===================================================================
   39.62 ---- ioemu.orig/configure	2006-10-24 14:37:25.000000000 +0100
   39.63 -+++ ioemu/configure	2006-10-24 14:40:20.000000000 +0100
   39.64 +--- ioemu.orig/configure	2006-12-08 01:26:04.000000000 +0000
   39.65 ++++ ioemu/configure	2006-12-08 01:40:58.000000000 +0000
   39.66  @@ -18,8 +18,8 @@
   39.67   
   39.68   # default parameters
    40.1 --- a/tools/ioemu/patches/xen-mm	Fri Dec 08 07:22:21 2006 -0800
    40.2 +++ b/tools/ioemu/patches/xen-mm	Fri Dec 08 18:31:01 2006 +0000
    40.3 @@ -1,7 +1,7 @@
    40.4  Index: ioemu/hw/pc.c
    40.5  ===================================================================
    40.6 ---- ioemu.orig/hw/pc.c	2006-08-17 19:36:00.588166019 +0100
    40.7 -+++ ioemu/hw/pc.c	2006-08-17 19:37:36.704485734 +0100
    40.8 +--- ioemu.orig/hw/pc.c	2006-12-08 02:00:38.000000000 +0000
    40.9 ++++ ioemu/hw/pc.c	2006-12-08 02:02:07.000000000 +0000
   40.10  @@ -646,7 +646,9 @@
   40.11       }
   40.12   
   40.13 @@ -25,8 +25,8 @@ Index: ioemu/hw/pc.c
   40.14       isa_bios_size = bios_size;
   40.15  Index: ioemu/vl.c
   40.16  ===================================================================
   40.17 ---- ioemu.orig/vl.c	2006-08-17 19:36:00.667157242 +0100
   40.18 -+++ ioemu/vl.c	2006-08-17 19:47:08.538087284 +0100
   40.19 +--- ioemu.orig/vl.c	2006-12-08 02:00:39.000000000 +0000
   40.20 ++++ ioemu/vl.c	2006-12-08 02:02:28.000000000 +0000
   40.21  @@ -158,6 +158,8 @@
   40.22   int acpi_enabled = 1;
   40.23   int fd_bootchk = 1;
   40.24 @@ -60,7 +60,7 @@ Index: ioemu/vl.c
   40.25                   break;
   40.26               case QEMU_OPTION_l:
   40.27                   {
   40.28 -@@ -6133,12 +6140,67 @@
   40.29 +@@ -6133,12 +6140,61 @@
   40.30       /* init the memory */
   40.31       phys_ram_size = ram_size + vga_ram_size + bios_size;
   40.32   
   40.33 @@ -85,14 +85,8 @@ Index: ioemu/vl.c
   40.34  +        exit(-1);
   40.35  +    }
   40.36  +
   40.37 -+    if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
   40.38 -+        fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
   40.39 -+        exit(-1);
   40.40 -+    }
   40.41 -+
   40.42 -+    if (ram_size > HVM_BELOW_4G_RAM_END)
   40.43 -+        for (i = 0; i < nr_pages - (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT); i++)
   40.44 -+            page_array[tmp_nr_pages - 1 - i] = page_array[nr_pages - 1 - i];
   40.45 ++    for ( i = 0; i < tmp_nr_pages; i++)
   40.46 ++        page_array[i] = i;
   40.47  +
   40.48  +    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
   40.49  +                                         PROT_READ|PROT_WRITE, page_array,
   40.50 @@ -130,8 +124,8 @@ Index: ioemu/vl.c
   40.51       if (cdrom_index >= 0) {
   40.52  Index: ioemu/hw/piix_pci.c
   40.53  ===================================================================
   40.54 ---- ioemu.orig/hw/piix_pci.c	2006-08-17 19:37:36.189542951 +0100
   40.55 -+++ ioemu/hw/piix_pci.c	2006-08-17 19:38:05.806252180 +0100
   40.56 +--- ioemu.orig/hw/piix_pci.c	2006-12-08 02:00:36.000000000 +0000
   40.57 ++++ ioemu/hw/piix_pci.c	2006-12-08 02:02:06.000000000 +0000
   40.58  @@ -399,7 +399,7 @@
   40.59       uint8_t elcr[2];
   40.60   
   40.61 @@ -143,8 +137,8 @@ Index: ioemu/hw/piix_pci.c
   40.62       elcr[0] = 0x00;
   40.63  Index: ioemu/vl.h
   40.64  ===================================================================
   40.65 ---- ioemu.orig/vl.h	2006-08-17 19:37:36.529505177 +0100
   40.66 -+++ ioemu/vl.h	2006-08-17 19:47:32.680418959 +0100
   40.67 +--- ioemu.orig/vl.h	2006-12-08 02:00:39.000000000 +0000
   40.68 ++++ ioemu/vl.h	2006-12-08 02:02:07.000000000 +0000
   40.69  @@ -39,6 +39,7 @@
   40.70   #include <sys/stat.h>
   40.71   #include "xenctrl.h"
    41.1 --- a/tools/ioemu/patches/xen-platform-device	Fri Dec 08 07:22:21 2006 -0800
    41.2 +++ b/tools/ioemu/patches/xen-platform-device	Fri Dec 08 18:31:01 2006 +0000
    41.3 @@ -3,9 +3,9 @@ will come later.
    41.4  
    41.5  Index: ioemu/Makefile.target
    41.6  ===================================================================
    41.7 ---- ioemu.orig/Makefile.target	2006-10-24 14:41:01.000000000 +0100
    41.8 -+++ ioemu/Makefile.target	2006-10-24 14:41:01.000000000 +0100
    41.9 -@@ -359,6 +359,7 @@
   41.10 +--- ioemu.orig/Makefile.target	2006-12-08 01:41:14.000000000 +0000
   41.11 ++++ ioemu/Makefile.target	2006-12-08 01:41:15.000000000 +0000
   41.12 +@@ -360,6 +360,7 @@
   41.13   VL_OBJS+= usb-uhci.o
   41.14   VL_OBJS+= piix4acpi.o
   41.15   VL_OBJS+= xenstore.o
   41.16 @@ -15,8 +15,8 @@ Index: ioemu/Makefile.target
   41.17   ifeq ($(TARGET_BASE_ARCH), ppc)
   41.18  Index: ioemu/hw/pc.c
   41.19  ===================================================================
   41.20 ---- ioemu.orig/hw/pc.c	2006-10-24 14:41:00.000000000 +0100
   41.21 -+++ ioemu/hw/pc.c	2006-10-24 14:41:01.000000000 +0100
   41.22 +--- ioemu.orig/hw/pc.c	2006-12-08 01:41:13.000000000 +0000
   41.23 ++++ ioemu/hw/pc.c	2006-12-08 01:41:15.000000000 +0000
   41.24  @@ -823,6 +823,9 @@
   41.25       }
   41.26   #endif /* !CONFIG_DM */
   41.27 @@ -30,7 +30,7 @@ Index: ioemu/hw/pc.c
   41.28  Index: ioemu/hw/xen_platform.c
   41.29  ===================================================================
   41.30  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
   41.31 -+++ ioemu/hw/xen_platform.c	2006-10-24 14:41:04.000000000 +0100
   41.32 ++++ ioemu/hw/xen_platform.c	2006-12-08 01:41:15.000000000 +0000
   41.33  @@ -0,0 +1,144 @@
   41.34  +/*
   41.35  + * XEN platform fake pci device, formerly known as the event channel device
   41.36 @@ -178,8 +178,8 @@ Index: ioemu/hw/xen_platform.c
   41.37  +}
   41.38  Index: ioemu/vl.h
   41.39  ===================================================================
   41.40 ---- ioemu.orig/vl.h	2006-10-24 14:41:01.000000000 +0100
   41.41 -+++ ioemu/vl.h	2006-10-24 14:41:01.000000000 +0100
   41.42 +--- ioemu.orig/vl.h	2006-12-08 01:41:14.000000000 +0000
   41.43 ++++ ioemu/vl.h	2006-12-08 01:41:15.000000000 +0000
   41.44  @@ -1212,6 +1212,9 @@
   41.45   void xenstore_check_new_media_present(int timeout);
   41.46   void xenstore_write_vncport(int vnc_display);
    42.1 --- a/tools/ioemu/patches/xen-support-buffered-ioreqs	Fri Dec 08 07:22:21 2006 -0800
    42.2 +++ b/tools/ioemu/patches/xen-support-buffered-ioreqs	Fri Dec 08 18:31:01 2006 +0000
    42.3 @@ -1,8 +1,8 @@
    42.4  Index: ioemu/vl.c
    42.5  ===================================================================
    42.6 ---- ioemu.orig/vl.c	2006-10-24 14:33:47.000000000 +0100
    42.7 -+++ ioemu/vl.c	2006-10-24 14:33:47.000000000 +0100
    42.8 -@@ -5854,6 +5854,7 @@
    42.9 +--- ioemu.orig/vl.c	2006-12-08 02:02:37.000000000 +0000
   42.10 ++++ ioemu/vl.c	2006-12-08 02:02:37.000000000 +0000
   42.11 +@@ -5838,6 +5838,7 @@
   42.12       unsigned long nr_pages, tmp_nr_pages, shared_page_nr;
   42.13       xen_pfn_t *page_array;
   42.14       extern void *shared_page;
   42.15 @@ -10,11 +10,10 @@ Index: ioemu/vl.c
   42.16   
   42.17       char qemu_dm_logfilename[64];
   42.18   
   42.19 -@@ -6440,6 +6441,18 @@
   42.20 +@@ -6418,6 +6419,17 @@
   42.21       fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
   42.22               shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
   42.23   
   42.24 -+    /* not yet add for IA64 */
   42.25  +    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   42.26  +                                            PROT_READ|PROT_WRITE,
   42.27  +                                            page_array[shared_page_nr - 2]);
   42.28 @@ -31,8 +30,8 @@ Index: ioemu/vl.c
   42.29   #elif defined(__ia64__)
   42.30  Index: ioemu/target-i386-dm/helper2.c
   42.31  ===================================================================
   42.32 ---- ioemu.orig/target-i386-dm/helper2.c	2006-10-24 14:33:45.000000000 +0100
   42.33 -+++ ioemu/target-i386-dm/helper2.c	2006-10-24 14:33:47.000000000 +0100
   42.34 +--- ioemu.orig/target-i386-dm/helper2.c	2006-12-08 02:02:35.000000000 +0000
   42.35 ++++ ioemu/target-i386-dm/helper2.c	2006-12-08 02:02:37.000000000 +0000
   42.36  @@ -76,6 +76,10 @@
   42.37   
   42.38   shared_iopage_t *shared_page = NULL;
   42.39 @@ -44,14 +43,14 @@ Index: ioemu/target-i386-dm/helper2.c
   42.40   /* the evtchn fd for polling */
   42.41   int xce_handle = -1;
   42.42   
   42.43 -@@ -419,36 +423,68 @@
   42.44 -     req->u.data = tmp1;
   42.45 +@@ -435,39 +439,71 @@
   42.46 +     req->data = tmp1;
   42.47   }
   42.48   
   42.49  +void __handle_ioreq(CPUState *env, ioreq_t *req)
   42.50  +{
   42.51 -+    if (!req->pdata_valid && req->dir == IOREQ_WRITE && req->size != 4)
   42.52 -+	req->u.data &= (1UL << (8 * req->size)) - 1;
   42.53 ++    if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
   42.54 ++	req->data &= (1UL << (8 * req->size)) - 1;
   42.55  +
   42.56  +    switch (req->type) {
   42.57  +    case IOREQ_TYPE_PIO:
   42.58 @@ -63,6 +62,9 @@ Index: ioemu/target-i386-dm/helper2.c
   42.59  +    case IOREQ_TYPE_AND:
   42.60  +        cpu_ioreq_and(env, req);
   42.61  +        break;
   42.62 ++    case IOREQ_TYPE_ADD:
   42.63 ++        cpu_ioreq_add(env, req);
   42.64 ++        break;
   42.65  +    case IOREQ_TYPE_OR:
   42.66  +        cpu_ioreq_or(env, req);
   42.67  +        break;
   42.68 @@ -109,9 +111,9 @@ Index: ioemu/target-i386-dm/helper2.c
   42.69   
   42.70  +    handle_buffered_io(env);
   42.71       if (req) {
   42.72 --        if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
   42.73 +-        if ((!req->data_is_ptr) && (req->dir == IOREQ_WRITE)) {
   42.74  -            if (req->size != 4)
   42.75 --                req->u.data &= (1UL << (8 * req->size))-1;
   42.76 +-                req->data &= (1UL << (8 * req->size))-1;
   42.77  -        }
   42.78  -
   42.79  -        switch (req->type) {
   42.80 @@ -124,6 +126,9 @@ Index: ioemu/target-i386-dm/helper2.c
   42.81  -        case IOREQ_TYPE_AND:
   42.82  -            cpu_ioreq_and(env, req);
   42.83  -            break;
   42.84 +-        case IOREQ_TYPE_ADD:
   42.85 +-            cpu_ioreq_add(env, req);
   42.86 +-            break;
   42.87  -        case IOREQ_TYPE_OR:
   42.88  -            cpu_ioreq_or(env, req);
   42.89  -            break;
   42.90 @@ -135,9 +140,9 @@ Index: ioemu/target-i386-dm/helper2.c
   42.91  -        }
   42.92  +        __handle_ioreq(env, req);
   42.93   
   42.94 -         /* No state change if state = STATE_IORESP_HOOK */
   42.95 -         if (req->state == STATE_IOREQ_INPROCESS) {
   42.96 -@@ -466,6 +502,10 @@
   42.97 +         if (req->state != STATE_IOREQ_INPROCESS) {
   42.98 +             fprintf(logfile, "Badness in I/O request ... not in service?!: "
   42.99 +@@ -492,6 +528,10 @@
  42.100       CPUState *env = cpu_single_env;
  42.101       int evtchn_fd = xc_evtchn_fd(xce_handle);
  42.102   
  42.103 @@ -147,4 +152,4 @@ Index: ioemu/target-i386-dm/helper2.c
  42.104  +
  42.105       qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
  42.106   
  42.107 -     env->send_event = 0;
  42.108 +     while (1) {
    43.1 --- a/tools/ioemu/patches/xenstore-block-device-config	Fri Dec 08 07:22:21 2006 -0800
    43.2 +++ b/tools/ioemu/patches/xenstore-block-device-config	Fri Dec 08 18:31:01 2006 +0000
    43.3 @@ -1,8 +1,8 @@
    43.4  Index: ioemu/Makefile.target
    43.5  ===================================================================
    43.6 ---- ioemu.orig/Makefile.target	2006-10-24 14:31:36.000000000 +0100
    43.7 -+++ ioemu/Makefile.target	2006-10-24 14:33:28.000000000 +0100
    43.8 -@@ -358,6 +358,7 @@
    43.9 +--- ioemu.orig/Makefile.target	2006-12-08 02:02:36.000000000 +0000
   43.10 ++++ ioemu/Makefile.target	2006-12-08 02:02:37.000000000 +0000
   43.11 +@@ -359,6 +359,7 @@
   43.12   VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
   43.13   VL_OBJS+= usb-uhci.o
   43.14   VL_OBJS+= piix4acpi.o
   43.15 @@ -13,7 +13,7 @@ Index: ioemu/Makefile.target
   43.16  Index: ioemu/xenstore.c
   43.17  ===================================================================
   43.18  --- /dev/null	1970-01-01 00:00:00.000000000 +0000
   43.19 -+++ ioemu/xenstore.c	2006-10-24 14:33:28.000000000 +0100
   43.20 ++++ ioemu/xenstore.c	2006-12-08 02:02:37.000000000 +0000
   43.21  @@ -0,0 +1,187 @@
   43.22  +/*
   43.23  + * This file is subject to the terms and conditions of the GNU General
   43.24 @@ -117,7 +117,7 @@ Index: ioemu/xenstore.c
   43.25  +	if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
   43.26  +	    continue;
   43.27  +	hd_index = dev[2] - 'a';
   43.28 -+	if (hd_index > MAX_DISKS)
   43.29 ++	if (hd_index >= MAX_DISKS)
   43.30  +	    continue;
   43.31  +	/* read the type of the device */
   43.32  +	if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
   43.33 @@ -204,8 +204,8 @@ Index: ioemu/xenstore.c
   43.34  +}
   43.35  Index: ioemu/vl.c
   43.36  ===================================================================
   43.37 ---- ioemu.orig/vl.c	2006-10-24 14:33:24.000000000 +0100
   43.38 -+++ ioemu/vl.c	2006-10-24 14:33:28.000000000 +0100
   43.39 +--- ioemu.orig/vl.c	2006-12-08 02:02:37.000000000 +0000
   43.40 ++++ ioemu/vl.c	2006-12-08 02:02:37.000000000 +0000
   43.41  @@ -5256,9 +5256,11 @@
   43.42              "Standard options:\n"
   43.43              "-M machine      select emulated machine (-M ? for list)\n"
   43.44 @@ -246,7 +246,7 @@ Index: ioemu/vl.c
   43.45       { "boot", HAS_ARG, QEMU_OPTION_boot },
   43.46       { "snapshot", 0, QEMU_OPTION_snapshot },
   43.47   #ifdef TARGET_I386
   43.48 -@@ -5817,10 +5823,16 @@
   43.49 +@@ -5801,10 +5807,16 @@
   43.50   #ifdef CONFIG_GDBSTUB
   43.51       int use_gdbstub, gdbstub_port;
   43.52   #endif
   43.53 @@ -265,7 +265,7 @@ Index: ioemu/vl.c
   43.54       const char *kernel_filename, *kernel_cmdline;
   43.55       DisplayState *ds = &display_state;
   43.56       int cyls, heads, secs, translation;
   43.57 -@@ -5881,8 +5893,10 @@
   43.58 +@@ -5865,8 +5877,10 @@
   43.59       initrd_filename = NULL;
   43.60       for(i = 0; i < MAX_FD; i++)
   43.61           fd_filename[i] = NULL;
   43.62 @@ -276,7 +276,7 @@ Index: ioemu/vl.c
   43.63       ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
   43.64       vga_ram_size = VGA_RAM_SIZE;
   43.65       bios_size = BIOS_SIZE;
   43.66 -@@ -5896,11 +5910,13 @@
   43.67 +@@ -5880,11 +5894,13 @@
   43.68       vncunused = 0;
   43.69       kernel_filename = NULL;
   43.70       kernel_cmdline = "";
   43.71 @@ -290,7 +290,7 @@ Index: ioemu/vl.c
   43.72       cyls = heads = secs = 0;
   43.73       translation = BIOS_ATA_TRANSLATION_AUTO;
   43.74       pstrcpy(monitor_device, sizeof(monitor_device), "vc");
   43.75 -@@ -5935,7 +5951,11 @@
   43.76 +@@ -5919,7 +5935,11 @@
   43.77               break;
   43.78           r = argv[optind];
   43.79           if (r[0] != '-') {
   43.80 @@ -302,7 +302,7 @@ Index: ioemu/vl.c
   43.81           } else {
   43.82               const QEMUOption *popt;
   43.83   
   43.84 -@@ -5979,6 +5999,7 @@
   43.85 +@@ -5963,6 +5983,7 @@
   43.86               case QEMU_OPTION_initrd:
   43.87                   initrd_filename = optarg;
   43.88                   break;
   43.89 @@ -310,7 +310,7 @@ Index: ioemu/vl.c
   43.90               case QEMU_OPTION_hda:
   43.91               case QEMU_OPTION_hdb:
   43.92               case QEMU_OPTION_hdc:
   43.93 -@@ -5991,6 +6012,7 @@
   43.94 +@@ -5975,6 +5996,7 @@
   43.95                           cdrom_index = -1;
   43.96                   }
   43.97                   break;
   43.98 @@ -318,7 +318,7 @@ Index: ioemu/vl.c
   43.99               case QEMU_OPTION_snapshot:
  43.100                   snapshot = 1;
  43.101                   break;
  43.102 -@@ -6043,11 +6065,13 @@
  43.103 +@@ -6027,11 +6049,13 @@
  43.104               case QEMU_OPTION_append:
  43.105                   kernel_cmdline = optarg;
  43.106                   break;
  43.107 @@ -332,7 +332,7 @@ Index: ioemu/vl.c
  43.108               case QEMU_OPTION_boot:
  43.109                   boot_device = optarg[0];
  43.110                   if (boot_device != 'a' && 
  43.111 -@@ -6305,12 +6329,18 @@
  43.112 +@@ -6289,12 +6313,18 @@
  43.113           }
  43.114       }
  43.115   
  43.116 @@ -351,7 +351,7 @@ Index: ioemu/vl.c
  43.117       if (!linux_boot && 
  43.118           hd_filename[0] == '\0' && 
  43.119           (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
  43.120 -@@ -6324,6 +6354,7 @@
  43.121 +@@ -6308,6 +6338,7 @@
  43.122           else
  43.123               boot_device = 'd';
  43.124       }
  43.125 @@ -359,7 +359,7 @@ Index: ioemu/vl.c
  43.126   
  43.127       setvbuf(stdout, NULL, _IOLBF, 0);
  43.128       
  43.129 -@@ -6456,6 +6487,7 @@
  43.130 +@@ -6441,6 +6472,7 @@
  43.131   
  43.132   #endif /* !CONFIG_DM */
  43.133   
  43.134 @@ -367,7 +367,7 @@ Index: ioemu/vl.c
  43.135       /* we always create the cdrom drive, even if no disk is there */
  43.136       bdrv_init();
  43.137       if (cdrom_index >= 0) {
  43.138 -@@ -6482,6 +6514,7 @@
  43.139 +@@ -6467,6 +6499,7 @@
  43.140               }
  43.141           }
  43.142       }
  43.143 @@ -375,7 +375,7 @@ Index: ioemu/vl.c
  43.144   
  43.145       /* we always create at least one floppy disk */
  43.146       fd_table[0] = bdrv_new("fda");
  43.147 -@@ -6560,6 +6593,8 @@
  43.148 +@@ -6545,6 +6578,8 @@
  43.149           }
  43.150       }
  43.151   
  43.152 @@ -386,8 +386,8 @@ Index: ioemu/vl.c
  43.153                     kernel_filename, kernel_cmdline, initrd_filename,
  43.154  Index: ioemu/monitor.c
  43.155  ===================================================================
  43.156 ---- ioemu.orig/monitor.c	2006-10-24 14:31:36.000000000 +0100
  43.157 -+++ ioemu/monitor.c	2006-10-24 14:33:28.000000000 +0100
  43.158 +--- ioemu.orig/monitor.c	2006-12-08 02:02:35.000000000 +0000
  43.159 ++++ ioemu/monitor.c	2006-12-08 02:02:37.000000000 +0000
  43.160  @@ -24,6 +24,7 @@
  43.161   #include "vl.h"
  43.162   #include "disas.h"
  43.163 @@ -416,8 +416,8 @@ Index: ioemu/monitor.c
  43.164       int i;
  43.165  Index: ioemu/block.c
  43.166  ===================================================================
  43.167 ---- ioemu.orig/block.c	2006-10-24 14:31:36.000000000 +0100
  43.168 -+++ ioemu/block.c	2006-10-24 14:33:28.000000000 +0100
  43.169 +--- ioemu.orig/block.c	2006-12-08 02:02:06.000000000 +0000
  43.170 ++++ ioemu/block.c	2006-12-08 02:02:37.000000000 +0000
  43.171  @@ -758,6 +758,7 @@
  43.172   static void raw_close(BlockDriverState *bs)
  43.173   {
  43.174 @@ -428,8 +428,8 @@ Index: ioemu/block.c
  43.175   
  43.176  Index: ioemu/vl.h
  43.177  ===================================================================
  43.178 ---- ioemu.orig/vl.h	2006-10-24 14:33:24.000000000 +0100
  43.179 -+++ ioemu/vl.h	2006-10-24 14:33:28.000000000 +0100
  43.180 +--- ioemu.orig/vl.h	2006-12-08 02:02:37.000000000 +0000
  43.181 ++++ ioemu/vl.h	2006-12-08 02:02:37.000000000 +0000
  43.182  @@ -1191,6 +1191,8 @@
  43.183   void term_print_help(void);
  43.184   void monitor_readline(const char *prompt, int is_password,
  43.185 @@ -455,8 +455,8 @@ Index: ioemu/vl.h
  43.186   extern char domain_name[];
  43.187  Index: ioemu/hw/ide.c
  43.188  ===================================================================
  43.189 ---- ioemu.orig/hw/ide.c	2006-10-24 14:31:36.000000000 +0100
  43.190 -+++ ioemu/hw/ide.c	2006-10-24 14:33:28.000000000 +0100
  43.191 +--- ioemu.orig/hw/ide.c	2006-12-08 02:02:35.000000000 +0000
  43.192 ++++ ioemu/hw/ide.c	2006-12-08 02:02:37.000000000 +0000
  43.193  @@ -1158,6 +1158,7 @@
  43.194           } else {
  43.195               ide_atapi_cmd_error(s, SENSE_NOT_READY, 
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/tools/ioemu/patches/xenstore-device-info-functions	Fri Dec 08 18:31:01 2006 +0000
    44.3 @@ -0,0 +1,190 @@
    44.4 +# HG changeset patch
    44.5 +# User kaf24@localhost.localdomain
    44.6 +# Node ID bbcac2aea0e8196cd75a3bf6dbe57bebf8c1e5b2
    44.7 +# Parent  dc973fe5633386547ce5bc8fd4cf5f2bb5b55174
    44.8 +[QEMU] Helper functions to interface with the xenstore and read device information from it.
    44.9 +
   44.10 + - detect what types of devices a domain has or whether a domain has a
   44.11 +   device of a certain type
   44.12 + - read the content of a variable related to a device, i.e.,
   44.13 +   hotplug-status
   44.14 + - subscribe to changes of the hotplug status of a device for not
   44.15 +   having to poll the status
   44.16 +
   44.17 +Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
   44.18 +
   44.19 +Index: ioemu/xenstore.c
   44.20 +===================================================================
   44.21 +--- ioemu.orig/xenstore.c	2006-12-08 18:20:53.000000000 +0000
   44.22 ++++ ioemu/xenstore.c	2006-12-08 18:20:53.000000000 +0000
   44.23 +@@ -264,3 +264,140 @@
   44.24 + 
   44.25 +     return rc;
   44.26 + }
   44.27 ++
   44.28 ++
   44.29 ++/*
   44.30 ++ * get all device instances of a certain type
   44.31 ++ */
   44.32 ++char **xenstore_domain_get_devices(struct xs_handle *handle,
   44.33 ++                                   const char *devtype, unsigned int *num)
   44.34 ++{
   44.35 ++    char *path;
   44.36 ++    char *buf = NULL;
   44.37 ++    char **e  = NULL;
   44.38 ++
   44.39 ++    path = xs_get_domain_path(handle, domid);
   44.40 ++    if (path == NULL)
   44.41 ++        goto out;
   44.42 ++
   44.43 ++    if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
   44.44 ++	goto out;
   44.45 ++
   44.46 ++    e = xs_directory(handle, XBT_NULL, buf, num);
   44.47 ++
   44.48 ++ out:
   44.49 ++    free(path);
   44.50 ++    free(buf);
   44.51 ++    return e;
   44.52 ++}
   44.53 ++
   44.54 ++/*
   44.55 ++ * Check whether a domain has devices of the given type
   44.56 ++ */
   44.57 ++int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype)
   44.58 ++{
   44.59 ++    int rc = 0;
   44.60 ++    unsigned int num;
   44.61 ++    char **e = xenstore_domain_get_devices(handle, devtype, &num);
   44.62 ++    if (e)
   44.63 ++        rc = 1;
   44.64 ++    free(e);
   44.65 ++    return rc;
   44.66 ++}
   44.67 ++
   44.68 ++/*
   44.69 ++ * Function that creates a path to a variable of an instance of a
   44.70 ++ * certain device
   44.71 ++ */
   44.72 ++static char *get_device_variable_path(const char *devtype, const char *inst,
   44.73 ++                                      const char *var)
   44.74 ++{
   44.75 ++    char *buf = NULL;
   44.76 ++    if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s",
   44.77 ++                  devtype,
   44.78 ++                  domid,
   44.79 ++                  inst,
   44.80 ++                  var) == -1) {
   44.81 ++        free(buf);
   44.82 ++        buf = NULL;
   44.83 ++    }
   44.84 ++    return buf;
   44.85 ++}
   44.86 ++
   44.87 ++char *xenstore_backend_read_variable(struct xs_handle *handle,
   44.88 ++                                     const char *devtype, const char *inst,
   44.89 ++                                     const char *var)
   44.90 ++{
   44.91 ++    char *value = NULL;
   44.92 ++    char *buf = NULL;
   44.93 ++    unsigned int len;
   44.94 ++
   44.95 ++    buf = get_device_variable_path(devtype, inst, var);
   44.96 ++    if (NULL == buf)
   44.97 ++	goto out;
   44.98 ++
   44.99 ++    value = xs_read(handle, XBT_NULL, buf, &len);
  44.100 ++
  44.101 ++    free(buf);
  44.102 ++
  44.103 ++out:
  44.104 ++    return value;
  44.105 ++}
  44.106 ++
  44.107 ++/*
  44.108 ++  Read the hotplug status variable from the backend given the type
  44.109 ++  of device and its instance.
  44.110 ++*/
  44.111 ++char *xenstore_read_hotplug_status(struct xs_handle *handle,
  44.112 ++                                   const char *devtype, const char *inst)
  44.113 ++{
  44.114 ++    return xenstore_backend_read_variable(handle, devtype, inst,
  44.115 ++                                          "hotplug-status");
  44.116 ++}
  44.117 ++
  44.118 ++/*
  44.119 ++   Subscribe to the hotplug status of a device given the type of device and
  44.120 ++   its instance.
  44.121 ++   In case an error occurrs, a negative number is returned.
  44.122 ++ */
  44.123 ++int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
  44.124 ++                                         const char *devtype,
  44.125 ++                                         const char *inst,
  44.126 ++                                         const char *token)
  44.127 ++{
  44.128 ++    int rc = 0;
  44.129 ++    char *path = get_device_variable_path(devtype, inst, "hotplug-status");
  44.130 ++
  44.131 ++    if (path == NULL)
  44.132 ++        return -1;
  44.133 ++
  44.134 ++    if (0 == xs_watch(handle, path, token))
  44.135 ++        rc = -2;
  44.136 ++
  44.137 ++    free(path);
  44.138 ++
  44.139 ++    return rc;
  44.140 ++}
  44.141 ++
  44.142 ++/*
  44.143 ++ * Unsubscribe from a subscription to the status of a hotplug variable of
  44.144 ++ * a device.
  44.145 ++ */
  44.146 ++int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
  44.147 ++                                             const char *devtype,
  44.148 ++                                             const char *inst,
  44.149 ++                                             const char *token)
  44.150 ++{
  44.151 ++    int rc = 0;
  44.152 ++    char *path;
  44.153 ++    path = get_device_variable_path(devtype, inst, "hotplug-status");
  44.154 ++    if (path == NULL)
  44.155 ++        return -1;
  44.156 ++
  44.157 ++    if (0 == xs_unwatch(handle, path, token))
  44.158 ++        rc = -2;
  44.159 ++
  44.160 ++    free(path);
  44.161 ++
  44.162 ++    return rc;
  44.163 ++}
  44.164 +Index: ioemu/vl.h
  44.165 +===================================================================
  44.166 +--- ioemu.orig/vl.h	2006-12-08 18:20:53.000000000 +0000
  44.167 ++++ ioemu/vl.h	2006-12-08 18:20:53.000000000 +0000
  44.168 +@@ -1216,6 +1216,25 @@
  44.169 + void xenstore_write_vncport(int vnc_display);
  44.170 + int xenstore_read_vncpasswd(int domid);
  44.171 + 
  44.172 ++int xenstore_domain_has_devtype(struct xs_handle *handle,
  44.173 ++                                const char *devtype);
  44.174 ++char **xenstore_domain_get_devices(struct xs_handle *handle,
  44.175 ++                                   const char *devtype, unsigned int *num);
  44.176 ++char *xenstore_read_hotplug_status(struct xs_handle *handle,
  44.177 ++                                   const char *devtype, const char *inst);
  44.178 ++char *xenstore_backend_read_variable(struct xs_handle *,
  44.179 ++                                     const char *devtype, const char *inst,
  44.180 ++                                     const char *var);
  44.181 ++int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
  44.182 ++                                         const char *devtype,
  44.183 ++                                         const char *inst,
  44.184 ++                                         const char *token);
  44.185 ++int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
  44.186 ++                                             const char *devtype,
  44.187 ++                                             const char *inst,
  44.188 ++                                             const char *token);
  44.189 ++
  44.190 ++
  44.191 + /* xen_platform.c */
  44.192 + void pci_xen_platform_init(PCIBus *bus);
  44.193 + 
    45.1 --- a/tools/ioemu/patches/xenstore-write-vnc-port	Fri Dec 08 07:22:21 2006 -0800
    45.2 +++ b/tools/ioemu/patches/xenstore-write-vnc-port	Fri Dec 08 18:31:01 2006 +0000
    45.3 @@ -1,7 +1,7 @@
    45.4  Index: ioemu/xenstore.c
    45.5  ===================================================================
    45.6 ---- ioemu.orig/xenstore.c	2006-10-24 14:33:47.000000000 +0100
    45.7 -+++ ioemu/xenstore.c	2006-10-24 14:33:47.000000000 +0100
    45.8 +--- ioemu.orig/xenstore.c	2006-12-08 02:02:37.000000000 +0000
    45.9 ++++ ioemu/xenstore.c	2006-12-08 02:02:37.000000000 +0000
   45.10  @@ -185,3 +185,31 @@
   45.11       free(image);
   45.12       free(vec);
   45.13 @@ -36,9 +36,9 @@ Index: ioemu/xenstore.c
   45.14  +}
   45.15  Index: ioemu/vl.c
   45.16  ===================================================================
   45.17 ---- ioemu.orig/vl.c	2006-10-24 14:33:47.000000000 +0100
   45.18 -+++ ioemu/vl.c	2006-10-24 14:33:47.000000000 +0100
   45.19 -@@ -6550,6 +6550,7 @@
   45.20 +--- ioemu.orig/vl.c	2006-12-08 02:02:37.000000000 +0000
   45.21 ++++ ioemu/vl.c	2006-12-08 02:02:37.000000000 +0000
   45.22 +@@ -6535,6 +6535,7 @@
   45.23   	vnc_display = vnc_display_init(ds, vnc_display, vncunused, &vnclisten_addr);
   45.24   	if (vncviewer)
   45.25   	    vnc_start_viewer(vnc_display);
   45.26 @@ -48,8 +48,8 @@ Index: ioemu/vl.c
   45.27           sdl_display_init(ds, full_screen);
   45.28  Index: ioemu/vl.h
   45.29  ===================================================================
   45.30 ---- ioemu.orig/vl.h	2006-10-24 14:33:47.000000000 +0100
   45.31 -+++ ioemu/vl.h	2006-10-24 14:33:47.000000000 +0100
   45.32 +--- ioemu.orig/vl.h	2006-12-08 02:02:37.000000000 +0000
   45.33 ++++ ioemu/vl.h	2006-12-08 02:02:37.000000000 +0000
   45.34  @@ -1210,6 +1210,7 @@
   45.35   int xenstore_fd(void);
   45.36   void xenstore_process_event(void *opaque);