]> xenbits.xensource.com Git - xenclient/ioemu-pq.git/commitdiff
push 3.4 in master
authorVincent Hanquez <vincent.hanquez@eu.citrix.com>
Wed, 20 May 2009 19:48:35 +0000 (20:48 +0100)
committerVincent Hanquez <vincent.hanquez@eu.citrix.com>
Wed, 20 May 2009 19:48:35 +0000 (20:48 +0100)
28 files changed:
master/battery-management [new file with mode: 0644]
master/disable-aio [new file with mode: 0644]
master/dm-ready [new file with mode: 0644]
master/dom0-driver [new file with mode: 0644]
master/fix-build-warnings [new file with mode: 0644]
master/intel [new file with mode: 0644]
master/ioemu-compil [new file with mode: 0644]
master/oem-features [new file with mode: 0644]
master/series [new file with mode: 0644]
master/status [new file with mode: 0644]
master/thermal-management [new file with mode: 0644]
master/use-vga-cmdline [new file with mode: 0644]
master/vga-passthrough [new file with mode: 0644]
master/xenstore-watch-callbacks [new file with mode: 0644]
xen-3.4/battery-management [deleted file]
xen-3.4/disable-aio [deleted file]
xen-3.4/dm-ready [deleted file]
xen-3.4/dom0-driver [deleted file]
xen-3.4/fix-build-warnings [deleted file]
xen-3.4/intel [deleted file]
xen-3.4/ioemu-compil [deleted file]
xen-3.4/oem-features [deleted file]
xen-3.4/series [deleted file]
xen-3.4/status [deleted file]
xen-3.4/thermal-management [deleted file]
xen-3.4/use-vga-cmdline [deleted file]
xen-3.4/vga-passthrough [deleted file]
xen-3.4/xenstore-watch-callbacks [deleted file]

diff --git a/master/battery-management b/master/battery-management
new file mode 100644 (file)
index 0000000..b5e1a99
--- /dev/null
@@ -0,0 +1,272 @@
+diff --git a/hw/battery_mgmt.c b/hw/battery_mgmt.c
+index 3ddeb09..1c83b80 100644
+--- a/hw/battery_mgmt.c
++++ b/hw/battery_mgmt.c
+@@ -29,7 +29,6 @@
+ #include "hw.h"
+ #include "pc.h"
+ #include "qemu-xen.h"
+-#include "qemu-log.h"
+ #include "isa.h" //register_ioport_read declaration
+ #include "battery_mgmt.h"
+@@ -59,6 +58,7 @@
+ static enum POWER_MGMT_MODE power_mgmt_mode = PM_MODE_NONE;
+ static battery_state_info battery_info;
++extern FILE *logfile;
+ int is_battery_pt_feasible(void)
+ {
+@@ -229,15 +229,21 @@ static uint32_t battery_port_2_readb(void *opaque, uint32_t addr)
+ static uint32_t battery_port_3_readb(void *opaque, uint32_t addr)
+ {
+-    if ( power_mgmt_mode == PM_MODE_PT || power_mgmt_mode == PM_MODE_NON_PT ) {
+-        if ( (power_mgmt_mode == PM_MODE_PT) && (is_battery_pt_feasible() == 0) )
+-            return 0x0F;
+-        return 0x1F;
+-    }
++    uint32_t system_state;
+-    return 0x0F;
+-}
++    if ( power_mgmt_mode != PM_MODE_PT && power_mgmt_mode != PM_MODE_NON_PT )
++        return 0x0;
++
++    if ( (power_mgmt_mode == PM_MODE_PT) && (is_battery_pt_feasible() == 0) )
++        return 0x0;
++    system_state = xenstore_read_ac_adapter_state();
++    if ( xenstore_read_lid_state() == 1 )
++        system_state |= 0x4;
++
++    system_state |= 0x2;
++    return system_state;
++}
+ void battery_mgmt_non_pt_mode_init(PCIDevice *device)
+ {
+@@ -290,6 +296,7 @@ void battery_mgmt_init(PCIDevice *device)
+     }
+     register_ioport_read(BATTERY_PORT_3, 1, 1, battery_port_3_readb, device);
++    xenstore_register_for_pm_events();
+ #ifdef BATTERY_MGMT_DEBUG
+     fprintf(logfile, "Power management mode set to - %d\n", power_mgmt_mode);
+diff --git a/hw/battery_mgmt.h b/hw/battery_mgmt.h
+index 4a4ac8e..19129b8 100644
+--- a/hw/battery_mgmt.h
++++ b/hw/battery_mgmt.h
+@@ -42,4 +42,12 @@ typedef struct battery_state_info {
+ void battery_mgmt_init(PCIDevice *device);
++#ifndef CONFIG_NO_BATTERY_MGMT
++int is_battery_pt_feasible(void);
++void battery_mgmt_pt_mode_init(void);
++void get_battery_data_from_xenstore(void);
++void write_battery_data_to_port(void);
++void battery_mgmt_non_pt_mode_init(PCIDevice *device);
++#endif
++
+ #endif
+diff --git a/hw/pc.h b/hw/pc.h
+index 8b71d48..a261c8a 100644
+--- a/hw/pc.h
++++ b/hw/pc.h
+@@ -106,6 +106,10 @@ int acpi_table_add(const char *table_desc);
+ void acpi_php_add(int);
+ void acpi_php_del(int);
++void acpi_ac_adapter_state_changed(void);
++void acpi_power_button_pressed(void);
++void acpi_sleep_button_pressed(void);
++void acpi_lid_state_changed(void);
+ /* hpet.c */
+ extern int no_hpet;
+diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
+index 7844cb8..c218782 100644
+--- a/hw/piix4acpi.c
++++ b/hw/piix4acpi.c
+@@ -53,6 +53,11 @@
+ /* The bit in GPE0_STS/EN to notify the pci hotplug event */
+ #define ACPI_PHP_GPE_BIT 3
++#define ACPI_PHP_SLOT_NUM NR_PCI_DEV
++#define ACPI_AC_POWER_STATE_BIT 0x1c
++#define ACPI_POWER_BUTTON_BIT 0x1
++#define ACPI_SLEEP_BUTTON_BIT 0x0
++#define ACPI_LID_STATE_BIT 0x17
+ typedef struct AcpiDeviceState AcpiDeviceState;
+ AcpiDeviceState *acpi_device_table;
+@@ -192,8 +197,6 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
+     battery_mgmt_init(pci_dev);
+ }
+-#ifdef CONFIG_PASSTHROUGH
+-
+ static inline int test_bit(uint8_t *map, int bit)
+ {
+     return ( map[bit / 8] & (1 << (bit % 8)) );
+@@ -210,6 +213,56 @@ static inline void clear_bit(uint8_t *map, int bit)
+ }
+ extern FILE *logfile;
++
++void acpi_ac_adapter_state_changed(void)
++{
++    GPEState *s = &gpe_state;
++
++    if ( !test_bit(&s->gpe0_sts[0], ACPI_AC_POWER_STATE_BIT) &&
++         test_bit(&s->gpe0_en[0], ACPI_AC_POWER_STATE_BIT) ) {
++        set_bit(&s->gpe0_sts[0], ACPI_AC_POWER_STATE_BIT);
++        s->sci_asserted = 1;
++        qemu_irq_raise(sci_irq);
++    }
++}
++
++void acpi_power_button_pressed(void)
++{
++    GPEState *s = &gpe_state;
++    if ( !test_bit(&s->gpe0_sts[0], ACPI_POWER_BUTTON_BIT) &&
++         test_bit(&s->gpe0_en[0], ACPI_POWER_BUTTON_BIT) ) {
++        set_bit(&s->gpe0_sts[0], ACPI_POWER_BUTTON_BIT);
++        s->sci_asserted = 1;
++        qemu_irq_raise(sci_irq);
++    }
++}
++
++void acpi_sleep_button_pressed(void)
++{
++    GPEState *s = &gpe_state;
++
++    if ( !test_bit(&s->gpe0_sts[0], ACPI_SLEEP_BUTTON_BIT) &&
++          test_bit(&s->gpe0_en[0], ACPI_SLEEP_BUTTON_BIT) ) {
++        set_bit(&s->gpe0_sts[0], ACPI_SLEEP_BUTTON_BIT);
++        s->sci_asserted = 1;
++        qemu_irq_raise(sci_irq);
++    }
++}
++
++void acpi_lid_state_changed(void)
++{
++    GPEState *s = &gpe_state;
++
++    if ( !test_bit(&s->gpe0_sts[0], ACPI_LID_STATE_BIT) &&
++         test_bit(&s->gpe0_en[0], ACPI_LID_STATE_BIT) ) {
++        set_bit(&s->gpe0_sts[0], ACPI_LID_STATE_BIT);
++        s->sci_asserted = 1;
++        qemu_irq_raise(sci_irq);
++    }
++}
++
++#ifdef CONFIG_PASSTHROUGH
++
+ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
+ {
+ #if defined(DEBUG)
+diff --git a/qemu-xen.h b/qemu-xen.h
+index c45bf9f..8c1debd 100644
+--- a/qemu-xen.h
++++ b/qemu-xen.h
+@@ -122,8 +122,12 @@ void xenstore_dm_finished_startup(void);
+ int xenstore_vm_write(int domid, const char *key, const char *val);
+ char *xenstore_vm_read(int domid, const char *key, unsigned int *len);
+ char *xenstore_device_model_read(int domid, const char *key, unsigned int *len);
++int xenstore_extended_power_mgmt_read_int(const char *key, int default_value);
+ char *xenstore_read_battery_data(int battery_status);
+ int xenstore_refresh_battery_status(void);
++void xenstore_register_for_pm_events(void);
++int xenstore_read_ac_adapter_state(void);
++int xenstore_read_lid_state(void);
+ int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
+                                          uint32_t build_nr);
+diff --git a/xenstore.c b/xenstore.c
+index 99b31fd..6f5b073 100644
+--- a/xenstore.c
++++ b/xenstore.c
+@@ -27,6 +27,7 @@
+ #include "hw.h"
+ #include "pci.h"
++#include "pc.h"
+ #include "qemu-timer.h"
+ #include "qemu-xen.h"
+@@ -991,6 +992,25 @@ void xenstore_process_event(void *opaque)
+         goto out;
+     }
++    if (!strcmp(vec[XS_WATCH_TOKEN], "acadapterstatechangeevt")) {
++        acpi_ac_adapter_state_changed();
++        goto out;
++    }
++
++    if (!strcmp(vec[XS_WATCH_TOKEN], "pwrbuttonpressedevt")) {
++        acpi_power_button_pressed();
++        goto out;
++    }
++
++    if (!strcmp(vec[XS_WATCH_TOKEN], "slpbuttonpressedevt")) {
++        acpi_sleep_button_pressed();
++    }
++
++    if (!strcmp(vec[XS_WATCH_TOKEN], "lidstatechangeevt")) {
++        acpi_lid_state_changed();
++        goto out;
++    }
++
+     if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
+         strlen(vec[XS_WATCH_TOKEN]) != 3)
+         goto out;
+@@ -1373,6 +1393,20 @@ static char *xenstore_extended_power_mgmt_read(const char *key, unsigned int *le
+     return value;
+ }
++int xenstore_extended_power_mgmt_read_int(const char *key, int default_value)
++{
++    int value = default_value;
++    char *buffer;
++
++    buffer = xenstore_extended_power_mgmt_read(key, NULL);
++    if ( buffer == NULL )
++        return value;
++
++    value = strtoull(buffer, NULL, 10);
++    free(buffer);
++    return value;
++}
++
+ static int xenstore_extended_power_mgmt_write(const char *key, const char *value)
+ {
+     int ret;
+@@ -1425,6 +1459,24 @@ int xenstore_refresh_battery_status(void)
+     return xenstore_extended_power_mgmt_event_trigger("refreshbatterystatus", "1");
+ }
++void xenstore_register_for_pm_events(void)
++{
++   xs_watch(xsh, "/pm/events/acadapterstatechanged", "acadapterstatechangeevt");
++   xs_watch(xsh, "/pm/events/lidstatechanged", "lidstatechangeevt");
++   xs_watch(xsh, "/pm/events/powerbuttonpressed", "pwrbuttonpressedevt");
++   xs_watch(xsh, "/pm/events/sleepbuttonpressed", "slpbuttonpressedevt");
++}
++
++int xenstore_read_ac_adapter_state(void)
++{
++    return xenstore_extended_power_mgmt_read_int("ac_adapter", 1);
++}
++
++int xenstore_read_lid_state(void)
++{
++    return xenstore_extended_power_mgmt_read_int("lid_state", 1);
++}
++
+ /*
+  * Create a store entry for a device (e.g., monitor, serial/parallel lines).
+  * The entry is <domain-path><storeString>/tty and the value is the name
diff --git a/master/disable-aio b/master/disable-aio
new file mode 100644 (file)
index 0000000..b6c874e
--- /dev/null
@@ -0,0 +1,13 @@
+diff --git a/xen-setup b/xen-setup
+index 24defda..84f2936 100755
+--- a/xen-setup
++++ b/xen-setup
+@@ -9,7 +9,7 @@ rm -f config-host.mak
+ if test -f config-host.h; then mv config-host.h config-host.h~; fi
+-./configure --disable-gfx-check --disable-curses --disable-slirp --disable-vnc-tls --disable-sdl "$@" --prefix=/usr
++./configure --disable-gfx-check --disable-curses --disable-slirp --disable-vnc-tls --disable-sdl --disable-aio "$@" --prefix=/usr
+ target=i386-dm
diff --git a/master/dm-ready b/master/dm-ready
new file mode 100644 (file)
index 0000000..2a9fb8c
--- /dev/null
@@ -0,0 +1,55 @@
+diff --git a/qemu-xen.h b/qemu-xen.h
+index 434d7db..3dc4518 100644
+--- a/qemu-xen.h
++++ b/qemu-xen.h
+@@ -86,6 +86,7 @@ void xenstore_dom_chmod(int domid, const char *key, const char *perms);
+ char *xenstore_read(const char *path);
+ int xenstore_write(const char *path, const char *val);
++void xenstore_dm_finished_startup(void);
+  /* `danger' means that this parameter, variable or function refers to
+   * an area of xenstore which is writeable by the guest and thus must
+diff --git a/vl.c b/vl.c
+index 5801e42..c31e0a1 100644
+--- a/vl.c
++++ b/vl.c
+@@ -5966,6 +5966,8 @@ int main(int argc, char **argv, char **envp)
+       close(fd);
+     }
++    xenstore_dm_finished_startup();
++
+     main_loop();
+     quit_timers();
+     net_cleanup();
+diff --git a/xenstore.c b/xenstore.c
+index 6448416..6834cce 100644
+--- a/xenstore.c
++++ b/xenstore.c
+@@ -1609,3 +1609,25 @@ int xenstore_write(const char *path, const char *val)
+ }
++/* Advertise through xenstore that the device model is up and the
++   domain can be started. */
++void xenstore_dm_finished_startup(void)
++{
++    char *path;
++    char *buf = NULL;
++
++    path = xs_get_domain_path(xsh, domid);
++    if (!path) {
++        fprintf(logfile, "xs_get_domain_path() failed.\n");
++        goto out;
++    }
++    if (pasprintf(&buf, "%s/device-misc/dm-ready", path) == -1) {
++        fprintf(logfile, "pasprintf failed to get path.\n");
++        goto out;
++    }
++    if (xs_write(xsh, XBT_NULL, buf, "1", 1) == 0)
++        fprintf(logfile, "xs_write() dm-ready failed\n");
++ out:
++    free(buf);
++    free(path);
++}
diff --git a/master/dom0-driver b/master/dom0-driver
new file mode 100644 (file)
index 0000000..daaa97c
--- /dev/null
@@ -0,0 +1,1415 @@
+diff --git a/console.h b/console.h
+index 14b42f3..97214c0 100644
+--- a/console.h
++++ b/console.h
+@@ -341,4 +341,19 @@ const char *readline_get_history(unsigned int index);
+ void readline_start(const char *prompt, int is_password,
+                     ReadLineFunc *readline_func, void *opaque);
++/* get_time */
++char *get_time(void);
++
++/* dom0_driver.c */
++void dom0_driver_init(const char *position);
++
++/* hid_linux.c */
++void hid_linux_init(void);
++int  hid_linux_grab_keyboard(int grab);
++int  hid_linux_grab_mouse(int grab);
++void hid_linux_secure_keyboard(void (*)(int));
++void hid_linux_add_binding(const int *, void (*)(void*), void *);
++void hid_linux_reset_keyboard(void);
++void hid_linux_probe(int grab);
++
+ #endif
+diff --git a/dom0_driver.c b/dom0_driver.c
+new file mode 100644
+index 0000000..1b5cd06
+--- /dev/null
++++ b/dom0_driver.c
+@@ -0,0 +1,697 @@
++/*
++ * QEMU dom0_driver
++ *
++ * Copyright (c) 2009 Citrix Systems
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++
++#include "qemu-common.h"
++#include "console.h"
++#include "qemu-timer.h"
++#include "qemu-xen.h"
++
++#include <sys/types.h>
++#include <linux/input.h>
++#include <linux/kd.h>
++#include <dirent.h>
++#include <stdio.h>
++#include <string.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <string.h>
++#include <assert.h>
++#include <time.h>
++
++extern int vga_passthrough;
++extern int intel;
++
++static void dom0_driver_state_change(const char *path, void *opaque);
++static void dom0_driver_command(const char *path, void *opaque);
++static void dom0_driver_leave_done(void);
++
++#define DEBUG_DOM0_DRIVER             1
++#define XS_REFRESH_INTERVAL           1000
++#define DOM0_DRIVER_SWITCH_TIMEOUT    2
++
++#define DOM0_MOUSE              1
++#define DOM0_KEYBOARD           2
++
++#if DEBUG_DOM0_DRIVER
++# define DEBUG(_format_, args...)    \
++    do { \
++      char *__str = get_time();       \
++    fprintf(stderr, "[%s] dom0_driver(%d):%d: " _format_, __str, domid, __LINE__, ## args);\
++      free(__str); \
++    } while (false)
++#else
++# define DEBUG(_format_, args...) (void)0
++#endif
++
++#define NB_SLOTS        10
++
++static void             dom0_read(void *opaque);
++static void             dom0_driver_reset_keyboard(void);
++static void             dom0_read_secure(void *opaque);
++struct dom0_driver
++{
++    QEMUTimer *xs_timer;
++    int secure_fd;
++    int (*enter)(void);
++    int (*leave)(void);
++};
++
++struct dom0_driver_handler
++{
++    void (*init)(void);
++    void (*probe)(int);
++    int  (*grab_keyboard)(int);
++    int  (*grab_mouse)(int);
++    void (*secure_keyboard)(void (*)(int));
++    void (*reset_keyboard)(void);
++    void (*add_binding)(const int *, void (*)(void *), void *);
++};
++
++struct dom0_driver_xs_info
++{
++    int state;
++    int domid;
++    int new_slot;
++    int timestamp;
++    int pre;
++};
++
++static struct dom0_driver_handler dom0_driver_hid_linux =
++{
++    .init = hid_linux_init,
++    .probe = hid_linux_probe,
++    .grab_keyboard = hid_linux_grab_keyboard,
++    .grab_mouse = hid_linux_grab_mouse,
++    .secure_keyboard = hid_linux_secure_keyboard,
++    .reset_keyboard = hid_linux_reset_keyboard,
++    .add_binding = hid_linux_add_binding,
++};
++
++static struct dom0_driver driver;
++static struct dom0_driver_handler *dom0_driver_handler = NULL;
++
++static int dom0_driver_xs_read_dom0(const char *key)
++{
++    char        *str = NULL;
++
++    if (!(str = xenstore_read_dom0_driver(key)))
++    {
++      fprintf(stderr, "dom0_driver: fatal the node %s don't exits\n", key);
++      exit(2);
++    }
++    return strtol(str, NULL, 10);
++}
++
++static void dom0_driver_read_xs_info(struct dom0_driver_xs_info *info,
++                                   int                        controller)
++{
++    char        *str = NULL;
++    char        path[128];
++    int         val[10];
++    const char  *key[] = {"state", "domid", "new-slot", "timestamp", "pre"};
++
++    memset(info, -1, sizeof (struct dom0_driver_xs_info));
++    for (int i = 0; i < sizeof (key) / sizeof (key[0]); i++)
++    {
++      if (controller == DOM0_MOUSE)
++          sprintf(path, "mouse/%s", key[i]);
++      else if (controller == DOM0_KEYBOARD)
++          sprintf(path, "keyboard/%s", key[i]);
++      else
++      {
++          fprintf(stderr, "dom0_driver unknown controller type\n");
++          exit(2);
++      }
++
++      val[i] = -1;
++      if ((str = xenstore_read_dom0_driver(path)))
++      {
++          val[i] = strtol(str, NULL, 10);
++          free(str);
++      }
++    }
++
++    info->state = val[0];
++    info->domid = val[1];
++    info->new_slot = val[2];
++    info->timestamp = val[3];
++    info->pre = val[4];
++}
++
++static void dom0_driver_xs_write(const char *key, int val, int controller)
++{
++    char        path[256], str[20];
++
++    if (controller == DOM0_MOUSE)
++      sprintf(path, "mouse/%s", key);
++    else if (controller == DOM0_KEYBOARD)
++      sprintf(path, "keyboard/%s", key);
++    else
++    {
++      DEBUG("unknown controller type\n");
++      exit(2);
++    }
++
++    sprintf(str, "%d", val);
++    DEBUG("write %s=%d\n", path, val);
++    xenstore_write_dom0_driver(path, str);
++}
++
++/*
++** Blanker fonctions
++*/
++static void dom0_driver_blank_changed(void)
++{
++    char *str;
++    int blank;
++
++    if (!(str = xenstore_read_dom0_driver("blank")))
++      return;
++    blank = strtol(str, NULL, 10);
++    free(str);
++    if (blank == 2)
++    {
++      usleep(100 * 1000); /* 100 ms */
++      dom0_driver_leave_done();
++    }
++}
++static int dom0_driver_blank(void)
++{
++    xenstore_write_dom0_driver("blank", "1");
++    return 0;
++}
++static int dom0_driver_unblank(void)
++{
++    xenstore_write_dom0_driver("blank", "0");
++    return 0;
++}
++
++static void dom0_driver_key_switch(int new_slot)
++{
++    struct dom0_driver_xs_info  info;
++    char                        buff[128];
++
++    dom0_driver_read_xs_info(&info, DOM0_MOUSE);
++    assert(info.state == 1);
++
++    sprintf(buff, "switch %d", new_slot);
++
++    DEBUG("Write \"%s\" into xenstore\n", buff);
++    xenstore_write_dom0_driver("command", buff);
++}
++
++static void dom0_driver_read_secure(int ascii)
++{
++    int write_sz;
++
++    if (ascii)
++    {
++      DEBUG("Send %d to xenmgr\n", ascii);
++      write_sz = write(driver.secure_fd, &ascii, 1);
++      if (ascii == -1 || ascii == 27 || write_sz != 1)
++      {
++          dom0_driver_handler->reset_keyboard();
++          dom0_driver_handler->secure_keyboard(NULL);
++          return;
++      }
++    }
++}
++
++static void dom0_driver_detect_secure_auth(void* opaque)
++{
++    struct stat s;
++    int sas_ascii = 1, ret = 0;;
++
++    DEBUG("Received SAS keystroke\n");
++    if ((driver.secure_fd = open("/var/lib/xenmgr/keys", O_WRONLY)) > 0)
++    {
++      DEBUG("write SAS ascii code\n");
++      if ((ret = write(driver.secure_fd, &sas_ascii, 1)) == 1)
++      {
++          DEBUG("Redirect fds to secure callback\n");
++          dom0_driver_handler->secure_keyboard(dom0_driver_read_secure);
++      }
++      DEBUG("writing SAS ret %d\n", ret);
++
++    }
++    else
++      DEBUG("xenmgr file is not there\n");
++}
++
++static void dom0_get_positions(int *positions)
++{
++    int *domids = NULL;
++    int num;
++    char *tmp;
++    unsigned int len;
++    int pos = 0;
++
++    for (int i = 0; i < NB_SLOTS; i++)
++      positions[i] = 0;
++
++    /* Get all the positions */
++    domids = xenstore_get_domids(&num);
++    for (int i = 0; i < num; i++)
++      if (domids[i])
++      {
++          if (!(tmp = xenstore_dom_read(domids[i], "dom0_input/pos", &len)))
++              continue;
++          pos = strtol(tmp, NULL, 10);
++          free(tmp);
++
++          positions[pos] = domids[i];
++      }
++    free(domids);
++}
++
++static void dom0_gr_devices(int grab, int controller)
++{
++    if (controller == DOM0_MOUSE)
++    {
++      DEBUG("%s mouse\n", grab ? "Grab" : "Release");
++      assert(dom0_driver_handler->grab_mouse(grab));
++    }
++    if (controller == DOM0_KEYBOARD)
++    {
++      DEBUG("%s keyboard\n", grab ? "Grab" : "Release");
++      assert(dom0_driver_handler->grab_keyboard(grab));
++    }
++
++    dom0_driver_handler->reset_keyboard();
++    if (!grab)
++      dom0_driver_xs_write("pre", domid, controller);
++    dom0_driver_xs_write("domid", domid, controller);
++    dom0_driver_xs_write("state", grab ? 1 : 2, controller);
++}
++
++static int dom0_dom_alive(int id)
++{
++    xc_dominfo_t info;
++    int rc;
++
++    rc = xc_domain_getinfo(xc_handle, id, 1, &info);
++    return rc == 1 && info.domid == id;
++}
++
++
++static int dom0_driver_failover_switch(void *opaque)
++{
++    int                         ret = 1;
++    uint32_t                  t = time(NULL);
++    struct dom0_driver_xs_info        mouse, keyboard;
++
++    dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
++    dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
++    if (mouse.domid == domid)
++      dom0_driver_handler->probe(1);
++    else
++      dom0_driver_handler->probe(0);
++
++    if (!vga_passthrough)
++      return 0;
++
++    if (mouse.state == -1)
++    {
++      DEBUG("No state grab the device\n");
++      dom0_gr_devices(1, DOM0_KEYBOARD);
++      dom0_gr_devices(1, DOM0_MOUSE);
++      driver.enter();
++      goto out;
++    }
++
++    /* The domain which has the focus crash */
++    if (!dom0_dom_alive(mouse.domid))
++    {
++      DEBUG("steal the focus from %d\n", mouse.domid);
++      dom0_gr_devices(1, DOM0_KEYBOARD);
++      dom0_gr_devices(1, DOM0_MOUSE);
++      driver.enter();
++      goto out;
++    }
++
++    if ( keyboard.state == 2 &&
++          (t - keyboard.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
++    {
++      DEBUG("Keyboard in state 2 for to long, take it back\n");
++      dom0_gr_devices(1, DOM0_KEYBOARD);
++    }
++
++    if (mouse.state == 2 &&
++          (t - mouse.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
++    {
++      DEBUG("Mouse in state 2 for to long, take it back\n");
++      dom0_gr_devices(1, DOM0_MOUSE);
++      DEBUG("Get the focus now !\n");
++      driver.enter();
++      goto out;
++    }
++
++    ret = 0;
++out:
++    qemu_mod_timer(driver.xs_timer, qemu_get_clock(rt_clock) + XS_REFRESH_INTERVAL);
++    return ret;
++}
++
++static void dom0_driver_dom_command(const char *path, void *opaque)
++{
++    unsigned int len;
++    char *str;
++    char buff[256];
++    int       positions[NB_SLOTS];
++    int natif_domid;
++    int i;
++    struct dom0_driver_xs_info mouse;
++
++    if (!(str = xenstore_read(path)) || !*str)
++      return;
++
++    DEBUG("Received private command %s\n", path);
++    dom0_get_positions(positions);
++    natif_domid = dom0_driver_xs_read_dom0("natif");
++
++    dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
++    if (mouse.domid != natif_domid)
++    {
++      DEBUG("Natif should have the focus for that.\n");
++      return;
++    }
++
++    for (i = 0; i < NB_SLOTS; ++i)
++    {
++      if (!strcmp("take", str) && positions[i] == domid)
++          break;
++      if (!strcmp("release", str) && positions[i] == natif_domid)
++          break;
++    }
++    if (i == NB_SLOTS)
++    {
++      DEBUG("Try to %s on a bad slot\n", str);
++      free(str);
++      return;
++    }
++
++    sprintf(buff, "keyboard %d", i);
++    DEBUG("Write \"%s\" into xenstore\n", buff);
++    xenstore_write_dom0_driver("command", buff);
++    free(str);
++}
++
++static void dom0_driver_event_init(const char *str_arg)
++{
++    int                 positions[NB_SLOTS];
++    char                str[20];
++    int                 pos = 0;
++    int                 i = 0;
++
++    pos = strtol(str_arg, NULL, 10);
++    dom0_get_positions(positions);
++    if (positions[pos])
++    {
++      DEBUG("There is already a vm at this slot\n");
++      exit(1);
++    }
++    else
++    {
++      snprintf(str, 9, "%d", pos);
++      xenstore_dom_write(domid, "dom0_input/pos", str);
++    }
++
++    if (vga_passthrough)
++    {
++      sprintf(str, "%d", domid);
++      xenstore_write_dom0_driver("natif", str);
++      xenstore_watch_dom0_driver("command", dom0_driver_command, NULL);
++    }
++    else
++    {
++      xenstore_dom_write(domid, "dom0_input/command", "");
++      sprintf(str, "w%d", domid);
++      xenstore_dom_chmod(domid, "dom0_input/command", str);
++      xenstore_dom_watch(domid, "dom0_input/command", dom0_driver_dom_command, NULL);
++    }
++
++    xenstore_watch_dom0_driver("mouse/state", dom0_driver_state_change, NULL);
++    xenstore_watch_dom0_driver("keyboard/state", dom0_driver_state_change, NULL);
++    xenstore_watch_dom0_driver("leave", dom0_driver_state_change, NULL);
++    xenstore_watch_dom0_driver("blank", dom0_driver_state_change, NULL);
++
++    /* Register the failover switch */
++    driver.xs_timer = qemu_new_timer(rt_clock,
++                                   (void (*)(void *))dom0_driver_failover_switch,
++                                   NULL);
++    qemu_mod_timer(driver.xs_timer, qemu_get_clock(rt_clock) + XS_REFRESH_INTERVAL);
++}
++
++static void dom0_driver_slots(int controller)
++{
++    struct dom0_driver_xs_info  info;
++    int                         next_domid;
++    int                         positions[NB_SLOTS];
++
++    if (dom0_driver_failover_switch(NULL))
++      return;
++
++    dom0_driver_read_xs_info(&info, controller);
++
++    if (info.new_slot != -1)
++    {
++      dom0_get_positions(positions);
++      if (positions[info.new_slot] != 0)
++      {
++          if (info.state == 0 && info.domid == domid)
++          {
++              dom0_gr_devices(0, controller);
++              return;
++          }
++
++          if (info.state == 2 && positions[info.new_slot] == domid)
++          {
++              dom0_gr_devices(1, controller);
++              return;
++          }
++
++      }
++    }
++}
++
++static void dom0_driver_switch_controller(int slot, int controller)
++{
++    int       positions[NB_SLOTS];
++    char *str;
++    int len;
++    int ready;
++    struct dom0_driver_xs_info info;
++
++    dom0_get_positions(positions);
++    if (positions[slot] == 0)
++    {
++      DEBUG("Cannot switch controller %d to %d slot empty\n", controller, slot);
++      return;
++    }
++
++    str = xenstore_dom_read(positions[slot], "dom0_input/ready", &len);
++    ready = strtol(str, NULL, 10);
++    free(str);
++    if (ready != 1)
++    {
++      DEBUG("Cannot switch controller %d to %d slot not ready\n", controller, slot);
++      return;
++    }
++
++    dom0_driver_read_xs_info(&info, controller);
++    if (info.state != 1)
++    {
++      DEBUG("Cannot switch controller %d to %d, unstable state\n", controller, slot);
++      return;
++    }
++
++    dom0_driver_xs_write("new-slot", slot, controller);
++    dom0_driver_xs_write("timestamp", time(NULL), controller);
++    dom0_driver_xs_write("state", 0, controller);
++}
++
++void dom0_driver_command(const char *path, void *opaque)
++{
++    char        *val = NULL;
++
++    val = xenstore_read(path);
++    if (val == NULL)
++      return;
++
++    if (!strncmp(val, "switch ", 7))
++    {
++      int slot = strtol(val + 7, NULL, 10);
++
++      if (errno == EINVAL)
++          goto out;
++
++      DEBUG("switch the keyboard/mouse to slot %d\n", slot);
++      dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
++      dom0_driver_switch_controller(slot, DOM0_MOUSE);
++      xenstore_write(path, "done");
++    }
++    else if (!strncmp(val, "keyboard ", 9))
++    {
++      int slot = strtol(val + 9, NULL, 10);
++
++      if (errno == EINVAL)
++          goto out;
++
++      DEBUG("switch the keyboard to slot %d\n", slot);
++      dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
++      xenstore_write(path, "done");
++    }
++out:
++    free(val);
++}
++
++static void dom0_driver_leave_done(void)
++{
++    char *str;
++    int id;
++
++    if (!(str = xenstore_read_dom0_driver("leave")))
++      return;
++    id = strtol(str, NULL, 10);
++    free(str);
++    if (id == 1)
++      xenstore_write_dom0_driver("leave", "2");
++}
++
++static void dom0_driver_leave_changed(void)
++{
++    char *str;
++    int id;
++    struct dom0_driver_xs_info mouse;
++
++    if (!(str = xenstore_read_dom0_driver("leave")))
++      return;
++    id = strtol(str, NULL, 10);
++    free(str);
++    dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
++    if (id == 2 && mouse.domid == domid)
++    {
++      xenstore_write_dom0_driver("leave", "0");
++      driver.enter();
++    }
++}
++
++static void dom0_driver_state_change(const char *path, void *opaque)
++{
++
++    if (strstr(path, "/keyboard/state"))
++      dom0_driver_slots(DOM0_KEYBOARD);
++    if (strstr(path, "/mouse/state"))
++      dom0_driver_slots(DOM0_MOUSE);
++    if (strstr(path, "/leave"))
++      dom0_driver_leave_changed();
++    else if (strstr(path, "/blank"))
++      dom0_driver_blank_changed();
++    else
++    {
++      struct dom0_driver_xs_info  mouse, keyboard;
++
++      dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
++      dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
++
++      if (mouse.state == 1 && keyboard.state == 1)
++          if (mouse.pre != -1 && mouse.pre == domid)
++          {
++              xenstore_write_dom0_driver("leave", "1");
++              if (driver.leave())
++                  dom0_driver_leave_done();
++          }
++    }
++}
++
++static void dom0_driver_switch(void *slot_arg)
++{
++    int slot = (int)slot_arg;
++    char buff[64];
++
++    DEBUG("%d pressed switch to slot %d\n", slot, slot);
++    sprintf(buff, "switch %d", slot);
++    xenstore_write_dom0_driver("command", buff);
++}
++
++static void dom0_driver_switch_bind(void)
++{
++    int               i = 0;
++    int               binds[4];
++
++    for (i = 0; i < 4; i++)
++      binds[i] = -1;
++
++    for (i = 0; i < 9; i++)
++    {
++      binds[0] = KEY_LEFTCTRL;
++      binds[1] = KEY_1 + i;
++      dom0_driver_handler->add_binding(binds, dom0_driver_switch, (void*)(i + 1));
++    }
++
++    binds[0] = KEY_LEFTCTRL;
++    binds[1] = KEY_LEFTALT;
++    binds[2] = KEY_BACKSPACE;
++    binds[3] = -1;
++    dom0_driver_handler->add_binding(binds, dom0_driver_detect_secure_auth, NULL);
++}
++
++static int dom0_driver_dummy_enter_leave(void)
++{
++  return 1;
++}
++
++void dom0_driver_init(const char *position)
++{
++    memset(&driver, 0, sizeof (driver));
++
++    dom0_driver_handler = &dom0_driver_hid_linux;
++    dom0_driver_handler->init();
++
++    if (vga_passthrough)
++    {
++      driver.enter = dom0_driver_unblank;
++      driver.leave = dom0_driver_blank;
++    }
++    else if (intel)
++    {
++        driver.enter = intel_enter;
++        driver.enter = intel_leave;
++    }
++    else
++    {
++      driver.enter = dom0_driver_dummy_enter_leave;
++      driver.leave = dom0_driver_dummy_enter_leave;
++    }
++
++    dom0_driver_switch_bind();
++    dom0_driver_event_init(position);
++    dom0_driver_failover_switch(NULL);
++
++    DEBUG("done\n");
++    xenstore_dom_write(domid, "dom0_input/ready", "1");
++}
+diff --git a/hid-linux.c b/hid-linux.c
+new file mode 100644
+index 0000000..4ec6bdd
+--- /dev/null
++++ b/hid-linux.c
+@@ -0,0 +1,513 @@
++/*
++ * QEMU hid-linux /dev/input driver
++ *
++ * Copyright (c) 2008 Citrix Systems
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++
++#include "qemu-common.h"
++#include "console.h"
++#include "qemu-timer.h"
++#include "qemu-xen.h"
++
++#include <sys/types.h>
++#include <linux/input.h>
++#include <linux/kd.h>
++#include <dirent.h>
++#include <stdio.h>
++#include <string.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <string.h>
++#include <assert.h>
++#include <time.h>
++#include <sys/time.h>
++
++#define HID_LINUX_XS_PATH             "/local/domain/0/hid_linux"
++#define ABS(x)                        ((x) > 0 ? (x) : -(x))
++#define EVENT_PATH                            "/dev/input/event"
++#define HID_LINUX_MAX_DEV             16
++
++#define DEBUG_HID_LINUX
++
++#ifdef DEBUG_HID_LINUX
++# define DEBUG(_format_, args...)     \
++    do \
++{ \
++    char *__str = get_time(); \
++    fprintf(stderr, "[%s] hid-linux(%d):%d: " _format_, (__str), domid, __LINE__, ## args);\
++    free(__str);\
++} \
++while (0);
++#else
++# define DEBUG(_format_, args...) (void)0
++#endif
++
++static struct hid_linux_driver
++{
++    int               keyboard_fds[HID_LINUX_MAX_DEV / 2];
++    int               mouse_fds[HID_LINUX_MAX_DEV / 2];
++    char      *controller_paths[HID_LINUX_MAX_DEV];
++    int               mouse_button_state;
++    int               key_status[256];
++    void      (*secure_key)(int ascii);
++} hid_linux_driver;
++
++struct hid_linux_binding
++{
++    int       *binding;
++    void      (*cb)(void *);
++    void      *payload;
++};
++
++static struct hid_linux_binding *hid_linux_binding = NULL;
++
++static const int ascii2keycode_table[] =
++{
++    KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
++    KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
++    KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z
++};
++
++static char keycode2ascii(int keycode)
++{
++    int i = 0;
++
++    switch (keycode)
++    {
++      case KEY_ESC: return 27;
++      case KEY_BACKSPACE: return 8;
++      case KEY_ENTER: return 10;
++      case KEY_LEFT: return 17;
++      case KEY_RIGHT: return 18;
++      case KEY_DELETE: return 127;
++      case KEY_HOME: return 2;
++      case KEY_END: return 3;
++      case KEY_INSERT: return 19;
++      case KEY_SPACE: return 20;
++      default:
++              for (i = 0; i < sizeof (ascii2keycode_table) / sizeof (int); i++)
++                  if (ascii2keycode_table[i] == keycode)
++                      return i + 'a';
++    }
++    return 0;
++}
++
++static int ascii2keycode(char ascii)
++{
++    return ascii2keycode_table[ascii - 'a'];
++}
++
++static char *hid_linux_xs_read(const char *key)
++{
++    char *path = NULL;
++    char *ret;
++
++    if (asprintf(&path, HID_LINUX_XS_PATH"/%s", key) == -1)
++      return NULL;
++    ret = xenstore_read(path);
++    free(path);
++    return ret;
++}
++
++void hid_linux_add_binding(const int *tab, void (*cb)(void*), void *payload)
++{
++    int i = 0, j = 0;
++
++    for (i = 0; hid_linux_binding && hid_linux_binding[i].cb; i++)
++      ;
++    hid_linux_binding = realloc(hid_linux_binding,
++                              (i + 2) * sizeof (struct hid_linux_binding));
++    hid_linux_binding[i + 1].cb = NULL;
++    hid_linux_binding[i].cb = cb;
++    hid_linux_binding[i].payload = payload;
++    hid_linux_binding[i].binding = NULL;
++
++    j = 0;
++    do
++    {
++      hid_linux_binding[i].binding = realloc(hid_linux_binding[i].binding,
++                                             (j + 1) * sizeof (int));
++      hid_linux_binding[i].binding[j] = tab[j];
++    }
++    while (tab[j++] != -1);
++}
++
++static int hid_linux_detect_binding(void)
++{
++    int i, j;
++
++    for (i = 0; hid_linux_binding && hid_linux_binding[i].cb; i++)
++    {
++      int *tab = hid_linux_binding[i].binding;
++
++      for (j = 0; tab[j] != -1; j++)
++          if (hid_linux_driver.key_status[tab[j]] == 0)
++              break;
++      if (tab[j] != -1)
++          continue;
++      else /* We match a binding */
++      {
++          DEBUG("binding payload %d\n", (int)(hid_linux_binding[i].payload));
++          hid_linux_binding[i].cb(hid_linux_binding[i].payload);
++          hid_linux_reset_keyboard();
++          return 1;
++      }
++    }
++    return 0;
++}
++
++static void hid_linux_key_inject(int code, uint32_t keycode)
++{
++    int first = 0;
++
++    switch (keycode)
++    {
++      case KEY_F11:       keycode = 0X57; break; /* F11 */
++      case KEY_F12:       keycode = 0X58; break; /* F12 */
++      case KEY_INSERT:    keycode = 0X52; break;
++      case KEY_HOME:      keycode = 0X47; break;
++      case KEY_PAGEUP:    keycode = 0X49; break;
++      case KEY_DELETE:    keycode = 0X53; break;
++      case KEY_END:       keycode = 0X4F; break;
++      case KEY_PAGEDOWN:  keycode = 0x51; break;
++      case KEY_UP:        keycode = 0X48; break;
++      case KEY_LEFT:      keycode = 0X4B; break;
++      case KEY_DOWN:      keycode = 0X50; break;
++      case KEY_RIGHT:     keycode = 0X4D; break;
++      case KEY_RIGHTALT:  keycode = 0x38; first = 0xe0; break;
++      case KEY_LEFTMETA:  keycode = 0x5B; first = 0xe0; break;
++      case KEY_RIGHTMETA: keycode = 0x5C; first = 0xe0; break;
++    }
++
++    if (first)
++      kbd_put_keycode(first);
++
++    if (code == 0)
++      kbd_put_keycode(keycode | 0x80);
++    else
++      kbd_put_keycode(keycode & 0x7f);
++}
++
++
++
++static void hid_linux_key_event(int code, uint32_t keycode)
++{
++    if (code == 1)
++      if (hid_linux_detect_binding())
++          return;
++    hid_linux_key_inject(code, keycode);
++}
++
++static void hid_linux_read(void *opaque)
++{
++    struct input_event  event[5];
++    int                 i = 0;
++    int                 read_sz = 0;
++    int                 fd = *(int *)opaque;
++
++    read_sz = read(fd, event, sizeof (event));
++    for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
++    {
++      if (event[i].type == EV_KEY)
++      {
++          if (event[i].code >= BTN_MOUSE)
++          {
++              /* Mouse Key */
++              int     type = 0;
++
++              switch(event[i].code)
++              {
++                  case BTN_LEFT: type = MOUSE_EVENT_LBUTTON; break;
++                  case BTN_RIGHT: type = MOUSE_EVENT_RBUTTON; break;
++                  case BTN_MIDDLE: type = MOUSE_EVENT_MBUTTON; break;
++              }
++
++              if (event[i].value)
++                  hid_linux_driver.mouse_button_state |= type;
++              else
++                  hid_linux_driver.mouse_button_state &= ~type;
++              kbd_mouse_event(0, 0, 0, hid_linux_driver.mouse_button_state);
++          }
++          else
++          {
++              hid_linux_driver.key_status[event[i].code] = event[i].value;
++              hid_linux_key_event(event[i].value, event[i].code);
++          }
++      }
++
++      if (event[i].type == EV_REL || event[i].type == EV_ABS)
++      {
++          /* Mouse motion */
++          int x = 0, y = 0, z = 0;
++
++          if (event[i].type == EV_REL)
++              switch (event[i].code)
++              {
++                  case REL_X : x = event[i].value; break;
++                  case REL_Y : y = event[i].value; break;
++                  case REL_WHEEL : z = -event[i].value; break;
++              }
++          if (event[i].type == EV_ABS)
++          {
++              static int last_x = 1, last_y = 1;
++              int px = 0, py = 0, l = 50;
++              double div = 1;
++              char *str = NULL;
++
++              str = hid_linux_xs_read("touchpad-limit");
++              if (str)
++                  l = strtol(str, NULL, 10);
++              str = hid_linux_xs_read("touchpad-div");
++              if (str)
++                  div = strtol(str, NULL, 10) / 1000.;
++
++              switch (event[i].code)
++              {
++                  case ABS_X : x = event[i].value; break;
++                  case ABS_Y : y = event[i].value; break;
++              }
++
++              if (x)
++              {
++                  px = x - last_x;
++                  last_x = x;
++              }
++              if (y)
++              {
++                  py = y - last_y;
++                  last_y = y;
++              }
++
++              x = (ABS(px) < l ? px : 0) / div;
++              y = (ABS(py) < l ? py : 0) / div;
++          }
++
++          kbd_mouse_event(x, y, z, hid_linux_driver.mouse_button_state);
++      }
++    }
++}
++
++void hid_linux_reset_keyboard(void)
++{
++    int i = 0;
++
++    for (i = 0; i < 256; i++)
++      if (hid_linux_driver.key_status[i])
++      {
++          hid_linux_key_inject(0, i);
++          hid_linux_driver.key_status[i] = 0;
++      }
++}
++
++
++
++static void hid_linux_redirect_fds(int *fd, IOHandler *cb)
++{
++    assert(fd != NULL);
++
++    while (*fd != -1)
++    {
++      qemu_set_fd_handler(*fd, cb, NULL, fd);
++      fd++;
++    }
++}
++
++static void hid_linux_secure_read(void *opaque)
++{
++    struct input_event  event[5];
++    int                 i = 0;
++    int                 read_sz = 0;
++    int                 fd = *(int *)opaque;
++
++    assert(hid_linux_driver.secure_key);
++
++    read_sz = read(fd, event, sizeof (event));
++    for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
++      if (event[i].type == EV_KEY && event[i].code < BTN_MOUSE &&
++              event[i].value > 0)
++          hid_linux_driver.secure_key(keycode2ascii(event[i].code));
++}
++
++
++void hid_linux_secure_keyboard(void (*cb)(int ascii))
++{
++    hid_linux_driver.secure_key = cb;
++    if (cb)
++      hid_linux_redirect_fds(hid_linux_driver.keyboard_fds,
++              hid_linux_secure_read);
++    else
++      hid_linux_redirect_fds(hid_linux_driver.keyboard_fds,
++              hid_linux_read);
++}
++
++static int hid_linux_grab_devices(int grab, int *fd)
++{
++    int rc = 0;
++    int try = 10;
++
++    assert(fd != NULL && *fd != -1);
++    for (; *fd != -1; fd++)
++    {
++      while (try--)
++      {
++          if ((rc = ioctl(*fd, EVIOCGRAB, grab)) == -1)
++          {
++              char *er;
++
++              if (errno == EBUSY)
++                  continue;
++              er = strerror(errno);
++              DEBUG("ioctl(%d, EVOCGRAB) failed, %s\n", *fd, er);
++              return 0;
++          }
++          else
++              break;
++      }
++      assert(try);
++
++      DEBUG("ioctl(%d, EVOCGRAB) succed\n", *fd);
++
++      if (grab)
++          qemu_set_fd_handler(*fd, hid_linux_read, NULL, fd);
++      else
++          qemu_set_fd_handler(*fd, NULL, NULL, fd);
++    }
++    return 1;
++}
++
++int hid_linux_grab_keyboard(int grab)
++{
++    return hid_linux_grab_devices(grab, hid_linux_driver.keyboard_fds);
++}
++
++int hid_linux_grab_mouse(int grab)
++{
++    return hid_linux_grab_devices(grab, hid_linux_driver.mouse_fds);
++}
++
++static int hid_linux_open_timeout(const char *path, int flags)
++{
++   int        try = 10;
++   int  fd = 0;
++
++   while (try-- && ((fd = open(path, flags)) == -1))
++       usleep(100000); /* 10 ms */
++   if (try == 0)
++       return 0;
++   return fd == -1 ? 0 : fd;
++}
++
++static int hid_linux_ioctl_timeout(int fd, int arg1, void *arg2)
++{
++   int        try = 10;
++
++   while (try-- && ioctl(fd, arg1, arg2) == -1)
++       usleep(100000); /* 10 ms */
++   if (try == 0)
++       return 0;
++   return 1;
++}
++
++void hid_linux_probe(int grab)
++{
++    int         i = 0, j = 0, c = 0;
++    int         fd = -1;
++    int         keyboard = 0, mouse = 0;
++    char        path[strlen(EVENT_PATH) + 3];
++    char        name[128];
++    int               *controllers;
++    struct stat       st;
++
++    while (1)
++    {
++      sprintf(path, "%s%i", EVENT_PATH, i++);
++
++      if (stat(path, &st) == -1)
++          break;
++
++      for ( c = 0; c < HID_LINUX_MAX_DEV && hid_linux_driver.controller_paths[c]; c++)
++          if (!strcmp(hid_linux_driver.controller_paths[c], path))
++              break;
++      assert(c != HID_LINUX_MAX_DEV);
++      if (hid_linux_driver.controller_paths[c])
++          continue;
++
++      if ((fd = open(path, O_RDONLY)) == -1)
++          break;
++
++      if (ioctl(fd, EVIOCGNAME(128), name) == -1)
++      {
++          DEBUG("Input get name failed on %s\n", path);
++          break;
++      }
++
++      if (strcasestr(name, "keyboard"))
++      {
++          DEBUG("Add %s %s as a keyboard, fd=%d\n", path, name, fd);
++          controllers = hid_linux_driver.keyboard_fds;
++      }
++      else
++      {
++          DEBUG("Add %s %s as a mouse, fd=%d\n", path, name, fd);
++          controllers = hid_linux_driver.mouse_fds;
++      }
++
++      for ( j = 0; j < (HID_LINUX_MAX_DEV / 2) && controllers[j] != -1; j++)
++          ;
++      assert(j != (HID_LINUX_MAX_DEV / 2));
++
++      controllers[j] = fd;
++      controllers[j + 1] = -1;
++
++      if (grab)
++      {
++          if (!hid_linux_grab_devices(1, controllers + j))
++          {
++              DEBUG("Grabing failed, try next time...\n");
++              controllers[j] = -1;
++              break;
++          }
++      }
++
++      hid_linux_driver.controller_paths[c] = strdup(path);
++      hid_linux_driver.controller_paths[c + 1] = NULL;
++
++      fd = -1;
++    }
++    if (fd != -1)
++      close(fd);
++}
++
++void hid_linux_init(void)
++{
++    hid_linux_driver.keyboard_fds[0] = -1;
++    hid_linux_driver.mouse_fds[0] = -1;
++    hid_linux_driver.controller_paths[0] = NULL;
++
++    while (hid_linux_driver.keyboard_fds[0] == -1)
++    {
++      hid_linux_probe(0);
++      usleep(100000); /* 10 ms */
++    }
++}
+diff --git a/qemu-xen.h b/qemu-xen.h
+index 0cc5dd8..2646ec7 100644
+--- a/qemu-xen.h
++++ b/qemu-xen.h
+@@ -107,7 +107,13 @@ int xenstore_write(const char *path, const char *val);
+ void xenstore_dm_finished_startup(void);
+- /* `danger' means that this parameter, variable or function refers to
++char *xenstore_read_dom0_driver(const char *key);
++int xenstore_write_dom0_driver(const char *key, const char *str);
++int xenstore_watch_dom0_driver(const char *key, xenstore_callback fptr, void *opaque);
++
++int *xenstore_get_domids(int *len);
++
++/* `danger' means that this parameter, variable or function refers to
+   * an area of xenstore which is writeable by the guest and thus must
+   * not be trusted by qemu code.  For variables containing xenstore
+   * paths, `danger' can mean that both the path refers to a
+diff --git a/vl.c b/vl.c
+index e519705..0ffe1ec 100644
+--- a/vl.c
++++ b/vl.c
+@@ -234,6 +234,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
+ int win2k_install_hack = 0;
+ int rtc_td_hack = 0;
+ int vga_passthrough = 0;
++const char *dom0_input = NULL;
+ #endif
+ int usb_enabled = 0;
+ int smp_cpus = 1;
+@@ -278,6 +279,20 @@ uint8_t qemu_uuid[16];
+ #include "xen-vl-extra.c"
++char *get_time(void)
++{
++
++  char buff[128];
++  char *str;
++  struct timeval tv;
++
++  gettimeofday(&tv, NULL);
++  str = malloc(256);
++  strftime(buff, 128, "%T", localtime(&tv.tv_sec));
++  sprintf(str, "%s:%06d", buff, (int)tv.tv_usec);
++  return str;
++}
++
+ /***********************************************************/
+ /* x86 ISA bus support */
+@@ -4277,6 +4292,7 @@ enum {
+     QEMU_OPTION_acpi,
+     QEMU_OPTION_vcpus,
+     QEMU_OPTION_vga_passthrough,
++    QEMU_OPTION_dom0_input,
+     /* Debug/Expert options: */
+     QEMU_OPTION_serial,
+@@ -4451,6 +4467,7 @@ static const QEMUOption qemu_options[] = {
+     { "vncunused", 0, QEMU_OPTION_vncunused },
+     { "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
+     { "vga-passthrough", 0, QEMU_OPTION_vga_passthrough },
++    { "dom0-input", 1, QEMU_OPTION_dom0_input },
+ #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
+     { "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
+     { "xen-create", 0, QEMU_OPTION_xen_create },
+@@ -5287,6 +5304,9 @@ int main(int argc, char **argv, char **envp)
+             case QEMU_OPTION_vga_passthrough:
+                 vga_passthrough = 1;
+                 break;
++            case QEMU_OPTION_dom0_input:
++                dom0_input = optarg;
++                break;
+             case QEMU_OPTION_direct_pci:
+                direct_pci = optarg;
+                 break;
+@@ -6053,6 +6073,9 @@ int main(int argc, char **argv, char **envp)
+         close(fd);
+     }
++    if (dom0_input)
++      dom0_driver_init(dom0_input);
++
+     xenstore_dm_finished_startup();
+     main_loop();
+diff --git a/xen-hooks.mak b/xen-hooks.mak
+index 7c94718..f243df1 100644
+--- a/xen-hooks.mak
++++ b/xen-hooks.mak
+@@ -37,6 +37,8 @@ OBJS += helper2.o
+ OBJS += battery_mgmt.o
+ OBJS += xen_acpi_wmi.o
+ OBJS += thermal_mgmt.o
++OBJS += dom0_driver.o
++OBJS += hid-linux.o
+ ifdef CONFIG_STUBDOM
+ CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
+diff --git a/xenstore.c b/xenstore.c
+index 01afcf0..20ca8cf 100644
+--- a/xenstore.c
++++ b/xenstore.c
+@@ -1727,3 +1727,63 @@ void xenstore_dm_finished_startup(void)
+     free(buf);
+     free(path);
+ }
++
++char *xenstore_read_dom0_driver(const char *key)
++{
++    const char *path = "/local/domain/0/dom0_driver";
++    char *buf = NULL;
++    int len = 0;
++    char *val = NULL;
++
++    if (pasprintf(&buf, "%s/%s", path, key) == -1)
++        return NULL;
++    val = xs_read(xsh, XBT_NULL, buf, &len);
++    free(buf);
++    return val;
++}
++
++int xenstore_watch_dom0_driver(const char *key, xenstore_callback fptr, void *opaque)
++{
++    const char *path = "/local/domain/0/dom0_driver";
++    char *buf = NULL;
++    int ret = 0;
++
++    if (pasprintf(&buf, "%s/%s", path, key) == -1)
++        return 0;
++    xenstore_watch_new_callback(buf, fptr, opaque);
++    free(buf);
++    return ret;
++}
++
++int xenstore_write_dom0_driver(const char *key, const char *str)
++{
++    const char *path = "/local/domain/0/dom0_driver";
++    char *buf = NULL;
++    int len = 0;
++    int ret = 0;
++
++    if (pasprintf(&buf, "%s/%s", path, key) == -1)
++        return 0;
++    ret = xs_write(xsh, XBT_NULL, buf, str, strlen(str));
++    free(buf);
++    return ret;
++}
++
++int *xenstore_get_domids(int *len)
++{
++    int *tab = NULL;
++    char **e;
++
++    e = xs_directory(xsh, XBT_NULL, "/local/domain", len);
++    if (e == NULL)
++    {
++        len = 0;
++        return NULL;
++    }
++
++    tab = malloc(*len * sizeof (int));
++    for (int i = 0; i < *len; i++)
++        tab[i] = strtol(e[i], NULL, 10);
++    return tab;
++}
++
diff --git a/master/fix-build-warnings b/master/fix-build-warnings
new file mode 100644 (file)
index 0000000..9b2d41c
--- /dev/null
@@ -0,0 +1,19 @@
+diff -Nur a/hw/pci.h b/hw/pci.h
+--- a/hw/pci.h 2009-05-13 14:31:58.000000000 -0400
++++ b/hw/pci.h 2009-05-13 16:51:34.000000000 -0400
+@@ -168,9 +168,13 @@
+ #define PCI_STATUS_RESERVED1  0x007
+ #define PCI_STATUS_INT_STATUS 0x008
+ #define PCI_STATUS_CAPABILITIES       0x010
+-#define PCI_STATUS_66MHZ      0x020
++#ifndef PCI_STATUS_66MHZ
++#define PCI_STATUS_66MHZ        0x020
++#endif
+ #define PCI_STATUS_RESERVED2  0x040
+-#define PCI_STATUS_FAST_BACK  0x080
++#ifndef PCI_STATUS_FAST_BACK
++#define PCI_STATUS_FAST_BACK    0x080
++#endif
+ #define PCI_STATUS_DEVSEL     0x600
+ #define PCI_STATUS_RESERVED_MASK_LO (PCI_STATUS_RESERVED1 | \
diff --git a/master/intel b/master/intel
new file mode 100644 (file)
index 0000000..3520c50
--- /dev/null
@@ -0,0 +1,605 @@
+diff --git a/console.h b/console.h
+index 97214c0..4c51c50 100644
+--- a/console.h
++++ b/console.h
+@@ -290,6 +290,9 @@ void vga_hw_update(void);
+ void vga_hw_invalidate(void);
+ void vga_hw_screen_dump(const char *filename);
++void unset_vga_acc(void);
++void set_vga_acc(void);
++
+ int is_graphic_console(void);
+ int is_fixedsize_console(void);
+ CharDriverState *text_console_init(const char *p);
+@@ -356,4 +359,8 @@ void hid_linux_add_binding(const int *, void (*)(void*), void *);
+ void hid_linux_reset_keyboard(void);
+ void hid_linux_probe(int grab);
++/* intel.c */
++int intel_enter(void);
++int intel_leave(void);
++void intel_display_init(DisplayState *ds);
+ #endif
+diff --git a/hw/vga.c b/hw/vga.c
+index 90bd544..b0f9f9c 100644
+--- a/hw/vga.c
++++ b/hw/vga.c
+@@ -161,6 +161,18 @@ static uint8_t expand4to8[16];
+ static void vga_bios_init(VGAState *s);
+ static void vga_screen_dump(void *opaque, const char *filename);
++static VGAState *xen_vga_state;
++
++void set_vga_acc(void)
++{
++   set_vram_mapping(xen_vga_state, xen_vga_state->lfb_addr, xen_vga_state->lfb_end);
++}
++
++void unset_vga_acc(void)
++{
++   unset_vram_mapping(xen_vga_state);
++}
++
+ static void vga_dumb_update_retrace_info(VGAState *s)
+ {
+     (void) s;
+@@ -2473,8 +2485,6 @@ static void vga_bios_init(VGAState *s)
+ }
+-static VGAState *xen_vga_state;
+-
+ /* Allocate video memory in the GPFN space */
+ void xen_vga_populate_vram(uint64_t vram_addr, uint32_t vga_ram_size)
+ {
+diff --git a/intel.c b/intel.c
+new file mode 100644
+index 0000000..4c5f773
+--- /dev/null
++++ b/intel.c
+@@ -0,0 +1,494 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <sys/mman.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <assert.h>
++#include <signal.h>
++#include <pci/pci.h>
++
++#include "qemu-common.h"
++#include "console.h"
++#include "sysemu.h"
++
++#define INTEL_DEBUG(format, args...)                                    \
++    fprintf (stderr, "intel.c:%d:%s " format , __LINE__, __func__, ## args)
++
++#define TileW           128
++#define TileH           8
++
++#define REG_DR_DSPASURF               0x7019C
++#define REG_DR_DSPACNTR               0x70180
++#define REG_DR_DSPASTRIDE     0x70188
++#define REG_DR_PIPEACONF      0x70008
++
++#define REG_DR_DSPBSURF               0x7119C
++#define REG_DR_DSPBCNTR               0x71180
++#define REG_DR_DSPBSTRIDE     0x71188
++#define REG_DR_PIPEBCONF      0x71008
++
++#define REG_DE_PIPEASRC               0x6001c
++
++extern int                      vga_passthrough;
++uint32_t                        guest_framebuffer;
++
++static int                      display = 0;
++
++static int                      mmio_fd = -1;
++static int                      mem_fd = -1;
++static uint8_t                  *intel_mem = NULL;
++static uint8_t                  *intel_mmio = NULL;
++static int                      intel_force_full_update = 0;
++static int                      intel_have_focus;
++static int                      IntelPitch = 16;
++static int                      IntelX = 1280;
++static int                      IntelY = 1024;
++static DisplayState             *lds = NULL;
++static uint8_t                  *old_data = NULL;
++static uint32_t                 intel_fb_base, intel_mmio_base;
++static uint32_t                 map_s, map_d, map_size;
++static int                      refresh;
++
++static void set_data_mappings(void);
++static void unset_data_mappings(int mapping);
++static void set_data_pointer(void);
++static void intel_resize(DisplayState *ds);
++
++static inline unsigned int intel_get_reg(unsigned int reg)
++{
++    return *(unsigned int*)(intel_mmio + reg);
++}
++
++static inline int is_linear(void)
++{
++    unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
++    if (((*dspacntr) & (1 << 10)) == 0)
++        return 1;
++    else
++        return 0;
++}
++
++static inline unsigned int intel_get_pitch(void)
++{
++    unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
++    return *dspastride;
++}
++
++static inline unsigned int intel_get_offset(DisplaySurface *ds, int x, int y)
++{
++    return (y * ds->width + x) * 4;
++}
++
++static void intel_update_linear(DisplaySurface *ds, int x, int y, int w, int h)
++{
++    int i, bpp = ds->pf.depth / 8;
++    unsigned char *s, *d;
++    s = ds->data;
++    d = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
++    s += (ds->linesize * y) + bpp * x;
++    d += (ds->linesize * y) + bpp * x;
++    for (i = 0; i < h; i++) {
++        memcpy(d, s, w * bpp);
++        s += ds->linesize;
++        d += ds->linesize;
++    }
++}
++
++static void intel_force_linear(int linesize)
++{
++    unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
++    unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF);
++    unsigned int *dspasurf = (unsigned int *)(intel_mmio + REG_DR_DSPASURF);
++    unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
++
++    unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
++    unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF);
++    unsigned int *dspbsurf = (unsigned int *)(intel_mmio + REG_DR_DSPBSURF);
++    unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
++
++    unsigned int surfa = 0, surfb = 0, pipea = 0, pipeb = 0;
++    char pipebenabled = !!(*pipebconf & (1 << 30));
++
++
++    INTEL_DEBUG("DSPASURF CTRL: 0x%x\n", intel_get_reg(REG_DR_DSPACNTR));
++
++    /* Disable surface */
++    pipea = *pipeaconf & (0x3 << 18);
++    *pipeaconf &= ~(0x3 << 18);
++    *dspacntr |= (1 << 31);
++    /* Address of the surface to map to */
++    surfa = *dspasurf;
++    *dspasurf = 0x00000000;
++    *dspacntr &= ~(1 << 31);
++    *dspasurf = 0x00000000;
++    *pipeaconf |= pipea;
++
++    if (pipebenabled) {
++        INTEL_DEBUG("PIPEBCONF enabled.\n");
++
++        /* Disable surface */
++        pipeb = *pipebconf & (0x3 << 18);
++        *pipebconf &= ~(0x3 << 18);
++        *dspbcntr |= (1 << 31);
++        /* Address of the surface to map to */
++        surfb = *dspbsurf;
++        *dspbsurf = 0x00000000;
++        *dspbcntr &= ~(1 << 31);
++        *dspbsurf = 0x00000000;
++        *pipebconf |= pipeb;
++    }
++
++    usleep(20000);
++
++    *pipeaconf &= ~(0x3 << 18);
++    /* Enable surface linear mode */
++    *dspacntr &= ~(1 << 10);
++    if (linesize) *dspastride = linesize;
++    *dspasurf = surfa;
++    *dspacntr |= (1 << 31);
++    *pipeaconf |= pipea;
++
++    if (pipebenabled) {
++        *pipebconf &= ~(0x3 << 18);
++        /* Enable surface linear mode */
++        *dspbcntr &= ~(1 << 10);
++        if (linesize) *dspbstride = linesize;
++        *dspbsurf = surfb;
++        *dspbcntr |= (1 << 31);
++        *pipebconf |= pipeb;
++    }
++
++    usleep(20000);
++}
++
++static void intel_update(DisplayState *ds, int x, int y, int w, int h)
++{
++    if (intel_have_focus && !old_data && !map_size)
++        intel_update_linear(ds->surface, x, y, w, h);
++}
++
++static void set_fb_mapping(void)
++{
++    DisplaySurface *surf = lds->surface;
++    int rc;
++    unsigned long nr_pfn;
++
++    unset_vga_acc();
++    fprintf(stderr, "set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_reg(REG_DR_DSPASURF)), guest_framebuffer);
++    nr_pfn = (surf->linesize * surf->height) >> TARGET_PAGE_BITS;
++
++    rc = xc_domain_memory_mapping(xc_handle,
++            domid,
++            (guest_framebuffer >> TARGET_PAGE_BITS),
++            ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS),
++            nr_pfn,
++            DPCI_ADD_MAPPING);
++    if (rc) {
++        fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
++        return;
++    }
++    map_s = ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS);
++    map_d = (guest_framebuffer >> TARGET_PAGE_BITS);
++    map_size = nr_pfn;
++}
++
++static void unset_fb_mapping(void)
++{
++    int rc;
++
++    fprintf(stderr, "unset_fb_mapping: %x %x\n", map_d, map_s);
++
++    rc = xc_domain_memory_mapping(xc_handle,
++            domid,
++            map_d,
++            map_s,
++            map_size,
++            DPCI_REMOVE_MAPPING);
++    if (rc) {
++        fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
++        return;
++    }
++
++    set_vga_acc();
++    map_s = 0;
++    map_d = 0;
++    map_size = 0;
++}
++
++static void intel_setdata(DisplayState *ds)
++{
++    if (map_size)
++        unset_fb_mapping();
++    set_fb_mapping();
++}
++
++static void intel_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
++{
++    DisplaySurface *surf = ds->surface;
++
++    if (!intel_have_focus) {
++        surf->width = w;
++        surf->height = h;
++        intel_resize(ds);
++        return;
++    }
++    if (depth == 32 && w == IntelX && h == IntelY)
++        surf->flags = QEMU_ALLOCATED_FLAG;
++    else
++        surf->flags &= ~QEMU_ALLOCATED_FLAG;
++    if (surf->flags & QEMU_ALLOCATED_FLAG) {
++        surf->width = w;
++        surf->height = h;
++        surf->pf.depth = 32;
++        surf->linesize = linesize;
++        /* adjust linesize */
++        intel_force_linear(linesize);
++        set_data_mappings();
++        if (refresh) {
++            memcpy(surf->data, pixels, surf->linesize * surf->height);
++            refresh = 0;
++        }
++        surf->data = pixels;
++        intel_setdata(ds);
++    } else {
++        surf->width = w;
++        surf->height = h;
++        intel_resize(ds);
++    }
++}
++
++static void intel_resize(DisplayState *ds)
++{
++    DisplaySurface *surf = ds->surface;
++    int old_linesize = surf->linesize;
++
++    if (surf->pf.depth == 32 && surf->width == IntelX && surf->height == IntelY)
++      surf->flags = QEMU_ALLOCATED_FLAG;
++    else
++      surf->flags &= ~QEMU_ALLOCATED_FLAG;
++
++    if (is_buffer_shared(surf))
++    {
++      INTEL_DEBUG("intel_resize_shared: enable shared buffer, linesize %d\n",
++                  surf->linesize);
++      intel_force_linear(surf->linesize);
++      set_data_mappings();
++      if (refresh)
++      {
++        // Pixels doesn't exist anymore ??
++        //memcpy(surf->data, pixels, surf->linesize * surf->height);
++        refresh = 0;
++      }
++      intel_setdata(ds);
++      return;
++    }
++    
++    INTEL_DEBUG("intel_resize: no shared buffer, linesize=%d\n", surf->linesize);
++    surf->linesize = intel_get_pitch();
++    if (map_size) {
++        unset_fb_mapping();
++        unset_data_mappings(1);
++    }
++    if (intel_have_focus && !is_linear()) {
++        intel_force_linear(0);
++    }
++    surf->flags &= ~QEMU_ALLOCATED_FLAG;
++    if (intel_have_focus && !old_data &&
++        surf->width * surf->height <= IntelX * IntelY)
++        set_data_mappings();
++    else if (intel_have_focus && old_data &&
++             surf->width * surf->height > IntelX * IntelY)
++        unset_data_mappings(0);
++    if (!old_data) {
++        qemu_free(surf->data);
++        surf->data = qemu_mallocz(surf->height * surf->linesize);
++    } else {
++        INTEL_DEBUG("intel_resize: set_data_pointer\n");
++        set_data_pointer();
++    }
++    if (intel_have_focus)
++        memset((unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)), 0x0, IntelX * IntelY);
++    if (refresh) {
++        if (old_data) {
++            unsigned char *s, *d;
++            int i;
++            s = old_data;
++            d = surf->data;
++            for (i = 0; i < surf->height; i++) {
++                memcpy(d, s, surf->width * 4);
++                s += old_linesize;
++                d += surf->linesize;
++            }
++        }
++        refresh = 0;
++    }
++}
++
++static void intel_refresh(DisplayState *ds)
++{
++    vga_hw_update();
++}
++
++static void intel_init_mapping(void)
++{
++    struct pci_access   *pci_bus;
++    struct pci_dev      *pci_dev;
++
++    mmio_fd = open("/dev/mem", O_RDWR);
++    if (mmio_fd == -1)
++    {
++        perror("open");
++        exit(1);
++    }
++    mem_fd = open("/dev/mem", O_RDWR);
++    if (mem_fd == -1)
++    {
++        perror("open");
++        exit(1);
++    }
++
++    pci_bus = pci_alloc();
++    pci_init(pci_bus);
++    pci_dev = pci_get_dev(pci_bus, 0, 0, 2, 0);
++    pci_fill_info(pci_dev, PCI_FILL_BASES);
++    intel_fb_base = pci_dev->base_addr[2] & 0xfffff000;
++    intel_mmio_base = pci_dev->base_addr[0] & 0xfffff000;
++    pci_free_dev(pci_dev);
++    pci_cleanup(pci_bus);
++
++    INTEL_DEBUG("Map intel main mem 0x%x\n", intel_fb_base);
++    intel_mem = mmap(NULL, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED,
++                     mem_fd, intel_fb_base);
++    if (intel_mem == MAP_FAILED)
++    {
++        perror("mmap");
++        exit(1);
++    }
++
++    INTEL_DEBUG("Map intel mmio 0x%x\n", intel_mmio_base);
++    intel_mmio = mmap(NULL, 4 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED,
++                      mmio_fd, intel_mmio_base);
++    if (intel_mem == MAP_FAILED)
++    {
++        perror("mmap");
++        exit(1);
++    }
++}
++
++static void set_data_pointer(void)
++{
++    DisplaySurface *surf = lds->surface;
++
++    surf->data = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
++    surf->data = surf->data +
++                surf->linesize * ((IntelY - surf->height) / 2) +
++                4 * ((IntelX - surf->width) / 2);
++}
++
++static void set_data_mappings(void)
++{
++    INTEL_DEBUG("set_data_mappings\n");
++    if (!old_data)
++        old_data = lds->surface->data;
++    set_data_pointer();
++}
++
++static void unset_data_mappings(int mapping)
++{
++    DisplaySurface *surf = lds->surface;
++    if (!old_data)
++        return;
++    if (mapping) {
++        uint8_t * buffer_pointer = surf->data;
++        surf->data = old_data;
++        old_data = NULL;
++        surf->data = realloc(surf->data, surf->linesize * surf->height);
++        memcpy(surf->data,
++                (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)),
++                surf->linesize * surf->height);
++        memcpy(buffer_pointer,
++                surf->data,
++                surf->linesize * surf->height);
++    } else {
++        uint8_t * buffer_pointer = surf->data;
++        surf->data = old_data;
++        old_data = NULL;
++        surf->data = realloc(surf->data, surf->linesize * surf->height);
++        memcpy(surf->data,
++                buffer_pointer,
++                surf->linesize * surf->height);
++    }
++    INTEL_DEBUG("unset_data_mappings %d: success\n", mapping);
++}
++
++static int intel_getfocus(void)
++{
++    return intel_have_focus;
++}
++
++static void intel_focus(int focus)
++{
++    if (intel_have_focus == focus)
++        return;
++
++    INTEL_DEBUG("intel_focus %d\n", focus);
++    intel_have_focus = focus;
++    if (focus) {
++        if (!is_linear()) {
++          IntelPitch = intel_get_reg(REG_DR_DSPASTRIDE);
++          IntelX = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1;
++          IntelY = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1;
++          INTEL_DEBUG("Resolution is %dx%d\n", IntelX, IntelY);
++        }
++        refresh = 1;
++        lds->listeners->dpy_resize = intel_resize;
++        lds->listeners->dpy_setdata = intel_setdata;
++        vga_hw_invalidate();
++    } else {
++        if (map_size) {
++            unset_fb_mapping();
++            unset_data_mappings(1);
++        } else if (old_data) {
++            unset_data_mappings(0);
++        }
++        lds->listeners->dpy_resize = NULL;
++        lds->listeners->dpy_setdata = NULL;
++        lds->surface->flags &= ~QEMU_ALLOCATED_FLAG;
++    }
++}
++
++int intel_enter(void)
++{
++    intel_focus(1);
++    return 1;
++}
++
++int intel_leave(void)
++{
++    intel_focus(0);
++    return 1;
++}
++
++void intel_display_init(DisplayState *ds)
++{
++    DisplaySurface *surf = ds->surface;
++
++    INTEL_DEBUG("\n");
++
++    intel_init_mapping();
++
++    INTEL_DEBUG("Frambuffer is at 0x%x\n", intel_get_reg(REG_DR_DSPASURF));
++
++    surf->flags = 0;
++    surf->width = 640;
++    surf->height = 480;
++    surf->pf.depth = 32;
++    intel_resize(ds);
++    lds = ds;
++
++    ds->listeners->dpy_update = intel_update;
++    ds->listeners->dpy_resize = intel_resize;
++    ds->listeners->dpy_refresh = intel_refresh;
++}
+diff --git a/vl.c b/vl.c
+index 0ffe1ec..d6379a9 100644
+--- a/vl.c
++++ b/vl.c
+@@ -235,6 +235,7 @@ int win2k_install_hack = 0;
+ int rtc_td_hack = 0;
+ int vga_passthrough = 0;
+ const char *dom0_input = NULL;
++int intel = 0;
+ #endif
+ int usb_enabled = 0;
+ int smp_cpus = 1;
+@@ -4293,6 +4294,7 @@ enum {
+     QEMU_OPTION_vcpus,
+     QEMU_OPTION_vga_passthrough,
+     QEMU_OPTION_dom0_input,
++    QEMU_OPTION_intel,
+     /* Debug/Expert options: */
+     QEMU_OPTION_serial,
+@@ -4468,6 +4470,7 @@ static const QEMUOption qemu_options[] = {
+     { "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
+     { "vga-passthrough", 0, QEMU_OPTION_vga_passthrough },
+     { "dom0-input", 1, QEMU_OPTION_dom0_input },
++    { "intel", 0, QEMU_OPTION_dom0_input },
+ #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
+     { "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
+     { "xen-create", 0, QEMU_OPTION_xen_create },
+@@ -5307,6 +5310,9 @@ int main(int argc, char **argv, char **envp)
+             case QEMU_OPTION_dom0_input:
+                 dom0_input = optarg;
+                 break;
++            case QEMU_OPTION_intel:
++                intel = 1;
++                break;
+             case QEMU_OPTION_direct_pci:
+                direct_pci = optarg;
+                 break;
+diff --git a/xen-hooks.mak b/xen-hooks.mak
+index f243df1..55dd477 100644
+--- a/xen-hooks.mak
++++ b/xen-hooks.mak
+@@ -39,6 +39,7 @@ OBJS += xen_acpi_wmi.o
+ OBJS += thermal_mgmt.o
+ OBJS += dom0_driver.o
+ OBJS += hid-linux.o
++OBJS += intel.o
+ ifdef CONFIG_STUBDOM
+ CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
diff --git a/master/ioemu-compil b/master/ioemu-compil
new file mode 100644 (file)
index 0000000..477838b
--- /dev/null
@@ -0,0 +1,45 @@
+diff --git a/xen-hooks.mak b/xen-hooks.mak
+index c6b4f8c..d2f09fb 100644
+--- a/xen-hooks.mak
++++ b/xen-hooks.mak
+@@ -52,7 +52,7 @@ endif
+ ifdef CONFIG_STUBDOM
+ CONFIG_PASSTHROUGH=1
+ else
+-  ifeq (,$(wildcard /usr/include/pci))
++  ifeq (,$(wildcard $(PCI_PREFIX_DIR)/usr/include/pci))
+ $(warning === pciutils-dev package not found - missing /usr/include/pci)
+ $(warning === PCI passthrough capability has been disabled)
+   else
+@@ -62,6 +62,9 @@ endif
+ ifdef CONFIG_PASSTHROUGH
+ OBJS+= pass-through.o pt-msi.o
++ifdef PCI_PREFIX_DIR
++LIBS += -L$(PCI_PREFIX_DIR)/usr/lib
++endif
+ LIBS += -lpci
+ CFLAGS += -DCONFIG_PASSTHROUGH 
+ $(info === PCI passthrough capability has been enabled ===)
+diff --git a/xen-setup b/xen-setup
+index 8ca0019..24defda 100755
+--- a/xen-setup
++++ b/xen-setup
+@@ -9,7 +9,7 @@ rm -f config-host.mak
+ if test -f config-host.h; then mv config-host.h config-host.h~; fi
+-./configure --disable-gfx-check --disable-curses --disable-slirp "$@" --prefix=/usr
++./configure --disable-gfx-check --disable-curses --disable-slirp --disable-vnc-tls --disable-sdl "$@" --prefix=/usr
+ target=i386-dm
+@@ -17,6 +17,8 @@ if [ "x$XEN_ROOT" != x ]; then
+       echo "XEN_ROOT=$XEN_ROOT" >>config-host.mak
+ fi
++echo "PCI_PREFIX_DIR=${STAGING_ROOT}" >>config-host.mak
++
+ ln -sf ../Makefile.target $target/Makefile
+ ln -sf ../xen-config.mak $target/config.mak
+ cat xen-config-host.mak >>config-host.mak
diff --git a/master/oem-features b/master/oem-features
new file mode 100644 (file)
index 0000000..7110652
--- /dev/null
@@ -0,0 +1,973 @@
+diff --git a/hw/acpi-wmi.h b/hw/acpi-wmi.h
+new file mode 100644
+index 0000000..af99c1c
+--- /dev/null
++++ b/hw/acpi-wmi.h
+@@ -0,0 +1,99 @@
++/******************************************************************************
++ * acpi-wmi.h
++ *
++ * Interface to /proc/misc/xen-acpi-wmi
++ *
++ * Copyright (c) 2009 Kamala Narasimhan
++ * Copyright (c) 2009 Citrix Systems, Inc.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation; or, when distributed
++ * separately from the Linux kernel or incorporated into other
++ * software packages, subject to the following license:
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this source file (the "Software"), to deal in the Software without
++ * restriction, including without limitation the rights to use, copy, modify,
++ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
++ * and to permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++ * IN THE SOFTWARE.
++ */
++
++/*  NOTE:  This header is a duplicate of drivers/xen/acpi-wmi/acpi-wmi.h in our
++ *  kernel repo.  As we don't share headers between kernel and userspace, we have
++ *  the same header in two places.  It is important to keep the two headers in sync
++ *  to avoid incompatibilities.
++ */ 
++
++#ifndef _XEN_WMI_ACPI
++#define _XEN_WMI_ACPI
++
++/*
++ * Userspace Interface
++ */
++
++#define XEN_WMI_DEVICE_NAME              "xen-acpi-wmi"
++#define XEN_WMI_GUID_SIZE                16
++
++#define XEN_WMI_SUCCESS                  0
++#define XEN_WMI_UNSUPPORTED_TYPE        -1
++#define XEN_WMI_BUFFER_TOO_SMALL        -11
++#define XEN_WMI_NOT_ENOUGH_MEMORY       -12
++#define XEN_WMI_EFAULT                  -14
++#define XEN_WMI_INVALID_ARGUMENT        -22
++#define XEN_WMI_ENOIOCTLCMD             -515
++ 
++#define XEN_WMI_IOCTL_CALL_METHOD        100
++#define XEN_WMI_IOCTL_QUERY_OBJECT       101
++#define XEN_WMI_IOCTL_SET_OBJECT         102
++#define XEN_WMI_IOCTL_GET_EVENT_DATA     103
++
++typedef unsigned char byte;
++
++typedef struct xen_wmi_buffer {
++    size_t       length; 
++    void        *pointer;
++    size_t      *copied_length;
++} xen_wmi_buffer_t;
++
++typedef struct xen_wmi_obj_invocation_data { 
++    byte                       guid[XEN_WMI_GUID_SIZE];
++    union {
++        struct {
++            ushort             instance;
++            uint               method_id;
++            xen_wmi_buffer_t   in_buf;
++            xen_wmi_buffer_t   out_buf;
++        } xen_wmi_method_arg;
++
++        struct {
++            ushort             instance;
++            xen_wmi_buffer_t   out_buf;
++        } xen_wmi_query_obj_arg;
++
++        struct {
++            ushort             instance;
++            xen_wmi_buffer_t   in_buf;
++        } xen_wmi_set_obj_arg;
++
++        struct {
++            ushort             event_id;
++            xen_wmi_buffer_t   out_buf;
++        } xen_wmi_event_data_arg;
++    } xen_wmi_arg;
++} xen_wmi_obj_invocation_data_t;
++
++#endif /* _XEN_WMI_ACPI */
++
+diff --git a/hw/pc.h b/hw/pc.h
+index a261c8a..2e3cade 100644
+--- a/hw/pc.h
++++ b/hw/pc.h
+@@ -111,6 +111,8 @@ void acpi_power_button_pressed(void);
+ void acpi_sleep_button_pressed(void);
+ void acpi_lid_state_changed(void);
++void acpi_oem_event(void);
++
+ /* hpet.c */
+ extern int no_hpet;
+diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
+index c218782..cf214a4 100644
+--- a/hw/piix4acpi.c
++++ b/hw/piix4acpi.c
+@@ -29,6 +29,7 @@
+ #include "sysemu.h"
+ #include "qemu-xen.h"
+ #include "battery_mgmt.h"
++#include "xen_acpi_wmi.h"
+ #include <xen/hvm/ioreq.h>
+ #include <xen/hvm/params.h>
+@@ -58,6 +59,7 @@
+ #define ACPI_POWER_BUTTON_BIT 0x1
+ #define ACPI_SLEEP_BUTTON_BIT 0x0
+ #define ACPI_LID_STATE_BIT 0x17
++#define ACPI_OEM_EVENT_BIT 0x18
+ typedef struct AcpiDeviceState AcpiDeviceState;
+ AcpiDeviceState *acpi_device_table;
+@@ -195,6 +197,7 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
+     register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
+     battery_mgmt_init(pci_dev);
++    xen_acpi_wmi_init(pci_dev);
+ }
+ static inline int test_bit(uint8_t *map, int bit)
+@@ -261,6 +262,19 @@ void acpi_lid_state_changed(void)
+     }
+ }
++void acpi_oem_event(void)
++{
++    GPEState *s = &gpe_state;
++
++    if ( !test_bit(&s->gpe0_sts[0], ACPI_OEM_EVENT_BIT) &&
++          test_bit(&s->gpe0_en[0], ACPI_OEM_EVENT_BIT) ) {
++        set_bit(&s->gpe0_sts[0], ACPI_OEM_EVENT_BIT);
++        s->sci_asserted = 1;
++        fprintf(logfile, "Raising oem event irq\n");
++        qemu_irq_raise(sci_irq);
++    }
++}
++
+ #ifdef CONFIG_PASSTHROUGH
+ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
+diff --git a/hw/xen_acpi_wmi.c b/hw/xen_acpi_wmi.c
+new file mode 100644
+index 0000000..e759e89
+--- /dev/null
++++ b/hw/xen_acpi_wmi.c
+@@ -0,0 +1,654 @@
++/*
++ * xen_acpi_wmi.c
++ *
++ * Copyright (c) 2009  Kamala Narasimhan
++ * Copyright (c) 2009  Citrix Systems, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++/* Xen ACPI WMI implementation - 
++ * OEMs expose their value add functionalites through firmware level WMI 
++ * acpi objects.  To support the underlying OEM value add within guest 
++ * space, we expose a WMI psuedo device object at our vACPI layer.  That 
++ * vACPI layer relies on the below implementation to communication to the
++ * base firmware (through xen wmi module and linux acpi wmi wrapper 
++ * driver) either it be to execute a WMI method or query or set 
++ * data or recieve wmi event data. 
++ */
++
++/* NOTE:  As the vACPI layer is written to send request and take response in a 
++ * synchronized way, there isn't a need to add synchronization logic here.
++ */
++
++#include "hw.h"
++#include "pc.h"
++#include "qemu-xen.h"
++#include "isa.h" 
++#include "xen_acpi_wmi.h"
++#include <sys/ioctl.h>
++
++#ifndef CONFIG_NO_XEN_ACPI_WMI
++
++#define XEN_WMI_DEFAULT_OUTPUT_BUFFER_SIZE 256
++
++static xen_acpi_wmi_cmd_info_t cmd_info;
++static int xen_wmi_device = -ENODEV;  
++extern FILE *logfile;
++
++/* #define XEN_ACPI_WMI_DEBUG */
++/* #define XEN_ACPI_WMI_DEBUG_EXT */
++
++/*
++ * xen_acpi_wmi_set_guid
++ */
++void xen_acpi_wmi_set_guid(uint8_t val)
++{
++    if ( cmd_info.invocation_type == XEN_ACPI_WMI_UNDEFINED )
++    {
++        fprintf(logfile, 
++            "XEN WMI: Unable to set guid with invalid invocation type!\n");
++        return;
++    }
++
++    if ( cmd_info.current_index >= XEN_WMI_GUID_SIZE )
++    {
++        fprintf(logfile, "XEN WMI: Guid array index out of range - %d!!!\n", 
++                cmd_info.current_index);
++        cmd_info.invocation_type = XEN_ACPI_WMI_UNDEFINED;  
++        return;
++    }
++
++    cmd_info.invocation_data.guid[cmd_info.current_index] = val;
++    cmd_info.current_index++;
++}
++
++/*
++ * xen_acpi_wmi_set_cmd_instance
++ */
++void xen_acpi_wmi_set_cmd_instance(uint32_t val)
++{
++    if ( cmd_info.invocation_type == XEN_ACPI_WMI_UNDEFINED ) 
++    {
++        fprintf(logfile, 
++            "XEN WMI: Unable to set cmd instance with invalid invocation type!\n");
++        return;
++    }
++
++    switch( cmd_info.invocation_type )
++    {
++        case XEN_ACPI_WMI_EXEC_METHOD:
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.instance = val;
++            break;
++        case XEN_ACPI_WMI_QUERY_OBJECT:
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_query_obj_arg.instance = val;
++            break;
++        case XEN_ACPI_WMI_SET_OBJECT:
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.instance = val;
++            break;
++        default:
++            fprintf(logfile, 
++                "Invalid attempt to set instance for current invocation type!\n");
++            break;
++    }
++}
++
++/*
++ * xen_acpi_wmi_set_method_id
++ */
++void xen_acpi_wmi_set_method_id(uint32_t val)
++{
++    if ( cmd_info.invocation_type != XEN_ACPI_WMI_EXEC_METHOD )
++    {
++        fprintf(logfile,
++            "Unable to set method id for the current invocation type!\n");
++        return;
++    }
++
++    cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.method_id = val;
++}
++
++/*
++ * xen_acpi_wmi_get_input_buffer
++ */
++xen_wmi_buffer_t *xen_acpi_wmi_get_input_buffer(void)
++{
++    if ( cmd_info.invocation_type != XEN_ACPI_WMI_EXEC_METHOD  &&
++         cmd_info.invocation_type != XEN_ACPI_WMI_SET_OBJECT )
++        return 0;
++
++    if ( cmd_info.invocation_type == XEN_ACPI_WMI_EXEC_METHOD )
++        return &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.in_buf;
++    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_SET_OBJECT )
++        return &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.in_buf;
++
++    return 0;
++}
++
++/*
++ * xen_acpi_wmi_set_buffer_size
++ * Guest vACPI layer passes to us the size of the input buffer it is 
++ * about to transfer to ioemu  and this method stores the passed in size  
++ * apart from allocating a buffer with the provided size. 
++ */
++void xen_acpi_wmi_set_in_buffer_size(uint32_t val)
++{
++    xen_wmi_buffer_t *buffer;
++
++    buffer = xen_acpi_wmi_get_input_buffer();
++    if ( buffer == NULL )
++        return;
++
++    cmd_info.current_index = 0;
++    buffer->length = val;
++    buffer->pointer = malloc(val); 
++}
++
++/*
++ * xen_acpi_wmi_set_in_buffer
++ */
++void xen_acpi_wmi_set_in_buffer(uint8_t val)
++{
++    xen_wmi_buffer_t *buffer;
++
++    buffer = xen_acpi_wmi_get_input_buffer();
++    if ( buffer == NULL )
++        return;
++
++    if ( cmd_info.current_index >= buffer->length )
++    {
++        fprintf(logfile, 
++            "XEN WMI: Cannot write beyond allocated input buffer size!!!\n");
++        return;
++    }
++
++    ((byte *)buffer->pointer)[cmd_info.current_index] = val;
++    cmd_info.current_index++;
++}
++
++/*
++ * xen_wmi_get_output_buffer
++ */
++xen_wmi_buffer_t *xen_acpi_wmi_get_output_buffer(void)
++{
++    if ( cmd_info.invocation_type != XEN_ACPI_WMI_EXEC_METHOD &&
++         cmd_info.invocation_type != XEN_ACPI_WMI_QUERY_OBJECT &&
++         cmd_info.invocation_type != XEN_ACPI_WMI_GET_EVENT_DATA )
++    {
++        fprintf(logfile,
++            "XEN WMI: Output buffer not available for current invocation type!\n"); 
++        return 0;
++    }
++
++    if ( cmd_info.invocation_type == XEN_ACPI_WMI_EXEC_METHOD )
++        return  &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.out_buf;
++    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_QUERY_OBJECT )
++        return &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_query_obj_arg.out_buf;
++    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_GET_EVENT_DATA )
++        return  &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_event_data_arg.out_buf;
++
++    return 0;
++}
++
++/*
++ * xen_acpi_wmi_allocate_output_buffer
++ */
++void xen_acpi_wmi_allocate_output_buffer(size_t length)
++{
++    xen_wmi_buffer_t *buffer;
++
++    buffer = xen_acpi_wmi_get_output_buffer();
++    if ( buffer == NULL )
++        return;
++
++    buffer->length = (length > 0) ? length : XEN_WMI_DEFAULT_OUTPUT_BUFFER_SIZE;
++    buffer->pointer = malloc(buffer->length); 
++    memset(buffer->pointer, 0, buffer->length);
++
++    buffer->copied_length = malloc(sizeof(size_t));
++    memset(buffer->copied_length, 0, sizeof(size_t));
++}
++
++/*
++ * xen_acpi_wmi_reallocate_output_buffer
++ */
++int xen_acpi_wmi_reallocate_output_buffer(void)
++{
++    xen_wmi_buffer_t *buffer;
++
++    buffer = xen_acpi_wmi_get_output_buffer();
++    if ( buffer == NULL || buffer->copied_length == NULL || buffer->pointer == NULL )
++        return XEN_WMI_NOT_ENOUGH_MEMORY; 
++
++    /* If required length is less than allocated length,
++     * we shouldn't have failed; no point in rellocating.
++     * @TODO: Rename copied_length to something more appropriate.
++     */
++    if ( *buffer->copied_length <= buffer->length )
++        return XEN_WMI_NOT_ENOUGH_MEMORY;
++
++    free(buffer->pointer);
++    buffer->pointer = malloc(*buffer->copied_length);
++    memset(buffer->pointer, 0, *buffer->copied_length);
++    buffer->length = *buffer->copied_length;
++    return XEN_WMI_SUCCESS;
++}
++
++/*
++ * xen_acpi_wmi_free_input_buffer 
++ */
++void xen_acpi_wmi_free_input_buffer(void)
++{
++    xen_wmi_buffer_t *buffer;
++
++    buffer = xen_acpi_wmi_get_input_buffer();
++    if ( buffer == NULL )
++        return;
++
++    if ( buffer->length > 0 )
++        free(buffer->pointer);
++    buffer->length = 0;
++}
++
++#ifdef XEN_ACPI_WMI_DEBUG
++
++/*
++ * xen_acpi_wmi_print_input_buffer
++ */
++void xen_acpi_wmi_print_input_buffer(xen_wmi_buffer_t *in_buf)
++{
++    int count;
++
++    fprintf(logfile, "In buffer length - %d\n", in_buf->length);
++    fprintf(logfile, "In buffer:  ");
++    for( count = 0; count < in_buf->length; count++ )
++        fprintf(logfile, " %d,  ", ((byte *)in_buf->pointer)[count]);
++    fprintf(logfile, "\n");
++}
++
++/*
++ * xen_acpi_wmi_print_input_info
++ */
++void xen_acpi_wmi_print_input_info(void)
++{
++    int count;
++
++    fprintf(logfile, "Command invocation type - %d\n", cmd_info.invocation_type);
++    fprintf(logfile, "Invocation Data:  \n");
++    fprintf(logfile, "Guid: ");
++
++    for (count=0; count < XEN_WMI_GUID_SIZE; count++)
++        fprintf(logfile,"%d  ", cmd_info.invocation_data.guid[count]);
++
++    fprintf(logfile, "\n");
++
++    if ( cmd_info.invocation_type == XEN_ACPI_WMI_EXEC_METHOD )
++    {
++        fprintf(logfile, 
++            "Instance id - %d\n", 
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.instance);
++        fprintf(logfile,
++            "Method id - %d\n", 
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.method_id);
++        xen_acpi_wmi_print_input_buffer(
++            &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.in_buf);
++    }
++    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_QUERY_OBJECT )
++    {
++        fprintf(logfile,
++            "Instance id - %d\n", 
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_query_obj_arg.instance);
++    }
++    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_SET_OBJECT )
++    {
++        fprintf(logfile,
++            "Instance id - %d\n", 
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.instance);
++        xen_acpi_wmi_print_input_buffer(
++            &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.in_buf);
++    }
++    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_GET_EVENT_DATA )
++    {
++        fprintf(logfile,
++            "Event id - %d\n",
++            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_event_data_arg.event_id);
++    } 
++}
++
++/*
++ * xen_acpi_wmi_print_output_buffer
++ */
++void xen_acpi_wmi_print_output_buffer(void)
++{
++    int count;
++    xen_wmi_buffer_t *buffer = xen_acpi_wmi_get_output_buffer();
++
++    if ( buffer == NULL || buffer->copied_length == NULL || *buffer->copied_length == 0 )
++        return;
++
++    fprintf(logfile, "XEN WMI: Output buffer size is - %d\n",
++            *buffer->copied_length);
++    fprintf(logfile, "XEN WMI output buffer is - ");
++    for (count=0; count < *buffer->copied_length; count++)
++        fprintf(logfile," %d, ", ((byte *)buffer->pointer)[count]);
++
++    fprintf(logfile, "\n");
++}
++
++#endif /* XEN_ACPI_WMI_DEBUG */
++
++/*
++ * xen_acpi_wmi_execute
++ */
++void xen_acpi_wmi_execute(void)
++{
++    int request, ret;
++
++    if ( cmd_info.invocation_type == XEN_ACPI_WMI_UNDEFINED )
++    {
++        fprintf(logfile,
++            "Unable to execute command for the given invocation type!\n");
++        return;
++    }
++
++    switch ( cmd_info.invocation_type )
++    {
++        case XEN_ACPI_WMI_EXEC_METHOD:
++            request = XEN_WMI_IOCTL_CALL_METHOD;
++            break;
++        case XEN_ACPI_WMI_QUERY_OBJECT:
++            request = XEN_WMI_IOCTL_QUERY_OBJECT; 
++            break;
++        case XEN_ACPI_WMI_SET_OBJECT:
++            request = XEN_WMI_IOCTL_SET_OBJECT;
++            break;
++        case XEN_ACPI_WMI_GET_EVENT_DATA:
++            request = XEN_WMI_IOCTL_GET_EVENT_DATA;
++            break;
++        default:
++            fprintf(logfile,
++                "Unable to execute command for the given invocation type!\n");
++            return;
++    } 
++
++    xen_acpi_wmi_allocate_output_buffer(0);
++#ifdef XEN_ACPI_WMI_DEBUG
++    fprintf(logfile, "XEN WMI Invoking ioctl - %d\n", cmd_info.invocation_type);
++    xen_acpi_wmi_print_input_info();
++#endif
++    ret = ioctl(xen_wmi_device, request, &cmd_info.invocation_data);
++    if ( ret == XEN_WMI_BUFFER_TOO_SMALL )
++    {
++        if ( xen_acpi_wmi_reallocate_output_buffer() == XEN_WMI_SUCCESS )
++            ret = ioctl(xen_wmi_device, request, &cmd_info.invocation_data);
++    }
++
++    if ( ret != XEN_WMI_SUCCESS )
++        fprintf(logfile, "Xen WMI ioctl failed with error - %d\n", ret);
++
++#ifdef XEN_ACPI_WMI_DEBUG
++    xen_acpi_wmi_print_output_buffer();
++#endif
++
++    xen_acpi_wmi_free_input_buffer();
++}
++
++/*
++ * xen_acpi_wmi_set_event_id
++ */
++void xen_acpi_wmi_set_event_id(uint8_t event_id)
++{
++    if ( cmd_info.invocation_type != XEN_ACPI_WMI_GET_EVENT_DATA )
++    {
++        fprintf(logfile, 
++            "XEN WMI: Request to set event ID with incorrect invocation type!!!\n");        
++        return;
++    }
++
++    cmd_info.invocation_data.xen_wmi_arg.xen_wmi_event_data_arg.event_id = event_id;
++}
++
++/*
++ * xen_acpi_wmi_cmd_port_read
++ */
++static uint32_t xen_acpi_wmi_cmd_port_read(void *opaque, uint32_t addr)
++{
++#ifdef XEN_ACPI_WMI_DEBUG_EXT
++    fprintf(logfile, "XEN WMI: In cmd port read - %d\n",
++        cmd_info.cmd_type);
++#endif
++    return cmd_info.cmd_type;
++}   
++
++/*
++ * xen_acpi_wmi_cmd_port_write
++ */
++static void xen_acpi_wmi_cmd_port_write(void *opaque, uint32_t addr, uint32_t val)
++{
++#ifdef XEN_ACPI_WMI_DEBUG_EXT
++    fprintf(logfile, "XEN WMI: In cmd port write - %d\n", val);
++#endif
++    cmd_info.cmd_type = val;
++    if ( val < XEN_ACPI_WMI_CMD_INIT || val >= XEN_ACPI_WMI_CMD_UNDEFINED )
++    {
++        fprintf(logfile,"XEN WMI: Unknown xen acpi wmi command - %d\n", val);
++        cmd_info.invocation_type = XEN_ACPI_WMI_UNDEFINED;
++        cmd_info.current_index = 0;
++        return; 
++    } 
++
++    if ( val == XEN_ACPI_WMI_CMD_EXECUTE )
++        xen_acpi_wmi_execute();
++}
++
++/*
++ * xen_acpi_wmi_data_port_readb
++ */
++static uint32_t xen_acpi_wmi_data_port_readb(void *opaque, uint32_t addr)
++{
++    xen_wmi_buffer_t *buffer;
++    byte ret;
++
++    if ( cmd_info.cmd_type == XEN_ACPI_WMI_CMD_OUT_BUFFER )
++    {
++        buffer = xen_acpi_wmi_get_output_buffer();
++        if ( buffer == NULL || buffer->copied_length == NULL )
++            return 0x0;
++
++        if ( *buffer->copied_length == 0 )
++            return 0x0;
++
++        if ( cmd_info.current_index >= *buffer->copied_length )
++        {
++            fprintf(logfile, 
++                "XEN WMI: Output buffer index overflow. Current - %d Max - %d\n",
++                 cmd_info.current_index, *buffer->copied_length);
++            cmd_info.cmd_type = XEN_ACPI_WMI_CMD_UNDEFINED; 
++            return 0x0;
++        }
++
++        ret = ((byte*)buffer->pointer)[cmd_info.current_index];
++        if ( cmd_info.current_index == buffer->length-1 )
++        {
++            /* @TODO: We expect that the firmware would read all of
++             * the output buffer before releasing it.  This
++             * could result in a leak if the firmware chooses
++             * to ignore the return buffer. It might make sense to
++             * introduce a cleanup command. */ 
++            cmd_info.cmd_type = XEN_ACPI_WMI_CMD_UNDEFINED; 
++            buffer->length = 0;
++            free(buffer->pointer);
++            buffer->pointer = NULL;
++            free(buffer->copied_length);
++            buffer->copied_length = NULL;
++        }
++
++#ifdef XEN_ACPI_WMI_DEBUG_EXT 
++        fprintf(logfile, "XEN WMI: Data port read returned - %d\n", ret);
++#endif
++        cmd_info.current_index++;
++        return ret;
++    } 
++
++    fprintf(logfile, "XEN WMI: Data port read byte.  Shouldn't be here!!!\n");
++    return 0x0;
++}  
++
++/*
++ * xen_acpi_wmi_data_port_writeb
++ */
++static void xen_acpi_wmi_data_port_writeb(void *opaque, uint32_t addr, uint32_t val)
++{
++#ifdef XEN_ACPI_WMI_DEBUG_EXT
++    fprintf(logfile, "XEN WMI: In data port write byte - %d\n", val);
++#endif
++
++    switch( cmd_info.cmd_type )
++    {
++        case XEN_ACPI_WMI_CMD_INIT:
++            cmd_info.invocation_type = val;
++            cmd_info.current_index = 0;
++            memset(&cmd_info.invocation_data, 0, sizeof(cmd_info.invocation_data));
++            break;
++        case XEN_ACPI_WMI_CMD_GUID:
++            xen_acpi_wmi_set_guid(val);
++            break;
++        case XEN_ACPI_WMI_CMD_IN_BUFFER:
++            xen_acpi_wmi_set_in_buffer(val);
++            break;
++        case XEN_ACPI_WMI_CMD_EVENT_ID:
++            xen_acpi_wmi_set_event_id(val);
++            break;
++        default:
++            fprintf(logfile, 
++                "XEN WMI: Attempting to write to data(byte) port with incompatible cmd type %d\n",    
++                    cmd_info.cmd_type);
++             break;
++    }    
++}
++
++/*
++ * xen_acpi_wmi_data_port_readl
++ */
++static uint32_t xen_acpi_wmi_data_port_readl(void *opaque, uint32_t addr)
++{
++    xen_wmi_buffer_t *buffer;
++
++    if ( cmd_info.cmd_type == XEN_ACPI_WMI_CMD_OUT_BUFFER_SIZE )
++    {
++        buffer = xen_acpi_wmi_get_output_buffer();
++        if ( buffer == NULL || buffer->copied_length == NULL )
++            return 0x0;
++
++        if (*buffer->copied_length == 0 )
++            return 0x0;
++
++        cmd_info.current_index = 0;
++#ifdef XEN_ACPI_WMI_DEBUG_EXT
++       fprintf(logfile, "XEN WMI: Output buffer length is - %d\n", *buffer->copied_length);
++#endif
++        return *buffer->copied_length;
++    }
++
++    fprintf(logfile, "XEN WMI: Data port read long.  Shouldn't be here!!!\n");
++    return 0x0;
++} 
++
++/*
++ * xen_acpi_wmi_data_port_writel
++ */
++static void xen_acpi_wmi_data_port_writel(void *opaque, uint32_t addr, uint32_t val)
++{
++#ifdef XEN_ACPI_WMI_DEBUG_EXT
++    fprintf(logfile, "XEN WMI: In data port write long - %d\n", val);
++#endif
++
++    switch( cmd_info.cmd_type )
++    {
++        case XEN_ACPI_WMI_CMD_OBJ_INSTANCE:
++            xen_acpi_wmi_set_cmd_instance(val);
++            break;
++        case XEN_ACPI_WMI_CMD_METHOD_ID:
++            xen_acpi_wmi_set_method_id(val);
++            break;
++        case XEN_ACPI_WMI_CMD_IN_BUFFER_SIZE:
++            xen_acpi_wmi_set_in_buffer_size(val);
++            break;
++        default:
++            fprintf(logfile,
++                "XEN WMI: Attempting to write to data(long) port with incompatible cmd type %d\n",
++                    cmd_info.cmd_type);
++             break;
++    }
++}
++
++/*
++ * xen_acpi_wmi_init
++ */
++void xen_acpi_wmi_init(PCIDevice *device)
++{
++    char dev_name[64];
++    char *oem_buffer;
++
++    cmd_info.invocation_type = XEN_ACPI_WMI_UNDEFINED;
++    cmd_info.current_index = 0;
++
++    oem_buffer = xenstore_device_model_read(domid, "oem_features", NULL);
++    if ( oem_buffer == NULL )
++    {
++#ifdef XEN_ACPI_WMI_DEBUG 
++        fprintf(logfile,"OEM value add disabled!\n");
++#endif
++        return;
++    }
++
++    sprintf(dev_name, "/dev/%s", XEN_WMI_DEVICE_NAME);
++    xen_wmi_device = open(dev_name, 0);
++    if ( xen_wmi_device < 0 )
++    {
++        fprintf(logfile, 
++            "XEN WMI: Unable to open device - %s\n", XEN_WMI_DEVICE_NAME);
++        return;
++    }
++
++    register_ioport_read(XEN_ACPI_WMI_CMD_PORT, 1, 1, xen_acpi_wmi_cmd_port_read, device);   
++    register_ioport_write(XEN_ACPI_WMI_CMD_PORT, 1, 1, xen_acpi_wmi_cmd_port_write, device); 
++    register_ioport_read(XEN_ACPI_WMI_DATA_PORTB, 1, 1, xen_acpi_wmi_data_port_readb, device);
++    register_ioport_write(XEN_ACPI_WMI_DATA_PORTB, 1, 1, xen_acpi_wmi_data_port_writeb, device);
++    register_ioport_read(XEN_ACPI_WMI_DATA_PORTL, 4, 4, xen_acpi_wmi_data_port_readl, device);
++    register_ioport_write(XEN_ACPI_WMI_DATA_PORTL, 4, 4, xen_acpi_wmi_data_port_writel, device);
++
++    xenstore_register_for_oem_events();
++#ifdef XEN_ACPI_WMI_DEBUG
++    fprintf(logfile, "XEN WMI:  XEN ACPI WMI registration succeeded!!!\n");
++#endif
++}
++
++/*
++ * xen_acpi_wmi_cleanup(void)
++ */
++void xen_acpi_wmi_cleanup(void)
++{
++    if ( xen_wmi_device > 0 )
++        close(xen_wmi_device);
++}
++
++#else
++
++void xen_acpi_wmi_init(PCIDevice *device) { }
++void xen_acpi_wmi_cleanup(void) { }
++
++#endif /* CONFIG_NO_XEN_ACPI_WMI */
++ 
+diff --git a/hw/xen_acpi_wmi.h b/hw/xen_acpi_wmi.h
+new file mode 100644
+index 0000000..df289f2
+--- /dev/null
++++ b/hw/xen_acpi_wmi.h
+@@ -0,0 +1,89 @@
++/*
++ * xen_acpi_wmi.h
++ *
++ * Copyright (c) 2009  Kamala Narasimhan
++ * Copyright (c) 2009  Citrix Systems, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef _XEN_ACPI_WMI_H
++#define _XEN_ACPI_WMI_H
++
++#ifdef CONFIG_STUBDOM
++#define CONFIG_NO_XEN_ACPI_WMI
++#endif
++
++#include "acpi-wmi.h"
++
++#define XEN_ACPI_WMI_CMD_PORT   0x96
++#define XEN_ACPI_WMI_DATA_PORTB 0x98
++#define XEN_ACPI_WMI_DATA_PORTL 0x9A
++
++/* Values written to WMI command port */
++enum XEN_ACPI_WMI_COMMAND { XEN_ACPI_WMI_CMD_INIT = 100,
++                            XEN_ACPI_WMI_CMD_GUID,
++                            XEN_ACPI_WMI_CMD_OBJ_INSTANCE,
++                            XEN_ACPI_WMI_CMD_METHOD_ID,
++                            XEN_ACPI_WMI_CMD_IN_BUFFER,
++                            XEN_ACPI_WMI_CMD_IN_BUFFER_SIZE, 
++                            XEN_ACPI_WMI_CMD_EXECUTE,
++                            XEN_ACPI_WMI_CMD_OUT_BUFFER,
++                            XEN_ACPI_WMI_CMD_OUT_BUFFER_SIZE, 
++                            XEN_ACPI_WMI_CMD_EVENT_ID,
++                            XEN_ACPI_WMI_CMD_UNDEFINED }; 
++
++enum XEN_ACPI_WMI_OBJ_INVOCATION_TYPE { XEN_ACPI_WMI_EXEC_METHOD = 1,
++                                        XEN_ACPI_WMI_QUERY_OBJECT,
++                                        XEN_ACPI_WMI_SET_OBJECT,
++                                        XEN_ACPI_WMI_GET_EVENT_DATA,
++                                        XEN_ACPI_WMI_UNDEFINED };
++
++typedef struct xen_acpi_wmi_cmd_info {
++    enum XEN_ACPI_WMI_COMMAND cmd_type;
++    enum XEN_ACPI_WMI_OBJ_INVOCATION_TYPE invocation_type;
++    xen_wmi_obj_invocation_data_t invocation_data;
++    uint32_t current_index;
++} xen_acpi_wmi_cmd_info_t; 
++
++void xen_acpi_wmi_init(PCIDevice *device);
++void xen_acpi_wmi_cleanup(void);
++
++#ifndef CONFIG_NO_XEN_ACPI_WMI
++
++void xen_acpi_wmi_set_guid(uint8_t val);
++void xen_acpi_wmi_set_cmd_instance(uint32_t val);
++void xen_acpi_wmi_set_method_id(uint32_t val);
++xen_wmi_buffer_t *xen_acpi_wmi_get_input_buffer(void);
++void xen_acpi_wmi_set_in_buffer_size(uint32_t val);
++void xen_acpi_wmi_set_in_buffer(uint8_t val);
++xen_wmi_buffer_t *xen_acpi_wmi_get_output_buffer(void);
++void xen_acpi_wmi_allocate_output_buffer(size_t length);
++int xen_acpi_wmi_reallocate_output_buffer(void);
++void xen_acpi_wmi_free_input_buffer(void);
++void xen_acpi_wmi_execute(void);
++void xen_acpi_wmi_set_event_id(uint8_t event_id);
++static uint32_t xen_acpi_wmi_cmd_port_read(void *opaque, uint32_t addr);
++static void xen_acpi_wmi_cmd_port_write(void *opaque, uint32_t addr, uint32_t val);
++static uint32_t xen_acpi_wmi_data_port_readb(void *opaque, uint32_t addr);
++static void xen_acpi_wmi_data_port_writeb(void *opaque, uint32_t addr, uint32_t val);
++static uint32_t xen_acpi_wmi_data_port_readl(void *opaque, uint32_t addr);
++static void xen_acpi_wmi_data_port_writel(void *opaque, uint32_t addr, uint32_t val);
++
++#endif
++
++#endif /* _XEN_ACPI_WMI_H */
++
++
+diff --git a/qemu-xen.h b/qemu-xen.h
+index 8c1debd..60ee108 100644
+--- a/qemu-xen.h
++++ b/qemu-xen.h
+@@ -128,6 +128,7 @@ int xenstore_refresh_battery_status(void);
+ void xenstore_register_for_pm_events(void);
+ int xenstore_read_ac_adapter_state(void);
+ int xenstore_read_lid_state(void);
++void xenstore_register_for_oem_events(void);
+ int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
+                                          uint32_t build_nr);
+diff --git a/xen-hooks.mak b/xen-hooks.mak
+index d2f09fb..03d670e 100644
+--- a/xen-hooks.mak
++++ b/xen-hooks.mak
+@@ -35,6 +35,7 @@ OBJS += exec-dm.o
+ OBJS += pci_emulation.o
+ OBJS += helper2.o
+ OBJS += battery_mgmt.o
++OBJS += xen_acpi_wmi.o
+ ifdef CONFIG_STUBDOM
+ CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
+diff --git a/xenstore.c b/xenstore.c
+index 6f5b073..7cd4d54 100644
+--- a/xenstore.c
++++ b/xenstore.c
+@@ -1011,6 +1011,11 @@ void xenstore_process_event(void *opaque)
+         goto out;
+     }
++    if (!strcmp(vec[XS_WATCH_TOKEN], "oemevt")) {
++        acpi_oem_event();
++        goto out;
++    }
++
+     if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
+         strlen(vec[XS_WATCH_TOKEN]) != 3)
+         goto out;
+@@ -1467,6 +1472,11 @@ void xenstore_register_for_pm_events(void)
+    xs_watch(xsh, "/pm/events/sleepbuttonpressed", "slpbuttonpressedevt");
+ }
++void xenstore_register_for_oem_events(void)
++{
++   xs_watch(xsh, "/oem/event", "oemevt");
++}
++
+ int xenstore_read_ac_adapter_state(void)
+ {
+     return xenstore_extended_power_mgmt_read_int("ac_adapter", 1);
diff --git a/master/series b/master/series
new file mode 100644 (file)
index 0000000..5f501b9
--- /dev/null
@@ -0,0 +1,15 @@
+ioemu-compil
+xenstore-watch-callbacks
+dm-ready
+
+battery-management
+oem-features
+thermal-management
+fix-build-warnings
+
+
+vga-passthrough
+dom0-driver
+intel
+use-vga-cmdline
+disable-aio
diff --git a/master/status b/master/status
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/master/thermal-management b/master/thermal-management
new file mode 100644 (file)
index 0000000..47e74bc
--- /dev/null
@@ -0,0 +1,208 @@
+diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
+index cf214a4..edede92 100644
+--- a/hw/piix4acpi.c
++++ b/hw/piix4acpi.c
+@@ -30,6 +30,7 @@
+ #include "qemu-xen.h"
+ #include "battery_mgmt.h"
+ #include "xen_acpi_wmi.h"
++#include "thermal_mgmt.h"
+ #include <xen/hvm/ioreq.h>
+ #include <xen/hvm/params.h>
+@@ -198,6 +199,7 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
+     battery_mgmt_init(pci_dev);
+     xen_acpi_wmi_init(pci_dev);
++    thermal_mgmt_init(pci_dev);
+ }
+ static inline int test_bit(uint8_t *map, int bit)
+diff --git a/hw/thermal_mgmt.c b/hw/thermal_mgmt.c
+new file mode 100644
+index 0000000..649b622
+--- /dev/null
++++ b/hw/thermal_mgmt.c
+@@ -0,0 +1,79 @@
++/*
++ * thermal_mgmt.c
++ *
++ * Copyright (c) 2009  Kamala Narasimhan
++ * Copyright (c) 2009  Citrix Systems, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++/* Implementation Notes:  Following provides a minimal thermal zone implementation for
++ * HVM guest.  The vACPI layer exposes a single thermal zone with critical and current
++ * temperature objects which when invoked relies on the below to return back the critical
++ * and current temperature provided by the underlying firmware.
++ */
++
++#include "hw.h"
++#include "pc.h"
++#include "qemu-xen.h"
++#include "isa.h" 
++#include "thermal_mgmt.h"
++
++#ifndef CONFIG_NO_THERMAL_MGMT
++
++/* #define THERMAL_MGMT_DBG */
++
++extern FILE *logfile;
++
++static uint32_t thermal_port_1_readw(void *opaque, uint32_t addr)
++{
++    int current_temp;
++
++    xenstore_refresh_thermal_info();
++    current_temp = xenstore_read_current_temperature();
++#ifdef THERMAL_MGMT_DBG
++    fprintf(logfile, "Current temperature - %d\n", current_temp);
++#endif
++    return current_temp;
++}
++
++static uint32_t thermal_port_2_readw(void *opaque, uint32_t addr)
++{
++    int critical_temp;
++
++    xenstore_refresh_thermal_info();
++    critical_temp = xenstore_read_critical_temperature();
++#ifdef THERMAL_MGMT_DBG
++    fprintf(logfile, "Critical trip point temperature - %d\n", critical_temp);
++#endif
++    return critical_temp;
++}
++
++void thermal_mgmt_init(PCIDevice *device)
++{
++#ifdef THERMAL_MGMT_DBG
++    fprintf(logfile, "In thermal management init\n");
++#endif
++
++    register_ioport_read(THERMAL_PORT_1, 1, 2, thermal_port_1_readw, device);
++    register_ioport_read(THERMAL_PORT_2, 1, 2, thermal_port_2_readw, device);
++}
++
++#else
++
++void thermal_mgmt_init(PCIDevice *device) { }
++
++#endif
++
+diff --git a/hw/thermal_mgmt.h b/hw/thermal_mgmt.h
+new file mode 100644
+index 0000000..d83273b
+--- /dev/null
++++ b/hw/thermal_mgmt.h
+@@ -0,0 +1,35 @@
++/*
++ * thermal_mgmt.h
++ *
++ * Copyright (c) 2009  Kamala Narasimhan
++ * Copyright (c) 2009  Citrix Systems, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef _THERMAL_MGMT_H
++#define _THERMAL_MGMT_H
++
++#ifdef CONFIG_STUBDOM
++#define CONFIG_NO_THERMAL_MGMT
++#endif
++
++#define THERMAL_PORT_1 0x90
++#define THERMAL_PORT_2 0x92
++
++void thermal_mgmt_init(PCIDevice *device);
++
++#endif
++
+diff --git a/qemu-xen.h b/qemu-xen.h
+index 60ee108..0cc5dd8 100644
+--- a/qemu-xen.h
++++ b/qemu-xen.h
+@@ -125,9 +125,12 @@ char *xenstore_device_model_read(int domid, const char *key, unsigned int *len);
+ int xenstore_extended_power_mgmt_read_int(const char *key, int default_value);
+ char *xenstore_read_battery_data(int battery_status);
+ int xenstore_refresh_battery_status(void);
++int xenstore_refresh_thermal_info(void);
+ void xenstore_register_for_pm_events(void);
+ int xenstore_read_ac_adapter_state(void);
+ int xenstore_read_lid_state(void);
++int xenstore_read_current_temperature(void);
++int xenstore_read_critical_temperature(void);
+ void xenstore_register_for_oem_events(void);
+ int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
+                                          uint32_t build_nr);
+diff --git a/xen-hooks.mak b/xen-hooks.mak
+index 03d670e..7c94718 100644
+--- a/xen-hooks.mak
++++ b/xen-hooks.mak
+@@ -36,6 +36,7 @@ OBJS += pci_emulation.o
+ OBJS += helper2.o
+ OBJS += battery_mgmt.o
+ OBJS += xen_acpi_wmi.o
++OBJS += thermal_mgmt.o
+ ifdef CONFIG_STUBDOM
+ CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
+diff --git a/xenstore.c b/xenstore.c
+index 7cd4d54..01afcf0 100644
+--- a/xenstore.c
++++ b/xenstore.c
+@@ -1464,6 +1464,11 @@ int xenstore_refresh_battery_status(void)
+     return xenstore_extended_power_mgmt_event_trigger("refreshbatterystatus", "1");
+ }
++int xenstore_refresh_thermal_info(void)
++{
++    return xenstore_extended_power_mgmt_event_trigger("refreshthermalinfo", "1");
++}
++
+ void xenstore_register_for_pm_events(void)
+ {
+    xs_watch(xsh, "/pm/events/acadapterstatechanged", "acadapterstatechangeevt");
+@@ -1487,6 +1492,16 @@ int xenstore_read_lid_state(void)
+     return xenstore_extended_power_mgmt_read_int("lid_state", 1);
+ }
++int xenstore_read_current_temperature(void)
++{
++    return xenstore_extended_power_mgmt_read_int("current_temperature", 0);
++}
++
++int xenstore_read_critical_temperature(void)
++{
++    return xenstore_extended_power_mgmt_read_int("critical_temperature", 100);
++}
++
+ /*
+  * Create a store entry for a device (e.g., monitor, serial/parallel lines).
+  * The entry is <domain-path><storeString>/tty and the value is the name
diff --git a/master/use-vga-cmdline b/master/use-vga-cmdline
new file mode 100644 (file)
index 0000000..4006998
--- /dev/null
@@ -0,0 +1,49 @@
+diff --git a/vl.c b/vl.c
+index ae32f82..05d12ae 100644
+--- a/vl.c
++++ b/vl.c
+@@ -4598,24 +4598,20 @@ static void select_soundhw (const char *optarg)
+ static void select_vgahw (const char *p)
+ {
+     const char *opts;
++    std_vga_enabled = 0;
++    cirrus_vga_enabled = 0;
++    vmsvga_enabled = 0;
+-    if (strstart(p, "std", &opts)) {
++    if (strstart(p, "std", &opts)) 
+         std_vga_enabled = 1;
+-        cirrus_vga_enabled = 0;
+-        vmsvga_enabled = 0;
+-    } else if (strstart(p, "cirrus", &opts)) {
++    else if (strstart(p, "cirrus", &opts)) 
+         cirrus_vga_enabled = 1;
+-        std_vga_enabled = 0;
+-        vmsvga_enabled = 0;
+-    } else if (strstart(p, "vmware", &opts)) {
+-        cirrus_vga_enabled = 0;
+-        std_vga_enabled = 0;
++    else if (strstart(p, "vmware", &opts)) 
+         vmsvga_enabled = 1;
+-    } else if (strstart(p, "none", &opts)) {
+-        cirrus_vga_enabled = 0;
+-        std_vga_enabled = 0;
+-        vmsvga_enabled = 0;
+-    } else {
++    else if (strstart(p, "passthrough", &opts))
++        vga_passthrough = 1;
++    else if (!strstart(p, "none", &opts)) 
++    {
+     invalid_vga:
+         fprintf(stderr, "Unknown vga type: %s\n", p);
+         exit(1);
+@@ -5272,6 +5268,9 @@ int main(int argc, char **argv, char **envp)
+                 break;
+             case QEMU_OPTION_vga_passthrough:
+                 vga_passthrough = 1;
++                std_vga_enabled = 0;
++                cirrus_vga_enabled = 0;
++                vmsvga_enabled = 0;
+                 break;
+             case QEMU_OPTION_dom0_input:
+                 dom0_input = optarg;
diff --git a/master/vga-passthrough b/master/vga-passthrough
new file mode 100644 (file)
index 0000000..d2adba9
--- /dev/null
@@ -0,0 +1,235 @@
+diff --git a/hw/pass-through.c b/hw/pass-through.c
+index 6a53137..3420e95 100644
+--- a/hw/pass-through.c
++++ b/hw/pass-through.c
+@@ -90,6 +90,8 @@
+ #include "qemu-xen.h"
+ #include <unistd.h>
++extern int vga_passthrough;
++
+ struct php_dev {
+     struct pt_dev *pt_dev;
+     uint8_t valid;
+@@ -1573,10 +1575,11 @@ static int pt_dev_is_virtfn(struct pci_dev *dev)
+ static int pt_register_regions(struct pt_dev *assigned_device)
+ {
+-    int i = 0;
++    int i = 0, ret = 0;
+     uint32_t bar_data = 0;
+     struct pci_dev *pci_dev = assigned_device->pci_dev;
+     PCIDevice *d = &assigned_device->dev;
++    uint16_t vendor_id, class;
+     /* Register PIO/MMIO BARs */
+     for ( i = 0; i < PCI_BAR_ENTRIES; i++ )
+@@ -1632,6 +1635,28 @@ static int pt_register_regions(struct pt_dev *assigned_device)
+             (uint32_t)(pci_dev->rom_size), (uint32_t)(pci_dev->rom_base_addr));
+     }
++    /* Map legacy ioport and iomem, for specific devices */
++    vendor_id = pci_read_word(pci_dev, 0x00);
++    class = pci_read_word(pci_dev, 0x0a);
++
++    PT_LOG("Real device vendor_id=0x%x class=0x%x\n", vendor_id, class);
++    if ( vga_passthrough && class == 0x0300 )
++    {
++        PT_LOG("add an intel graphic card\n");
++
++        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, 0x3B0, 0xb,
++                                      DPCI_ADD_MAPPING);
++        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, 0x3C0, 32,
++                                      DPCI_ADD_MAPPING);
++        ret |= xc_domain_memory_mapping(xc_handle, domid, 0xa0, 0xa0, 32,
++                                       DPCI_ADD_MAPPING);
++        if ( ret != 0 )
++        {
++            PT_LOG("legacy mapping failed !\n");
++            return ret;
++        }
++    }
++
+     return 0;
+ }
+@@ -1640,6 +1665,7 @@ static void pt_unregister_regions(struct pt_dev *assigned_device)
+     int i, type, ret;
+     uint32_t e_size;
+     PCIDevice *d = (PCIDevice*)assigned_device;
++    uint16_t class, vendor_id;
+     for ( i = 0; i < PCI_NUM_REGIONS; i++ )
+     {
+@@ -1681,6 +1707,26 @@ static void pt_unregister_regions(struct pt_dev *assigned_device)
+     }
++    /* unmap legacy ioport and iomem, for specific devices */
++    vendor_id = pci_read_word(assigned_device->pci_dev, 0x00);
++    class = pci_read_word(assigned_device->pci_dev, 0x0a);
++
++    PT_LOG("Real device vendor_id=0x%x class=0x%x\n", vendor_id, class);
++    if ( vga_passthrough && class == 0x0300 )
++    {
++        PT_LOG("remove an intel graphic card\n");
++
++        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, 0x3B0, 0xb,
++                                      DPCI_REMOVE_MAPPING);
++        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, 0x3C0, 32,
++                                       DPCI_REMOVE_MAPPING);
++        ret |= xc_domain_memory_mapping(xc_handle, domid, 0xa0, 0xa0, 32,
++                                        DPCI_REMOVE_MAPPING);
++        if ( ret != 0 )
++        {
++            PT_LOG("legacy unmapping failed !\n");
++        }
++    }
+ }
+ static uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
+@@ -4084,3 +4130,41 @@ err:
+     return status;
+ }
++u8      pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr)
++{
++    struct pci_dev*     pci_dev;
++    u8                  val;
++
++    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
++    if (!pci_dev)
++        return 0;
++    val = pci_read_byte(pci_dev, addr);
++    pci_free_dev(pci_dev);
++    return val;
++}
++
++u16     pt_pci_host_read_word(int bus, int dev, int fn, u32 addr)
++{
++    struct pci_dev*     pci_dev;
++    u16                 val;
++
++    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
++    if (!pci_dev)
++        return 0;
++    val = pci_read_word(pci_dev, addr);
++    pci_free_dev(pci_dev);
++    return val;
++}
++
++u32     pt_pci_host_read_long(int bus, int dev, int fn, u32 addr)
++{
++    struct pci_dev*     pci_dev;
++    u32                 val;
++
++    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
++    if (!pci_dev)
++        return 0;
++    val = pci_read_long(pci_dev, addr);
++    pci_free_dev(pci_dev);
++    return val;
++}
+diff --git a/hw/pass-through.h b/hw/pass-through.h
+index a503e80..1752e8d 100644
+--- a/hw/pass-through.h
++++ b/hw/pass-through.h
+@@ -392,5 +392,9 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base)
+     return base & PCI_ADDR_MEM_MASK;
+ }
++u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr);
++u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr);
++u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr);
++
+ #endif /* __PASSTHROUGH_H__ */
+diff --git a/hw/pci.c b/hw/pci.c
+index d7c516e..b2f4d43 100644
+--- a/hw/pci.c
++++ b/hw/pci.c
+@@ -28,11 +28,14 @@
+ #include "virtio-net.h"
+ #include "sysemu.h"
++#include "pass-through.h"
+ #include "exec-all.h"
+ #include "qemu-xen.h"
+ //#define DEBUG_PCI
++extern int vga_passthrough;
++
+ struct PCIBus {
+     int bus_num;
+     int devfn_min;
+@@ -611,7 +614,30 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
+         goto the_end;
+     }
+     config_addr = addr & 0xff;
+-    val = pci_dev->config_read(pci_dev, config_addr, len);
++    if (vga_passthrough && pci_dev->devfn == 0x00) //Host Bridge
++    {
++      val = pci_dev->config_read(pci_dev, config_addr, len);
++
++        if (config_addr == 0x52) // GMCH
++            val = pt_pci_host_read_word(0, 0, 0, 0x52);
++        if (config_addr == 0x02) // Device ID
++      {
++          if (len == 2)
++              val = pt_pci_host_read_word(0, 0, 0, 0x02);
++      }
++      if (config_addr == 0x0)
++      {
++          if (len == 2)
++              val = pt_pci_host_read_word(0, 0, 0, 0x00);
++          else if (len == 4)
++              val = pt_pci_host_read_long(0, 0, 0, 0x00);
++      }
++    }
++    else if (vga_passthrough && pci_dev->devfn == 0x10 && // intel graphic card
++          config_addr == 0xfc) // OpRegion address
++      val = 0; // force to fall back to SMI mode
++    else
++      val = pci_dev->config_read(pci_dev, config_addr, len);
+ #if defined(DEBUG_PCI)
+     printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
+            pci_dev->name, config_addr, val, len);
+diff --git a/vl.c b/vl.c
+index b273c75..e519705 100644
+--- a/vl.c
++++ b/vl.c
+@@ -233,6 +233,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
+ #ifdef TARGET_I386
+ int win2k_install_hack = 0;
+ int rtc_td_hack = 0;
++int vga_passthrough = 0;
+ #endif
+ int usb_enabled = 0;
+ int smp_cpus = 1;
+@@ -4275,6 +4276,7 @@ enum {
+     QEMU_OPTION_domainname,
+     QEMU_OPTION_acpi,
+     QEMU_OPTION_vcpus,
++    QEMU_OPTION_vga_passthrough,
+     /* Debug/Expert options: */
+     QEMU_OPTION_serial,
+@@ -4448,6 +4450,7 @@ static const QEMUOption qemu_options[] = {
+     { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
+     { "vncunused", 0, QEMU_OPTION_vncunused },
+     { "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
++    { "vga-passthrough", 0, QEMU_OPTION_vga_passthrough },
+ #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
+     { "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
+     { "xen-create", 0, QEMU_OPTION_xen_create },
+@@ -5281,6 +5284,9 @@ int main(int argc, char **argv, char **envp)
+             case QEMU_OPTION_disable_opengl:
+                 opengl_enabled = 0;
+                 break;
++            case QEMU_OPTION_vga_passthrough:
++                vga_passthrough = 1;
++                break;
+             case QEMU_OPTION_direct_pci:
+                direct_pci = optarg;
+                 break;
diff --git a/master/xenstore-watch-callbacks b/master/xenstore-watch-callbacks
new file mode 100644 (file)
index 0000000..916f5f4
--- /dev/null
@@ -0,0 +1,244 @@
+Improved the way to do xenstore watchs.
+
+diff --git a/qemu-xen.h b/qemu-xen.h
+index ec4cd94..9f7feda 100644
+--- a/qemu-xen.h
++++ b/qemu-xen.h
+@@ -78,6 +78,19 @@ int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
+                                              const char *inst,
+                                              const char *token);
++typedef void (*xenstore_callback) (const char *path, void *opaque);
++int xenstore_watch_screenshot_node(DisplayState *ds);
++int xenstore_watch_new_callback(const char *path, xenstore_callback fptr, void *opaque);
++
++char *xenstore_dom_read(int domid, const char *key, unsigned int *len);
++int xenstore_dom_write(int domid, const char *key, const char *value);
++void xenstore_dom_watch(int domid, const char *key, xenstore_callback ftp, void *opaque);
++void xenstore_dom_chmod(int domid, const char *key, const char *perms);
++
++char *xenstore_read(const char *path);
++int xenstore_write(const char *path, const char *val);
++
++
+  /* `danger' means that this parameter, variable or function refers to
+   * an area of xenstore which is writeable by the guest and thus must
+   * not be trusted by qemu code.  For variables containing xenstore
+@@ -92,7 +105,7 @@ int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
+ int xenstore_vm_write(int domid, const char *key, const char *val);
+ char *xenstore_vm_read(int domid, const char *key, unsigned int *len);
+-char *xenstore_device_model_read(int domid, char *key, unsigned int *len);
++char *xenstore_device_model_read(int domid, const char *key, unsigned int *len);
+ char *xenstore_read_battery_data(int battery_status);
+ int xenstore_refresh_battery_status(void);
+ int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
+diff --git a/xenstore.c b/xenstore.c
+index ef7b5f3..ea39dce 100644
+--- a/xenstore.c
++++ b/xenstore.c
+@@ -37,6 +37,52 @@ static QEMUTimer *insert_timer = NULL;
+ #define UWAIT_MAX (30*1000000) /* thirty seconds */
+ #define UWAIT     (100000)     /* 1/10th second  */
++struct xenstore_watch_cb_t
++{
++    char                *path;
++    xenstore_callback   cb;
++    void                *opaque;
++};
++
++static struct xenstore_watch_cb_t *xenstore_watch_callbacks = NULL;
++
++int xenstore_watch_new_callback(const char          *path,
++                                xenstore_callback   fptr,
++                                void                *opaque)
++{
++    int         i = 0, ret = 0;
++
++    ret = xs_watch(xsh, path, path);
++    if (ret == 0)
++        return 0;
++
++    if (!xenstore_watch_callbacks)
++    {
++        xenstore_watch_callbacks = malloc(sizeof (struct xenstore_watch_cb_t));
++        xenstore_watch_callbacks[0].path = NULL;
++    }
++
++    while (xenstore_watch_callbacks[i].path)
++    {
++      if (!strcmp(xenstore_watch_callbacks[i].path, path))
++      {
++          xenstore_watch_callbacks[i].cb = fptr;
++          xenstore_watch_callbacks[i].opaque = opaque;
++          return ret;
++      }
++        i++;
++    }
++
++    xenstore_watch_callbacks = realloc(xenstore_watch_callbacks,
++                                       (i + 2) * sizeof (struct xenstore_watch_cb_t));
++    xenstore_watch_callbacks[i].path = strdup(path);
++    xenstore_watch_callbacks[i].cb = fptr;
++    xenstore_watch_callbacks[i].opaque = opaque;
++    xenstore_watch_callbacks[i + 1].path = NULL;
++    return ret;
++}
++
++
+ static int pasprintf(char **buf, const char *fmt, ...)
+ {
+     va_list ap;
+@@ -904,12 +950,18 @@ void xenstore_record_dm_state(const char *state)
+ void xenstore_process_event(void *opaque)
+ {
+     char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
+-    unsigned int len, num, hd_index;
++    unsigned int len, num, hd_index, i;
+     vec = xs_read_watch(xsh, &num);
+     if (!vec)
+         return;
++    for (i = 0; xenstore_watch_callbacks &&  xenstore_watch_callbacks[i].path; i++)
++      if (xenstore_watch_callbacks[i].cb &&
++          !strcmp(vec[XS_WATCH_TOKEN], xenstore_watch_callbacks[i].path))
++            xenstore_watch_callbacks[i].cb(vec[XS_WATCH_TOKEN],
++                                           xenstore_watch_callbacks[i].opaque);
++
+     if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
+         xenstore_process_logdirty_event();
+         goto out;
+@@ -1272,7 +1324,7 @@ int xenstore_vm_write(int domid, const char *key, const char *value)
+     return rc;
+ }
+-char *xenstore_device_model_read(int domid, char *key, unsigned int *len)
++char *xenstore_device_model_read(int domid, const char *key, unsigned int *len)
+ {
+     char *path = NULL, *value = NULL;
+@@ -1438,3 +1490,122 @@ void xenstore_store_serial_port_info(int i, CharDriverState *chr,
+     if (i == 0) /* serial 0 is also called the console */
+         store_dev_info(devname, domid, chr, "/console");
+ }
++
++char *xenstore_dom_read(int domid, const char *key, unsigned int *len)
++{
++    char *buf = NULL, *path = NULL, *value = NULL;
++
++    if (xsh == NULL)
++        goto out;
++
++    path = xs_get_domain_path(xsh, domid);
++    if (path == NULL) {
++        fprintf(logfile, "xs_get_domain_path(%d): error\n", domid);
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/%s", path, key);
++    value = xs_read(xsh, XBT_NULL, buf, len);
++    if (value == NULL) {
++        fprintf(logfile, "xs_read(%s): read error\n", buf);
++        goto out;
++    }
++
++ out:
++    free(path);
++    free(buf);
++    return value;
++}
++
++void xenstore_dom_watch(int domid, const char *key, xenstore_callback fptr, void *opaque)
++{
++    char *buf = NULL, *path = NULL;
++    int rc = -1;
++
++    if (xsh == NULL)
++        goto out;
++
++    path = xs_get_domain_path(xsh, domid);
++    if (path == NULL) {
++        fprintf(logfile, "xs_get_domain_path: error\n");
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/%s", path, key);
++      xenstore_watch_new_callback(buf, fptr, opaque);
++
++ out:
++    free(path);
++    free(buf);
++}
++
++void xenstore_dom_chmod(int domid, const char *key, const char *perms)
++{
++    char *buf = NULL, *path = NULL;
++    int rc = -1;
++      struct xs_permissions p;
++
++    if (xsh == NULL)
++        goto out;
++
++    path = xs_get_domain_path(xsh, domid);
++    if (path == NULL) {
++        fprintf(logfile, "xs_get_domain_path: error\n");
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/%s", path, key);
++
++      xs_strings_to_perms(&p, 1, perms);
++      xs_set_permissions(xsh, XBT_NULL, buf, &p, 1);
++
++ out:
++    free(path);
++    free(buf);
++}
++
++int xenstore_dom_write(int domid, const char *key, const char *value)
++{
++    char *buf = NULL, *path = NULL;
++    int rc = -1;
++
++    if (xsh == NULL)
++        goto out;
++
++    path = xs_get_domain_path(xsh, domid);
++    if (path == NULL) {
++        fprintf(logfile, "xs_get_domain_path: error\n");
++        goto out;
++    }
++
++    pasprintf(&buf, "%s/%s", path, key);
++    rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value));
++    if (rc == 0) {
++        fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key);
++        goto out;
++    }
++
++ out:
++    free(path);
++    free(buf);
++    return rc;
++}
++
++char *xenstore_read(const char *path)
++{
++    char *value = NULL;
++    unsigned int len;
++
++    if (xsh == NULL)
++        return NULL;
++    return xs_read(xsh, XBT_NULL, path, &len);
++}
++
++int xenstore_write(const char *path, const char *val)
++{
++    if (xsh == NULL)
++        return 1;
++    return xs_write(xsh, XBT_NULL, path, val, strlen(val));
++}
++
++
diff --git a/xen-3.4/battery-management b/xen-3.4/battery-management
deleted file mode 100644 (file)
index b5e1a99..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-diff --git a/hw/battery_mgmt.c b/hw/battery_mgmt.c
-index 3ddeb09..1c83b80 100644
---- a/hw/battery_mgmt.c
-+++ b/hw/battery_mgmt.c
-@@ -29,7 +29,6 @@
- #include "hw.h"
- #include "pc.h"
- #include "qemu-xen.h"
--#include "qemu-log.h"
- #include "isa.h" //register_ioport_read declaration
- #include "battery_mgmt.h"
-@@ -59,6 +58,7 @@
- static enum POWER_MGMT_MODE power_mgmt_mode = PM_MODE_NONE;
- static battery_state_info battery_info;
-+extern FILE *logfile;
- int is_battery_pt_feasible(void)
- {
-@@ -229,15 +229,21 @@ static uint32_t battery_port_2_readb(void *opaque, uint32_t addr)
- static uint32_t battery_port_3_readb(void *opaque, uint32_t addr)
- {
--    if ( power_mgmt_mode == PM_MODE_PT || power_mgmt_mode == PM_MODE_NON_PT ) {
--        if ( (power_mgmt_mode == PM_MODE_PT) && (is_battery_pt_feasible() == 0) )
--            return 0x0F;
--        return 0x1F;
--    }
-+    uint32_t system_state;
--    return 0x0F;
--}
-+    if ( power_mgmt_mode != PM_MODE_PT && power_mgmt_mode != PM_MODE_NON_PT )
-+        return 0x0;
-+
-+    if ( (power_mgmt_mode == PM_MODE_PT) && (is_battery_pt_feasible() == 0) )
-+        return 0x0;
-+    system_state = xenstore_read_ac_adapter_state();
-+    if ( xenstore_read_lid_state() == 1 )
-+        system_state |= 0x4;
-+
-+    system_state |= 0x2;
-+    return system_state;
-+}
- void battery_mgmt_non_pt_mode_init(PCIDevice *device)
- {
-@@ -290,6 +296,7 @@ void battery_mgmt_init(PCIDevice *device)
-     }
-     register_ioport_read(BATTERY_PORT_3, 1, 1, battery_port_3_readb, device);
-+    xenstore_register_for_pm_events();
- #ifdef BATTERY_MGMT_DEBUG
-     fprintf(logfile, "Power management mode set to - %d\n", power_mgmt_mode);
-diff --git a/hw/battery_mgmt.h b/hw/battery_mgmt.h
-index 4a4ac8e..19129b8 100644
---- a/hw/battery_mgmt.h
-+++ b/hw/battery_mgmt.h
-@@ -42,4 +42,12 @@ typedef struct battery_state_info {
- void battery_mgmt_init(PCIDevice *device);
-+#ifndef CONFIG_NO_BATTERY_MGMT
-+int is_battery_pt_feasible(void);
-+void battery_mgmt_pt_mode_init(void);
-+void get_battery_data_from_xenstore(void);
-+void write_battery_data_to_port(void);
-+void battery_mgmt_non_pt_mode_init(PCIDevice *device);
-+#endif
-+
- #endif
-diff --git a/hw/pc.h b/hw/pc.h
-index 8b71d48..a261c8a 100644
---- a/hw/pc.h
-+++ b/hw/pc.h
-@@ -106,6 +106,10 @@ int acpi_table_add(const char *table_desc);
- void acpi_php_add(int);
- void acpi_php_del(int);
-+void acpi_ac_adapter_state_changed(void);
-+void acpi_power_button_pressed(void);
-+void acpi_sleep_button_pressed(void);
-+void acpi_lid_state_changed(void);
- /* hpet.c */
- extern int no_hpet;
-diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index 7844cb8..c218782 100644
---- a/hw/piix4acpi.c
-+++ b/hw/piix4acpi.c
-@@ -53,6 +53,11 @@
- /* The bit in GPE0_STS/EN to notify the pci hotplug event */
- #define ACPI_PHP_GPE_BIT 3
-+#define ACPI_PHP_SLOT_NUM NR_PCI_DEV
-+#define ACPI_AC_POWER_STATE_BIT 0x1c
-+#define ACPI_POWER_BUTTON_BIT 0x1
-+#define ACPI_SLEEP_BUTTON_BIT 0x0
-+#define ACPI_LID_STATE_BIT 0x17
- typedef struct AcpiDeviceState AcpiDeviceState;
- AcpiDeviceState *acpi_device_table;
-@@ -192,8 +197,6 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
-     battery_mgmt_init(pci_dev);
- }
--#ifdef CONFIG_PASSTHROUGH
--
- static inline int test_bit(uint8_t *map, int bit)
- {
-     return ( map[bit / 8] & (1 << (bit % 8)) );
-@@ -210,6 +213,56 @@ static inline void clear_bit(uint8_t *map, int bit)
- }
- extern FILE *logfile;
-+
-+void acpi_ac_adapter_state_changed(void)
-+{
-+    GPEState *s = &gpe_state;
-+
-+    if ( !test_bit(&s->gpe0_sts[0], ACPI_AC_POWER_STATE_BIT) &&
-+         test_bit(&s->gpe0_en[0], ACPI_AC_POWER_STATE_BIT) ) {
-+        set_bit(&s->gpe0_sts[0], ACPI_AC_POWER_STATE_BIT);
-+        s->sci_asserted = 1;
-+        qemu_irq_raise(sci_irq);
-+    }
-+}
-+
-+void acpi_power_button_pressed(void)
-+{
-+    GPEState *s = &gpe_state;
-+    if ( !test_bit(&s->gpe0_sts[0], ACPI_POWER_BUTTON_BIT) &&
-+         test_bit(&s->gpe0_en[0], ACPI_POWER_BUTTON_BIT) ) {
-+        set_bit(&s->gpe0_sts[0], ACPI_POWER_BUTTON_BIT);
-+        s->sci_asserted = 1;
-+        qemu_irq_raise(sci_irq);
-+    }
-+}
-+
-+void acpi_sleep_button_pressed(void)
-+{
-+    GPEState *s = &gpe_state;
-+
-+    if ( !test_bit(&s->gpe0_sts[0], ACPI_SLEEP_BUTTON_BIT) &&
-+          test_bit(&s->gpe0_en[0], ACPI_SLEEP_BUTTON_BIT) ) {
-+        set_bit(&s->gpe0_sts[0], ACPI_SLEEP_BUTTON_BIT);
-+        s->sci_asserted = 1;
-+        qemu_irq_raise(sci_irq);
-+    }
-+}
-+
-+void acpi_lid_state_changed(void)
-+{
-+    GPEState *s = &gpe_state;
-+
-+    if ( !test_bit(&s->gpe0_sts[0], ACPI_LID_STATE_BIT) &&
-+         test_bit(&s->gpe0_en[0], ACPI_LID_STATE_BIT) ) {
-+        set_bit(&s->gpe0_sts[0], ACPI_LID_STATE_BIT);
-+        s->sci_asserted = 1;
-+        qemu_irq_raise(sci_irq);
-+    }
-+}
-+
-+#ifdef CONFIG_PASSTHROUGH
-+
- static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
- {
- #if defined(DEBUG)
-diff --git a/qemu-xen.h b/qemu-xen.h
-index c45bf9f..8c1debd 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -122,8 +122,12 @@ void xenstore_dm_finished_startup(void);
- int xenstore_vm_write(int domid, const char *key, const char *val);
- char *xenstore_vm_read(int domid, const char *key, unsigned int *len);
- char *xenstore_device_model_read(int domid, const char *key, unsigned int *len);
-+int xenstore_extended_power_mgmt_read_int(const char *key, int default_value);
- char *xenstore_read_battery_data(int battery_status);
- int xenstore_refresh_battery_status(void);
-+void xenstore_register_for_pm_events(void);
-+int xenstore_read_ac_adapter_state(void);
-+int xenstore_read_lid_state(void);
- int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
-                                          uint32_t build_nr);
-diff --git a/xenstore.c b/xenstore.c
-index 99b31fd..6f5b073 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -27,6 +27,7 @@
- #include "hw.h"
- #include "pci.h"
-+#include "pc.h"
- #include "qemu-timer.h"
- #include "qemu-xen.h"
-@@ -991,6 +992,25 @@ void xenstore_process_event(void *opaque)
-         goto out;
-     }
-+    if (!strcmp(vec[XS_WATCH_TOKEN], "acadapterstatechangeevt")) {
-+        acpi_ac_adapter_state_changed();
-+        goto out;
-+    }
-+
-+    if (!strcmp(vec[XS_WATCH_TOKEN], "pwrbuttonpressedevt")) {
-+        acpi_power_button_pressed();
-+        goto out;
-+    }
-+
-+    if (!strcmp(vec[XS_WATCH_TOKEN], "slpbuttonpressedevt")) {
-+        acpi_sleep_button_pressed();
-+    }
-+
-+    if (!strcmp(vec[XS_WATCH_TOKEN], "lidstatechangeevt")) {
-+        acpi_lid_state_changed();
-+        goto out;
-+    }
-+
-     if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
-         strlen(vec[XS_WATCH_TOKEN]) != 3)
-         goto out;
-@@ -1373,6 +1393,20 @@ static char *xenstore_extended_power_mgmt_read(const char *key, unsigned int *le
-     return value;
- }
-+int xenstore_extended_power_mgmt_read_int(const char *key, int default_value)
-+{
-+    int value = default_value;
-+    char *buffer;
-+
-+    buffer = xenstore_extended_power_mgmt_read(key, NULL);
-+    if ( buffer == NULL )
-+        return value;
-+
-+    value = strtoull(buffer, NULL, 10);
-+    free(buffer);
-+    return value;
-+}
-+
- static int xenstore_extended_power_mgmt_write(const char *key, const char *value)
- {
-     int ret;
-@@ -1425,6 +1459,24 @@ int xenstore_refresh_battery_status(void)
-     return xenstore_extended_power_mgmt_event_trigger("refreshbatterystatus", "1");
- }
-+void xenstore_register_for_pm_events(void)
-+{
-+   xs_watch(xsh, "/pm/events/acadapterstatechanged", "acadapterstatechangeevt");
-+   xs_watch(xsh, "/pm/events/lidstatechanged", "lidstatechangeevt");
-+   xs_watch(xsh, "/pm/events/powerbuttonpressed", "pwrbuttonpressedevt");
-+   xs_watch(xsh, "/pm/events/sleepbuttonpressed", "slpbuttonpressedevt");
-+}
-+
-+int xenstore_read_ac_adapter_state(void)
-+{
-+    return xenstore_extended_power_mgmt_read_int("ac_adapter", 1);
-+}
-+
-+int xenstore_read_lid_state(void)
-+{
-+    return xenstore_extended_power_mgmt_read_int("lid_state", 1);
-+}
-+
- /*
-  * Create a store entry for a device (e.g., monitor, serial/parallel lines).
-  * The entry is <domain-path><storeString>/tty and the value is the name
diff --git a/xen-3.4/disable-aio b/xen-3.4/disable-aio
deleted file mode 100644 (file)
index b6c874e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/xen-setup b/xen-setup
-index 24defda..84f2936 100755
---- a/xen-setup
-+++ b/xen-setup
-@@ -9,7 +9,7 @@ rm -f config-host.mak
- if test -f config-host.h; then mv config-host.h config-host.h~; fi
--./configure --disable-gfx-check --disable-curses --disable-slirp --disable-vnc-tls --disable-sdl "$@" --prefix=/usr
-+./configure --disable-gfx-check --disable-curses --disable-slirp --disable-vnc-tls --disable-sdl --disable-aio "$@" --prefix=/usr
- target=i386-dm
diff --git a/xen-3.4/dm-ready b/xen-3.4/dm-ready
deleted file mode 100644 (file)
index 2a9fb8c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-diff --git a/qemu-xen.h b/qemu-xen.h
-index 434d7db..3dc4518 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -86,6 +86,7 @@ void xenstore_dom_chmod(int domid, const char *key, const char *perms);
- char *xenstore_read(const char *path);
- int xenstore_write(const char *path, const char *val);
-+void xenstore_dm_finished_startup(void);
-  /* `danger' means that this parameter, variable or function refers to
-   * an area of xenstore which is writeable by the guest and thus must
-diff --git a/vl.c b/vl.c
-index 5801e42..c31e0a1 100644
---- a/vl.c
-+++ b/vl.c
-@@ -5966,6 +5966,8 @@ int main(int argc, char **argv, char **envp)
-       close(fd);
-     }
-+    xenstore_dm_finished_startup();
-+
-     main_loop();
-     quit_timers();
-     net_cleanup();
-diff --git a/xenstore.c b/xenstore.c
-index 6448416..6834cce 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -1609,3 +1609,25 @@ int xenstore_write(const char *path, const char *val)
- }
-+/* Advertise through xenstore that the device model is up and the
-+   domain can be started. */
-+void xenstore_dm_finished_startup(void)
-+{
-+    char *path;
-+    char *buf = NULL;
-+
-+    path = xs_get_domain_path(xsh, domid);
-+    if (!path) {
-+        fprintf(logfile, "xs_get_domain_path() failed.\n");
-+        goto out;
-+    }
-+    if (pasprintf(&buf, "%s/device-misc/dm-ready", path) == -1) {
-+        fprintf(logfile, "pasprintf failed to get path.\n");
-+        goto out;
-+    }
-+    if (xs_write(xsh, XBT_NULL, buf, "1", 1) == 0)
-+        fprintf(logfile, "xs_write() dm-ready failed\n");
-+ out:
-+    free(buf);
-+    free(path);
-+}
diff --git a/xen-3.4/dom0-driver b/xen-3.4/dom0-driver
deleted file mode 100644 (file)
index daaa97c..0000000
+++ /dev/null
@@ -1,1415 +0,0 @@
-diff --git a/console.h b/console.h
-index 14b42f3..97214c0 100644
---- a/console.h
-+++ b/console.h
-@@ -341,4 +341,19 @@ const char *readline_get_history(unsigned int index);
- void readline_start(const char *prompt, int is_password,
-                     ReadLineFunc *readline_func, void *opaque);
-+/* get_time */
-+char *get_time(void);
-+
-+/* dom0_driver.c */
-+void dom0_driver_init(const char *position);
-+
-+/* hid_linux.c */
-+void hid_linux_init(void);
-+int  hid_linux_grab_keyboard(int grab);
-+int  hid_linux_grab_mouse(int grab);
-+void hid_linux_secure_keyboard(void (*)(int));
-+void hid_linux_add_binding(const int *, void (*)(void*), void *);
-+void hid_linux_reset_keyboard(void);
-+void hid_linux_probe(int grab);
-+
- #endif
-diff --git a/dom0_driver.c b/dom0_driver.c
-new file mode 100644
-index 0000000..1b5cd06
---- /dev/null
-+++ b/dom0_driver.c
-@@ -0,0 +1,697 @@
-+/*
-+ * QEMU dom0_driver
-+ *
-+ * Copyright (c) 2009 Citrix Systems
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "qemu-common.h"
-+#include "console.h"
-+#include "qemu-timer.h"
-+#include "qemu-xen.h"
-+
-+#include <sys/types.h>
-+#include <linux/input.h>
-+#include <linux/kd.h>
-+#include <dirent.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <fcntl.h>
-+#include <limits.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <assert.h>
-+#include <time.h>
-+
-+extern int vga_passthrough;
-+extern int intel;
-+
-+static void dom0_driver_state_change(const char *path, void *opaque);
-+static void dom0_driver_command(const char *path, void *opaque);
-+static void dom0_driver_leave_done(void);
-+
-+#define DEBUG_DOM0_DRIVER             1
-+#define XS_REFRESH_INTERVAL           1000
-+#define DOM0_DRIVER_SWITCH_TIMEOUT    2
-+
-+#define DOM0_MOUSE              1
-+#define DOM0_KEYBOARD           2
-+
-+#if DEBUG_DOM0_DRIVER
-+# define DEBUG(_format_, args...)    \
-+    do { \
-+      char *__str = get_time();       \
-+    fprintf(stderr, "[%s] dom0_driver(%d):%d: " _format_, __str, domid, __LINE__, ## args);\
-+      free(__str); \
-+    } while (false)
-+#else
-+# define DEBUG(_format_, args...) (void)0
-+#endif
-+
-+#define NB_SLOTS        10
-+
-+static void             dom0_read(void *opaque);
-+static void             dom0_driver_reset_keyboard(void);
-+static void             dom0_read_secure(void *opaque);
-+struct dom0_driver
-+{
-+    QEMUTimer *xs_timer;
-+    int secure_fd;
-+    int (*enter)(void);
-+    int (*leave)(void);
-+};
-+
-+struct dom0_driver_handler
-+{
-+    void (*init)(void);
-+    void (*probe)(int);
-+    int  (*grab_keyboard)(int);
-+    int  (*grab_mouse)(int);
-+    void (*secure_keyboard)(void (*)(int));
-+    void (*reset_keyboard)(void);
-+    void (*add_binding)(const int *, void (*)(void *), void *);
-+};
-+
-+struct dom0_driver_xs_info
-+{
-+    int state;
-+    int domid;
-+    int new_slot;
-+    int timestamp;
-+    int pre;
-+};
-+
-+static struct dom0_driver_handler dom0_driver_hid_linux =
-+{
-+    .init = hid_linux_init,
-+    .probe = hid_linux_probe,
-+    .grab_keyboard = hid_linux_grab_keyboard,
-+    .grab_mouse = hid_linux_grab_mouse,
-+    .secure_keyboard = hid_linux_secure_keyboard,
-+    .reset_keyboard = hid_linux_reset_keyboard,
-+    .add_binding = hid_linux_add_binding,
-+};
-+
-+static struct dom0_driver driver;
-+static struct dom0_driver_handler *dom0_driver_handler = NULL;
-+
-+static int dom0_driver_xs_read_dom0(const char *key)
-+{
-+    char        *str = NULL;
-+
-+    if (!(str = xenstore_read_dom0_driver(key)))
-+    {
-+      fprintf(stderr, "dom0_driver: fatal the node %s don't exits\n", key);
-+      exit(2);
-+    }
-+    return strtol(str, NULL, 10);
-+}
-+
-+static void dom0_driver_read_xs_info(struct dom0_driver_xs_info *info,
-+                                   int                        controller)
-+{
-+    char        *str = NULL;
-+    char        path[128];
-+    int         val[10];
-+    const char  *key[] = {"state", "domid", "new-slot", "timestamp", "pre"};
-+
-+    memset(info, -1, sizeof (struct dom0_driver_xs_info));
-+    for (int i = 0; i < sizeof (key) / sizeof (key[0]); i++)
-+    {
-+      if (controller == DOM0_MOUSE)
-+          sprintf(path, "mouse/%s", key[i]);
-+      else if (controller == DOM0_KEYBOARD)
-+          sprintf(path, "keyboard/%s", key[i]);
-+      else
-+      {
-+          fprintf(stderr, "dom0_driver unknown controller type\n");
-+          exit(2);
-+      }
-+
-+      val[i] = -1;
-+      if ((str = xenstore_read_dom0_driver(path)))
-+      {
-+          val[i] = strtol(str, NULL, 10);
-+          free(str);
-+      }
-+    }
-+
-+    info->state = val[0];
-+    info->domid = val[1];
-+    info->new_slot = val[2];
-+    info->timestamp = val[3];
-+    info->pre = val[4];
-+}
-+
-+static void dom0_driver_xs_write(const char *key, int val, int controller)
-+{
-+    char        path[256], str[20];
-+
-+    if (controller == DOM0_MOUSE)
-+      sprintf(path, "mouse/%s", key);
-+    else if (controller == DOM0_KEYBOARD)
-+      sprintf(path, "keyboard/%s", key);
-+    else
-+    {
-+      DEBUG("unknown controller type\n");
-+      exit(2);
-+    }
-+
-+    sprintf(str, "%d", val);
-+    DEBUG("write %s=%d\n", path, val);
-+    xenstore_write_dom0_driver(path, str);
-+}
-+
-+/*
-+** Blanker fonctions
-+*/
-+static void dom0_driver_blank_changed(void)
-+{
-+    char *str;
-+    int blank;
-+
-+    if (!(str = xenstore_read_dom0_driver("blank")))
-+      return;
-+    blank = strtol(str, NULL, 10);
-+    free(str);
-+    if (blank == 2)
-+    {
-+      usleep(100 * 1000); /* 100 ms */
-+      dom0_driver_leave_done();
-+    }
-+}
-+static int dom0_driver_blank(void)
-+{
-+    xenstore_write_dom0_driver("blank", "1");
-+    return 0;
-+}
-+static int dom0_driver_unblank(void)
-+{
-+    xenstore_write_dom0_driver("blank", "0");
-+    return 0;
-+}
-+
-+static void dom0_driver_key_switch(int new_slot)
-+{
-+    struct dom0_driver_xs_info  info;
-+    char                        buff[128];
-+
-+    dom0_driver_read_xs_info(&info, DOM0_MOUSE);
-+    assert(info.state == 1);
-+
-+    sprintf(buff, "switch %d", new_slot);
-+
-+    DEBUG("Write \"%s\" into xenstore\n", buff);
-+    xenstore_write_dom0_driver("command", buff);
-+}
-+
-+static void dom0_driver_read_secure(int ascii)
-+{
-+    int write_sz;
-+
-+    if (ascii)
-+    {
-+      DEBUG("Send %d to xenmgr\n", ascii);
-+      write_sz = write(driver.secure_fd, &ascii, 1);
-+      if (ascii == -1 || ascii == 27 || write_sz != 1)
-+      {
-+          dom0_driver_handler->reset_keyboard();
-+          dom0_driver_handler->secure_keyboard(NULL);
-+          return;
-+      }
-+    }
-+}
-+
-+static void dom0_driver_detect_secure_auth(void* opaque)
-+{
-+    struct stat s;
-+    int sas_ascii = 1, ret = 0;;
-+
-+    DEBUG("Received SAS keystroke\n");
-+    if ((driver.secure_fd = open("/var/lib/xenmgr/keys", O_WRONLY)) > 0)
-+    {
-+      DEBUG("write SAS ascii code\n");
-+      if ((ret = write(driver.secure_fd, &sas_ascii, 1)) == 1)
-+      {
-+          DEBUG("Redirect fds to secure callback\n");
-+          dom0_driver_handler->secure_keyboard(dom0_driver_read_secure);
-+      }
-+      DEBUG("writing SAS ret %d\n", ret);
-+
-+    }
-+    else
-+      DEBUG("xenmgr file is not there\n");
-+}
-+
-+static void dom0_get_positions(int *positions)
-+{
-+    int *domids = NULL;
-+    int num;
-+    char *tmp;
-+    unsigned int len;
-+    int pos = 0;
-+
-+    for (int i = 0; i < NB_SLOTS; i++)
-+      positions[i] = 0;
-+
-+    /* Get all the positions */
-+    domids = xenstore_get_domids(&num);
-+    for (int i = 0; i < num; i++)
-+      if (domids[i])
-+      {
-+          if (!(tmp = xenstore_dom_read(domids[i], "dom0_input/pos", &len)))
-+              continue;
-+          pos = strtol(tmp, NULL, 10);
-+          free(tmp);
-+
-+          positions[pos] = domids[i];
-+      }
-+    free(domids);
-+}
-+
-+static void dom0_gr_devices(int grab, int controller)
-+{
-+    if (controller == DOM0_MOUSE)
-+    {
-+      DEBUG("%s mouse\n", grab ? "Grab" : "Release");
-+      assert(dom0_driver_handler->grab_mouse(grab));
-+    }
-+    if (controller == DOM0_KEYBOARD)
-+    {
-+      DEBUG("%s keyboard\n", grab ? "Grab" : "Release");
-+      assert(dom0_driver_handler->grab_keyboard(grab));
-+    }
-+
-+    dom0_driver_handler->reset_keyboard();
-+    if (!grab)
-+      dom0_driver_xs_write("pre", domid, controller);
-+    dom0_driver_xs_write("domid", domid, controller);
-+    dom0_driver_xs_write("state", grab ? 1 : 2, controller);
-+}
-+
-+static int dom0_dom_alive(int id)
-+{
-+    xc_dominfo_t info;
-+    int rc;
-+
-+    rc = xc_domain_getinfo(xc_handle, id, 1, &info);
-+    return rc == 1 && info.domid == id;
-+}
-+
-+
-+static int dom0_driver_failover_switch(void *opaque)
-+{
-+    int                         ret = 1;
-+    uint32_t                  t = time(NULL);
-+    struct dom0_driver_xs_info        mouse, keyboard;
-+
-+    dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
-+    dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
-+    if (mouse.domid == domid)
-+      dom0_driver_handler->probe(1);
-+    else
-+      dom0_driver_handler->probe(0);
-+
-+    if (!vga_passthrough)
-+      return 0;
-+
-+    if (mouse.state == -1)
-+    {
-+      DEBUG("No state grab the device\n");
-+      dom0_gr_devices(1, DOM0_KEYBOARD);
-+      dom0_gr_devices(1, DOM0_MOUSE);
-+      driver.enter();
-+      goto out;
-+    }
-+
-+    /* The domain which has the focus crash */
-+    if (!dom0_dom_alive(mouse.domid))
-+    {
-+      DEBUG("steal the focus from %d\n", mouse.domid);
-+      dom0_gr_devices(1, DOM0_KEYBOARD);
-+      dom0_gr_devices(1, DOM0_MOUSE);
-+      driver.enter();
-+      goto out;
-+    }
-+
-+    if ( keyboard.state == 2 &&
-+          (t - keyboard.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
-+    {
-+      DEBUG("Keyboard in state 2 for to long, take it back\n");
-+      dom0_gr_devices(1, DOM0_KEYBOARD);
-+    }
-+
-+    if (mouse.state == 2 &&
-+          (t - mouse.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
-+    {
-+      DEBUG("Mouse in state 2 for to long, take it back\n");
-+      dom0_gr_devices(1, DOM0_MOUSE);
-+      DEBUG("Get the focus now !\n");
-+      driver.enter();
-+      goto out;
-+    }
-+
-+    ret = 0;
-+out:
-+    qemu_mod_timer(driver.xs_timer, qemu_get_clock(rt_clock) + XS_REFRESH_INTERVAL);
-+    return ret;
-+}
-+
-+static void dom0_driver_dom_command(const char *path, void *opaque)
-+{
-+    unsigned int len;
-+    char *str;
-+    char buff[256];
-+    int       positions[NB_SLOTS];
-+    int natif_domid;
-+    int i;
-+    struct dom0_driver_xs_info mouse;
-+
-+    if (!(str = xenstore_read(path)) || !*str)
-+      return;
-+
-+    DEBUG("Received private command %s\n", path);
-+    dom0_get_positions(positions);
-+    natif_domid = dom0_driver_xs_read_dom0("natif");
-+
-+    dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
-+    if (mouse.domid != natif_domid)
-+    {
-+      DEBUG("Natif should have the focus for that.\n");
-+      return;
-+    }
-+
-+    for (i = 0; i < NB_SLOTS; ++i)
-+    {
-+      if (!strcmp("take", str) && positions[i] == domid)
-+          break;
-+      if (!strcmp("release", str) && positions[i] == natif_domid)
-+          break;
-+    }
-+    if (i == NB_SLOTS)
-+    {
-+      DEBUG("Try to %s on a bad slot\n", str);
-+      free(str);
-+      return;
-+    }
-+
-+    sprintf(buff, "keyboard %d", i);
-+    DEBUG("Write \"%s\" into xenstore\n", buff);
-+    xenstore_write_dom0_driver("command", buff);
-+    free(str);
-+}
-+
-+static void dom0_driver_event_init(const char *str_arg)
-+{
-+    int                 positions[NB_SLOTS];
-+    char                str[20];
-+    int                 pos = 0;
-+    int                 i = 0;
-+
-+    pos = strtol(str_arg, NULL, 10);
-+    dom0_get_positions(positions);
-+    if (positions[pos])
-+    {
-+      DEBUG("There is already a vm at this slot\n");
-+      exit(1);
-+    }
-+    else
-+    {
-+      snprintf(str, 9, "%d", pos);
-+      xenstore_dom_write(domid, "dom0_input/pos", str);
-+    }
-+
-+    if (vga_passthrough)
-+    {
-+      sprintf(str, "%d", domid);
-+      xenstore_write_dom0_driver("natif", str);
-+      xenstore_watch_dom0_driver("command", dom0_driver_command, NULL);
-+    }
-+    else
-+    {
-+      xenstore_dom_write(domid, "dom0_input/command", "");
-+      sprintf(str, "w%d", domid);
-+      xenstore_dom_chmod(domid, "dom0_input/command", str);
-+      xenstore_dom_watch(domid, "dom0_input/command", dom0_driver_dom_command, NULL);
-+    }
-+
-+    xenstore_watch_dom0_driver("mouse/state", dom0_driver_state_change, NULL);
-+    xenstore_watch_dom0_driver("keyboard/state", dom0_driver_state_change, NULL);
-+    xenstore_watch_dom0_driver("leave", dom0_driver_state_change, NULL);
-+    xenstore_watch_dom0_driver("blank", dom0_driver_state_change, NULL);
-+
-+    /* Register the failover switch */
-+    driver.xs_timer = qemu_new_timer(rt_clock,
-+                                   (void (*)(void *))dom0_driver_failover_switch,
-+                                   NULL);
-+    qemu_mod_timer(driver.xs_timer, qemu_get_clock(rt_clock) + XS_REFRESH_INTERVAL);
-+}
-+
-+static void dom0_driver_slots(int controller)
-+{
-+    struct dom0_driver_xs_info  info;
-+    int                         next_domid;
-+    int                         positions[NB_SLOTS];
-+
-+    if (dom0_driver_failover_switch(NULL))
-+      return;
-+
-+    dom0_driver_read_xs_info(&info, controller);
-+
-+    if (info.new_slot != -1)
-+    {
-+      dom0_get_positions(positions);
-+      if (positions[info.new_slot] != 0)
-+      {
-+          if (info.state == 0 && info.domid == domid)
-+          {
-+              dom0_gr_devices(0, controller);
-+              return;
-+          }
-+
-+          if (info.state == 2 && positions[info.new_slot] == domid)
-+          {
-+              dom0_gr_devices(1, controller);
-+              return;
-+          }
-+
-+      }
-+    }
-+}
-+
-+static void dom0_driver_switch_controller(int slot, int controller)
-+{
-+    int       positions[NB_SLOTS];
-+    char *str;
-+    int len;
-+    int ready;
-+    struct dom0_driver_xs_info info;
-+
-+    dom0_get_positions(positions);
-+    if (positions[slot] == 0)
-+    {
-+      DEBUG("Cannot switch controller %d to %d slot empty\n", controller, slot);
-+      return;
-+    }
-+
-+    str = xenstore_dom_read(positions[slot], "dom0_input/ready", &len);
-+    ready = strtol(str, NULL, 10);
-+    free(str);
-+    if (ready != 1)
-+    {
-+      DEBUG("Cannot switch controller %d to %d slot not ready\n", controller, slot);
-+      return;
-+    }
-+
-+    dom0_driver_read_xs_info(&info, controller);
-+    if (info.state != 1)
-+    {
-+      DEBUG("Cannot switch controller %d to %d, unstable state\n", controller, slot);
-+      return;
-+    }
-+
-+    dom0_driver_xs_write("new-slot", slot, controller);
-+    dom0_driver_xs_write("timestamp", time(NULL), controller);
-+    dom0_driver_xs_write("state", 0, controller);
-+}
-+
-+void dom0_driver_command(const char *path, void *opaque)
-+{
-+    char        *val = NULL;
-+
-+    val = xenstore_read(path);
-+    if (val == NULL)
-+      return;
-+
-+    if (!strncmp(val, "switch ", 7))
-+    {
-+      int slot = strtol(val + 7, NULL, 10);
-+
-+      if (errno == EINVAL)
-+          goto out;
-+
-+      DEBUG("switch the keyboard/mouse to slot %d\n", slot);
-+      dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
-+      dom0_driver_switch_controller(slot, DOM0_MOUSE);
-+      xenstore_write(path, "done");
-+    }
-+    else if (!strncmp(val, "keyboard ", 9))
-+    {
-+      int slot = strtol(val + 9, NULL, 10);
-+
-+      if (errno == EINVAL)
-+          goto out;
-+
-+      DEBUG("switch the keyboard to slot %d\n", slot);
-+      dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
-+      xenstore_write(path, "done");
-+    }
-+out:
-+    free(val);
-+}
-+
-+static void dom0_driver_leave_done(void)
-+{
-+    char *str;
-+    int id;
-+
-+    if (!(str = xenstore_read_dom0_driver("leave")))
-+      return;
-+    id = strtol(str, NULL, 10);
-+    free(str);
-+    if (id == 1)
-+      xenstore_write_dom0_driver("leave", "2");
-+}
-+
-+static void dom0_driver_leave_changed(void)
-+{
-+    char *str;
-+    int id;
-+    struct dom0_driver_xs_info mouse;
-+
-+    if (!(str = xenstore_read_dom0_driver("leave")))
-+      return;
-+    id = strtol(str, NULL, 10);
-+    free(str);
-+    dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
-+    if (id == 2 && mouse.domid == domid)
-+    {
-+      xenstore_write_dom0_driver("leave", "0");
-+      driver.enter();
-+    }
-+}
-+
-+static void dom0_driver_state_change(const char *path, void *opaque)
-+{
-+
-+    if (strstr(path, "/keyboard/state"))
-+      dom0_driver_slots(DOM0_KEYBOARD);
-+    if (strstr(path, "/mouse/state"))
-+      dom0_driver_slots(DOM0_MOUSE);
-+    if (strstr(path, "/leave"))
-+      dom0_driver_leave_changed();
-+    else if (strstr(path, "/blank"))
-+      dom0_driver_blank_changed();
-+    else
-+    {
-+      struct dom0_driver_xs_info  mouse, keyboard;
-+
-+      dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
-+      dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
-+
-+      if (mouse.state == 1 && keyboard.state == 1)
-+          if (mouse.pre != -1 && mouse.pre == domid)
-+          {
-+              xenstore_write_dom0_driver("leave", "1");
-+              if (driver.leave())
-+                  dom0_driver_leave_done();
-+          }
-+    }
-+}
-+
-+static void dom0_driver_switch(void *slot_arg)
-+{
-+    int slot = (int)slot_arg;
-+    char buff[64];
-+
-+    DEBUG("%d pressed switch to slot %d\n", slot, slot);
-+    sprintf(buff, "switch %d", slot);
-+    xenstore_write_dom0_driver("command", buff);
-+}
-+
-+static void dom0_driver_switch_bind(void)
-+{
-+    int               i = 0;
-+    int               binds[4];
-+
-+    for (i = 0; i < 4; i++)
-+      binds[i] = -1;
-+
-+    for (i = 0; i < 9; i++)
-+    {
-+      binds[0] = KEY_LEFTCTRL;
-+      binds[1] = KEY_1 + i;
-+      dom0_driver_handler->add_binding(binds, dom0_driver_switch, (void*)(i + 1));
-+    }
-+
-+    binds[0] = KEY_LEFTCTRL;
-+    binds[1] = KEY_LEFTALT;
-+    binds[2] = KEY_BACKSPACE;
-+    binds[3] = -1;
-+    dom0_driver_handler->add_binding(binds, dom0_driver_detect_secure_auth, NULL);
-+}
-+
-+static int dom0_driver_dummy_enter_leave(void)
-+{
-+  return 1;
-+}
-+
-+void dom0_driver_init(const char *position)
-+{
-+    memset(&driver, 0, sizeof (driver));
-+
-+    dom0_driver_handler = &dom0_driver_hid_linux;
-+    dom0_driver_handler->init();
-+
-+    if (vga_passthrough)
-+    {
-+      driver.enter = dom0_driver_unblank;
-+      driver.leave = dom0_driver_blank;
-+    }
-+    else if (intel)
-+    {
-+        driver.enter = intel_enter;
-+        driver.enter = intel_leave;
-+    }
-+    else
-+    {
-+      driver.enter = dom0_driver_dummy_enter_leave;
-+      driver.leave = dom0_driver_dummy_enter_leave;
-+    }
-+
-+    dom0_driver_switch_bind();
-+    dom0_driver_event_init(position);
-+    dom0_driver_failover_switch(NULL);
-+
-+    DEBUG("done\n");
-+    xenstore_dom_write(domid, "dom0_input/ready", "1");
-+}
-diff --git a/hid-linux.c b/hid-linux.c
-new file mode 100644
-index 0000000..4ec6bdd
---- /dev/null
-+++ b/hid-linux.c
-@@ -0,0 +1,513 @@
-+/*
-+ * QEMU hid-linux /dev/input driver
-+ *
-+ * Copyright (c) 2008 Citrix Systems
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+ * THE SOFTWARE.
-+ */
-+
-+#include "qemu-common.h"
-+#include "console.h"
-+#include "qemu-timer.h"
-+#include "qemu-xen.h"
-+
-+#include <sys/types.h>
-+#include <linux/input.h>
-+#include <linux/kd.h>
-+#include <dirent.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <fcntl.h>
-+#include <limits.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <assert.h>
-+#include <time.h>
-+#include <sys/time.h>
-+
-+#define HID_LINUX_XS_PATH             "/local/domain/0/hid_linux"
-+#define ABS(x)                        ((x) > 0 ? (x) : -(x))
-+#define EVENT_PATH                            "/dev/input/event"
-+#define HID_LINUX_MAX_DEV             16
-+
-+#define DEBUG_HID_LINUX
-+
-+#ifdef DEBUG_HID_LINUX
-+# define DEBUG(_format_, args...)     \
-+    do \
-+{ \
-+    char *__str = get_time(); \
-+    fprintf(stderr, "[%s] hid-linux(%d):%d: " _format_, (__str), domid, __LINE__, ## args);\
-+    free(__str);\
-+} \
-+while (0);
-+#else
-+# define DEBUG(_format_, args...) (void)0
-+#endif
-+
-+static struct hid_linux_driver
-+{
-+    int               keyboard_fds[HID_LINUX_MAX_DEV / 2];
-+    int               mouse_fds[HID_LINUX_MAX_DEV / 2];
-+    char      *controller_paths[HID_LINUX_MAX_DEV];
-+    int               mouse_button_state;
-+    int               key_status[256];
-+    void      (*secure_key)(int ascii);
-+} hid_linux_driver;
-+
-+struct hid_linux_binding
-+{
-+    int       *binding;
-+    void      (*cb)(void *);
-+    void      *payload;
-+};
-+
-+static struct hid_linux_binding *hid_linux_binding = NULL;
-+
-+static const int ascii2keycode_table[] =
-+{
-+    KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
-+    KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
-+    KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z
-+};
-+
-+static char keycode2ascii(int keycode)
-+{
-+    int i = 0;
-+
-+    switch (keycode)
-+    {
-+      case KEY_ESC: return 27;
-+      case KEY_BACKSPACE: return 8;
-+      case KEY_ENTER: return 10;
-+      case KEY_LEFT: return 17;
-+      case KEY_RIGHT: return 18;
-+      case KEY_DELETE: return 127;
-+      case KEY_HOME: return 2;
-+      case KEY_END: return 3;
-+      case KEY_INSERT: return 19;
-+      case KEY_SPACE: return 20;
-+      default:
-+              for (i = 0; i < sizeof (ascii2keycode_table) / sizeof (int); i++)
-+                  if (ascii2keycode_table[i] == keycode)
-+                      return i + 'a';
-+    }
-+    return 0;
-+}
-+
-+static int ascii2keycode(char ascii)
-+{
-+    return ascii2keycode_table[ascii - 'a'];
-+}
-+
-+static char *hid_linux_xs_read(const char *key)
-+{
-+    char *path = NULL;
-+    char *ret;
-+
-+    if (asprintf(&path, HID_LINUX_XS_PATH"/%s", key) == -1)
-+      return NULL;
-+    ret = xenstore_read(path);
-+    free(path);
-+    return ret;
-+}
-+
-+void hid_linux_add_binding(const int *tab, void (*cb)(void*), void *payload)
-+{
-+    int i = 0, j = 0;
-+
-+    for (i = 0; hid_linux_binding && hid_linux_binding[i].cb; i++)
-+      ;
-+    hid_linux_binding = realloc(hid_linux_binding,
-+                              (i + 2) * sizeof (struct hid_linux_binding));
-+    hid_linux_binding[i + 1].cb = NULL;
-+    hid_linux_binding[i].cb = cb;
-+    hid_linux_binding[i].payload = payload;
-+    hid_linux_binding[i].binding = NULL;
-+
-+    j = 0;
-+    do
-+    {
-+      hid_linux_binding[i].binding = realloc(hid_linux_binding[i].binding,
-+                                             (j + 1) * sizeof (int));
-+      hid_linux_binding[i].binding[j] = tab[j];
-+    }
-+    while (tab[j++] != -1);
-+}
-+
-+static int hid_linux_detect_binding(void)
-+{
-+    int i, j;
-+
-+    for (i = 0; hid_linux_binding && hid_linux_binding[i].cb; i++)
-+    {
-+      int *tab = hid_linux_binding[i].binding;
-+
-+      for (j = 0; tab[j] != -1; j++)
-+          if (hid_linux_driver.key_status[tab[j]] == 0)
-+              break;
-+      if (tab[j] != -1)
-+          continue;
-+      else /* We match a binding */
-+      {
-+          DEBUG("binding payload %d\n", (int)(hid_linux_binding[i].payload));
-+          hid_linux_binding[i].cb(hid_linux_binding[i].payload);
-+          hid_linux_reset_keyboard();
-+          return 1;
-+      }
-+    }
-+    return 0;
-+}
-+
-+static void hid_linux_key_inject(int code, uint32_t keycode)
-+{
-+    int first = 0;
-+
-+    switch (keycode)
-+    {
-+      case KEY_F11:       keycode = 0X57; break; /* F11 */
-+      case KEY_F12:       keycode = 0X58; break; /* F12 */
-+      case KEY_INSERT:    keycode = 0X52; break;
-+      case KEY_HOME:      keycode = 0X47; break;
-+      case KEY_PAGEUP:    keycode = 0X49; break;
-+      case KEY_DELETE:    keycode = 0X53; break;
-+      case KEY_END:       keycode = 0X4F; break;
-+      case KEY_PAGEDOWN:  keycode = 0x51; break;
-+      case KEY_UP:        keycode = 0X48; break;
-+      case KEY_LEFT:      keycode = 0X4B; break;
-+      case KEY_DOWN:      keycode = 0X50; break;
-+      case KEY_RIGHT:     keycode = 0X4D; break;
-+      case KEY_RIGHTALT:  keycode = 0x38; first = 0xe0; break;
-+      case KEY_LEFTMETA:  keycode = 0x5B; first = 0xe0; break;
-+      case KEY_RIGHTMETA: keycode = 0x5C; first = 0xe0; break;
-+    }
-+
-+    if (first)
-+      kbd_put_keycode(first);
-+
-+    if (code == 0)
-+      kbd_put_keycode(keycode | 0x80);
-+    else
-+      kbd_put_keycode(keycode & 0x7f);
-+}
-+
-+
-+
-+static void hid_linux_key_event(int code, uint32_t keycode)
-+{
-+    if (code == 1)
-+      if (hid_linux_detect_binding())
-+          return;
-+    hid_linux_key_inject(code, keycode);
-+}
-+
-+static void hid_linux_read(void *opaque)
-+{
-+    struct input_event  event[5];
-+    int                 i = 0;
-+    int                 read_sz = 0;
-+    int                 fd = *(int *)opaque;
-+
-+    read_sz = read(fd, event, sizeof (event));
-+    for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
-+    {
-+      if (event[i].type == EV_KEY)
-+      {
-+          if (event[i].code >= BTN_MOUSE)
-+          {
-+              /* Mouse Key */
-+              int     type = 0;
-+
-+              switch(event[i].code)
-+              {
-+                  case BTN_LEFT: type = MOUSE_EVENT_LBUTTON; break;
-+                  case BTN_RIGHT: type = MOUSE_EVENT_RBUTTON; break;
-+                  case BTN_MIDDLE: type = MOUSE_EVENT_MBUTTON; break;
-+              }
-+
-+              if (event[i].value)
-+                  hid_linux_driver.mouse_button_state |= type;
-+              else
-+                  hid_linux_driver.mouse_button_state &= ~type;
-+              kbd_mouse_event(0, 0, 0, hid_linux_driver.mouse_button_state);
-+          }
-+          else
-+          {
-+              hid_linux_driver.key_status[event[i].code] = event[i].value;
-+              hid_linux_key_event(event[i].value, event[i].code);
-+          }
-+      }
-+
-+      if (event[i].type == EV_REL || event[i].type == EV_ABS)
-+      {
-+          /* Mouse motion */
-+          int x = 0, y = 0, z = 0;
-+
-+          if (event[i].type == EV_REL)
-+              switch (event[i].code)
-+              {
-+                  case REL_X : x = event[i].value; break;
-+                  case REL_Y : y = event[i].value; break;
-+                  case REL_WHEEL : z = -event[i].value; break;
-+              }
-+          if (event[i].type == EV_ABS)
-+          {
-+              static int last_x = 1, last_y = 1;
-+              int px = 0, py = 0, l = 50;
-+              double div = 1;
-+              char *str = NULL;
-+
-+              str = hid_linux_xs_read("touchpad-limit");
-+              if (str)
-+                  l = strtol(str, NULL, 10);
-+              str = hid_linux_xs_read("touchpad-div");
-+              if (str)
-+                  div = strtol(str, NULL, 10) / 1000.;
-+
-+              switch (event[i].code)
-+              {
-+                  case ABS_X : x = event[i].value; break;
-+                  case ABS_Y : y = event[i].value; break;
-+              }
-+
-+              if (x)
-+              {
-+                  px = x - last_x;
-+                  last_x = x;
-+              }
-+              if (y)
-+              {
-+                  py = y - last_y;
-+                  last_y = y;
-+              }
-+
-+              x = (ABS(px) < l ? px : 0) / div;
-+              y = (ABS(py) < l ? py : 0) / div;
-+          }
-+
-+          kbd_mouse_event(x, y, z, hid_linux_driver.mouse_button_state);
-+      }
-+    }
-+}
-+
-+void hid_linux_reset_keyboard(void)
-+{
-+    int i = 0;
-+
-+    for (i = 0; i < 256; i++)
-+      if (hid_linux_driver.key_status[i])
-+      {
-+          hid_linux_key_inject(0, i);
-+          hid_linux_driver.key_status[i] = 0;
-+      }
-+}
-+
-+
-+
-+static void hid_linux_redirect_fds(int *fd, IOHandler *cb)
-+{
-+    assert(fd != NULL);
-+
-+    while (*fd != -1)
-+    {
-+      qemu_set_fd_handler(*fd, cb, NULL, fd);
-+      fd++;
-+    }
-+}
-+
-+static void hid_linux_secure_read(void *opaque)
-+{
-+    struct input_event  event[5];
-+    int                 i = 0;
-+    int                 read_sz = 0;
-+    int                 fd = *(int *)opaque;
-+
-+    assert(hid_linux_driver.secure_key);
-+
-+    read_sz = read(fd, event, sizeof (event));
-+    for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
-+      if (event[i].type == EV_KEY && event[i].code < BTN_MOUSE &&
-+              event[i].value > 0)
-+          hid_linux_driver.secure_key(keycode2ascii(event[i].code));
-+}
-+
-+
-+void hid_linux_secure_keyboard(void (*cb)(int ascii))
-+{
-+    hid_linux_driver.secure_key = cb;
-+    if (cb)
-+      hid_linux_redirect_fds(hid_linux_driver.keyboard_fds,
-+              hid_linux_secure_read);
-+    else
-+      hid_linux_redirect_fds(hid_linux_driver.keyboard_fds,
-+              hid_linux_read);
-+}
-+
-+static int hid_linux_grab_devices(int grab, int *fd)
-+{
-+    int rc = 0;
-+    int try = 10;
-+
-+    assert(fd != NULL && *fd != -1);
-+    for (; *fd != -1; fd++)
-+    {
-+      while (try--)
-+      {
-+          if ((rc = ioctl(*fd, EVIOCGRAB, grab)) == -1)
-+          {
-+              char *er;
-+
-+              if (errno == EBUSY)
-+                  continue;
-+              er = strerror(errno);
-+              DEBUG("ioctl(%d, EVOCGRAB) failed, %s\n", *fd, er);
-+              return 0;
-+          }
-+          else
-+              break;
-+      }
-+      assert(try);
-+
-+      DEBUG("ioctl(%d, EVOCGRAB) succed\n", *fd);
-+
-+      if (grab)
-+          qemu_set_fd_handler(*fd, hid_linux_read, NULL, fd);
-+      else
-+          qemu_set_fd_handler(*fd, NULL, NULL, fd);
-+    }
-+    return 1;
-+}
-+
-+int hid_linux_grab_keyboard(int grab)
-+{
-+    return hid_linux_grab_devices(grab, hid_linux_driver.keyboard_fds);
-+}
-+
-+int hid_linux_grab_mouse(int grab)
-+{
-+    return hid_linux_grab_devices(grab, hid_linux_driver.mouse_fds);
-+}
-+
-+static int hid_linux_open_timeout(const char *path, int flags)
-+{
-+   int        try = 10;
-+   int  fd = 0;
-+
-+   while (try-- && ((fd = open(path, flags)) == -1))
-+       usleep(100000); /* 10 ms */
-+   if (try == 0)
-+       return 0;
-+   return fd == -1 ? 0 : fd;
-+}
-+
-+static int hid_linux_ioctl_timeout(int fd, int arg1, void *arg2)
-+{
-+   int        try = 10;
-+
-+   while (try-- && ioctl(fd, arg1, arg2) == -1)
-+       usleep(100000); /* 10 ms */
-+   if (try == 0)
-+       return 0;
-+   return 1;
-+}
-+
-+void hid_linux_probe(int grab)
-+{
-+    int         i = 0, j = 0, c = 0;
-+    int         fd = -1;
-+    int         keyboard = 0, mouse = 0;
-+    char        path[strlen(EVENT_PATH) + 3];
-+    char        name[128];
-+    int               *controllers;
-+    struct stat       st;
-+
-+    while (1)
-+    {
-+      sprintf(path, "%s%i", EVENT_PATH, i++);
-+
-+      if (stat(path, &st) == -1)
-+          break;
-+
-+      for ( c = 0; c < HID_LINUX_MAX_DEV && hid_linux_driver.controller_paths[c]; c++)
-+          if (!strcmp(hid_linux_driver.controller_paths[c], path))
-+              break;
-+      assert(c != HID_LINUX_MAX_DEV);
-+      if (hid_linux_driver.controller_paths[c])
-+          continue;
-+
-+      if ((fd = open(path, O_RDONLY)) == -1)
-+          break;
-+
-+      if (ioctl(fd, EVIOCGNAME(128), name) == -1)
-+      {
-+          DEBUG("Input get name failed on %s\n", path);
-+          break;
-+      }
-+
-+      if (strcasestr(name, "keyboard"))
-+      {
-+          DEBUG("Add %s %s as a keyboard, fd=%d\n", path, name, fd);
-+          controllers = hid_linux_driver.keyboard_fds;
-+      }
-+      else
-+      {
-+          DEBUG("Add %s %s as a mouse, fd=%d\n", path, name, fd);
-+          controllers = hid_linux_driver.mouse_fds;
-+      }
-+
-+      for ( j = 0; j < (HID_LINUX_MAX_DEV / 2) && controllers[j] != -1; j++)
-+          ;
-+      assert(j != (HID_LINUX_MAX_DEV / 2));
-+
-+      controllers[j] = fd;
-+      controllers[j + 1] = -1;
-+
-+      if (grab)
-+      {
-+          if (!hid_linux_grab_devices(1, controllers + j))
-+          {
-+              DEBUG("Grabing failed, try next time...\n");
-+              controllers[j] = -1;
-+              break;
-+          }
-+      }
-+
-+      hid_linux_driver.controller_paths[c] = strdup(path);
-+      hid_linux_driver.controller_paths[c + 1] = NULL;
-+
-+      fd = -1;
-+    }
-+    if (fd != -1)
-+      close(fd);
-+}
-+
-+void hid_linux_init(void)
-+{
-+    hid_linux_driver.keyboard_fds[0] = -1;
-+    hid_linux_driver.mouse_fds[0] = -1;
-+    hid_linux_driver.controller_paths[0] = NULL;
-+
-+    while (hid_linux_driver.keyboard_fds[0] == -1)
-+    {
-+      hid_linux_probe(0);
-+      usleep(100000); /* 10 ms */
-+    }
-+}
-diff --git a/qemu-xen.h b/qemu-xen.h
-index 0cc5dd8..2646ec7 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -107,7 +107,13 @@ int xenstore_write(const char *path, const char *val);
- void xenstore_dm_finished_startup(void);
-- /* `danger' means that this parameter, variable or function refers to
-+char *xenstore_read_dom0_driver(const char *key);
-+int xenstore_write_dom0_driver(const char *key, const char *str);
-+int xenstore_watch_dom0_driver(const char *key, xenstore_callback fptr, void *opaque);
-+
-+int *xenstore_get_domids(int *len);
-+
-+/* `danger' means that this parameter, variable or function refers to
-   * an area of xenstore which is writeable by the guest and thus must
-   * not be trusted by qemu code.  For variables containing xenstore
-   * paths, `danger' can mean that both the path refers to a
-diff --git a/vl.c b/vl.c
-index e519705..0ffe1ec 100644
---- a/vl.c
-+++ b/vl.c
-@@ -234,6 +234,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
- int win2k_install_hack = 0;
- int rtc_td_hack = 0;
- int vga_passthrough = 0;
-+const char *dom0_input = NULL;
- #endif
- int usb_enabled = 0;
- int smp_cpus = 1;
-@@ -278,6 +279,20 @@ uint8_t qemu_uuid[16];
- #include "xen-vl-extra.c"
-+char *get_time(void)
-+{
-+
-+  char buff[128];
-+  char *str;
-+  struct timeval tv;
-+
-+  gettimeofday(&tv, NULL);
-+  str = malloc(256);
-+  strftime(buff, 128, "%T", localtime(&tv.tv_sec));
-+  sprintf(str, "%s:%06d", buff, (int)tv.tv_usec);
-+  return str;
-+}
-+
- /***********************************************************/
- /* x86 ISA bus support */
-@@ -4277,6 +4292,7 @@ enum {
-     QEMU_OPTION_acpi,
-     QEMU_OPTION_vcpus,
-     QEMU_OPTION_vga_passthrough,
-+    QEMU_OPTION_dom0_input,
-     /* Debug/Expert options: */
-     QEMU_OPTION_serial,
-@@ -4451,6 +4467,7 @@ static const QEMUOption qemu_options[] = {
-     { "vncunused", 0, QEMU_OPTION_vncunused },
-     { "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
-     { "vga-passthrough", 0, QEMU_OPTION_vga_passthrough },
-+    { "dom0-input", 1, QEMU_OPTION_dom0_input },
- #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
-     { "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
-     { "xen-create", 0, QEMU_OPTION_xen_create },
-@@ -5287,6 +5304,9 @@ int main(int argc, char **argv, char **envp)
-             case QEMU_OPTION_vga_passthrough:
-                 vga_passthrough = 1;
-                 break;
-+            case QEMU_OPTION_dom0_input:
-+                dom0_input = optarg;
-+                break;
-             case QEMU_OPTION_direct_pci:
-                direct_pci = optarg;
-                 break;
-@@ -6053,6 +6073,9 @@ int main(int argc, char **argv, char **envp)
-         close(fd);
-     }
-+    if (dom0_input)
-+      dom0_driver_init(dom0_input);
-+
-     xenstore_dm_finished_startup();
-     main_loop();
-diff --git a/xen-hooks.mak b/xen-hooks.mak
-index 7c94718..f243df1 100644
---- a/xen-hooks.mak
-+++ b/xen-hooks.mak
-@@ -37,6 +37,8 @@ OBJS += helper2.o
- OBJS += battery_mgmt.o
- OBJS += xen_acpi_wmi.o
- OBJS += thermal_mgmt.o
-+OBJS += dom0_driver.o
-+OBJS += hid-linux.o
- ifdef CONFIG_STUBDOM
- CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
-diff --git a/xenstore.c b/xenstore.c
-index 01afcf0..20ca8cf 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -1727,3 +1727,63 @@ void xenstore_dm_finished_startup(void)
-     free(buf);
-     free(path);
- }
-+
-+char *xenstore_read_dom0_driver(const char *key)
-+{
-+    const char *path = "/local/domain/0/dom0_driver";
-+    char *buf = NULL;
-+    int len = 0;
-+    char *val = NULL;
-+
-+    if (pasprintf(&buf, "%s/%s", path, key) == -1)
-+        return NULL;
-+    val = xs_read(xsh, XBT_NULL, buf, &len);
-+    free(buf);
-+    return val;
-+}
-+
-+int xenstore_watch_dom0_driver(const char *key, xenstore_callback fptr, void *opaque)
-+{
-+    const char *path = "/local/domain/0/dom0_driver";
-+    char *buf = NULL;
-+    int ret = 0;
-+
-+    if (pasprintf(&buf, "%s/%s", path, key) == -1)
-+        return 0;
-+    xenstore_watch_new_callback(buf, fptr, opaque);
-+    free(buf);
-+    return ret;
-+}
-+
-+int xenstore_write_dom0_driver(const char *key, const char *str)
-+{
-+    const char *path = "/local/domain/0/dom0_driver";
-+    char *buf = NULL;
-+    int len = 0;
-+    int ret = 0;
-+
-+    if (pasprintf(&buf, "%s/%s", path, key) == -1)
-+        return 0;
-+    ret = xs_write(xsh, XBT_NULL, buf, str, strlen(str));
-+    free(buf);
-+    return ret;
-+}
-+
-+int *xenstore_get_domids(int *len)
-+{
-+    int *tab = NULL;
-+    char **e;
-+
-+    e = xs_directory(xsh, XBT_NULL, "/local/domain", len);
-+    if (e == NULL)
-+    {
-+        len = 0;
-+        return NULL;
-+    }
-+
-+    tab = malloc(*len * sizeof (int));
-+    for (int i = 0; i < *len; i++)
-+        tab[i] = strtol(e[i], NULL, 10);
-+    return tab;
-+}
-+
diff --git a/xen-3.4/fix-build-warnings b/xen-3.4/fix-build-warnings
deleted file mode 100644 (file)
index 9b2d41c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-diff -Nur a/hw/pci.h b/hw/pci.h
---- a/hw/pci.h 2009-05-13 14:31:58.000000000 -0400
-+++ b/hw/pci.h 2009-05-13 16:51:34.000000000 -0400
-@@ -168,9 +168,13 @@
- #define PCI_STATUS_RESERVED1  0x007
- #define PCI_STATUS_INT_STATUS 0x008
- #define PCI_STATUS_CAPABILITIES       0x010
--#define PCI_STATUS_66MHZ      0x020
-+#ifndef PCI_STATUS_66MHZ
-+#define PCI_STATUS_66MHZ        0x020
-+#endif
- #define PCI_STATUS_RESERVED2  0x040
--#define PCI_STATUS_FAST_BACK  0x080
-+#ifndef PCI_STATUS_FAST_BACK
-+#define PCI_STATUS_FAST_BACK    0x080
-+#endif
- #define PCI_STATUS_DEVSEL     0x600
- #define PCI_STATUS_RESERVED_MASK_LO (PCI_STATUS_RESERVED1 | \
diff --git a/xen-3.4/intel b/xen-3.4/intel
deleted file mode 100644 (file)
index 3520c50..0000000
+++ /dev/null
@@ -1,605 +0,0 @@
-diff --git a/console.h b/console.h
-index 97214c0..4c51c50 100644
---- a/console.h
-+++ b/console.h
-@@ -290,6 +290,9 @@ void vga_hw_update(void);
- void vga_hw_invalidate(void);
- void vga_hw_screen_dump(const char *filename);
-+void unset_vga_acc(void);
-+void set_vga_acc(void);
-+
- int is_graphic_console(void);
- int is_fixedsize_console(void);
- CharDriverState *text_console_init(const char *p);
-@@ -356,4 +359,8 @@ void hid_linux_add_binding(const int *, void (*)(void*), void *);
- void hid_linux_reset_keyboard(void);
- void hid_linux_probe(int grab);
-+/* intel.c */
-+int intel_enter(void);
-+int intel_leave(void);
-+void intel_display_init(DisplayState *ds);
- #endif
-diff --git a/hw/vga.c b/hw/vga.c
-index 90bd544..b0f9f9c 100644
---- a/hw/vga.c
-+++ b/hw/vga.c
-@@ -161,6 +161,18 @@ static uint8_t expand4to8[16];
- static void vga_bios_init(VGAState *s);
- static void vga_screen_dump(void *opaque, const char *filename);
-+static VGAState *xen_vga_state;
-+
-+void set_vga_acc(void)
-+{
-+   set_vram_mapping(xen_vga_state, xen_vga_state->lfb_addr, xen_vga_state->lfb_end);
-+}
-+
-+void unset_vga_acc(void)
-+{
-+   unset_vram_mapping(xen_vga_state);
-+}
-+
- static void vga_dumb_update_retrace_info(VGAState *s)
- {
-     (void) s;
-@@ -2473,8 +2485,6 @@ static void vga_bios_init(VGAState *s)
- }
--static VGAState *xen_vga_state;
--
- /* Allocate video memory in the GPFN space */
- void xen_vga_populate_vram(uint64_t vram_addr, uint32_t vga_ram_size)
- {
-diff --git a/intel.c b/intel.c
-new file mode 100644
-index 0000000..4c5f773
---- /dev/null
-+++ b/intel.c
-@@ -0,0 +1,494 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdint.h>
-+#include <sys/mman.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <assert.h>
-+#include <signal.h>
-+#include <pci/pci.h>
-+
-+#include "qemu-common.h"
-+#include "console.h"
-+#include "sysemu.h"
-+
-+#define INTEL_DEBUG(format, args...)                                    \
-+    fprintf (stderr, "intel.c:%d:%s " format , __LINE__, __func__, ## args)
-+
-+#define TileW           128
-+#define TileH           8
-+
-+#define REG_DR_DSPASURF               0x7019C
-+#define REG_DR_DSPACNTR               0x70180
-+#define REG_DR_DSPASTRIDE     0x70188
-+#define REG_DR_PIPEACONF      0x70008
-+
-+#define REG_DR_DSPBSURF               0x7119C
-+#define REG_DR_DSPBCNTR               0x71180
-+#define REG_DR_DSPBSTRIDE     0x71188
-+#define REG_DR_PIPEBCONF      0x71008
-+
-+#define REG_DE_PIPEASRC               0x6001c
-+
-+extern int                      vga_passthrough;
-+uint32_t                        guest_framebuffer;
-+
-+static int                      display = 0;
-+
-+static int                      mmio_fd = -1;
-+static int                      mem_fd = -1;
-+static uint8_t                  *intel_mem = NULL;
-+static uint8_t                  *intel_mmio = NULL;
-+static int                      intel_force_full_update = 0;
-+static int                      intel_have_focus;
-+static int                      IntelPitch = 16;
-+static int                      IntelX = 1280;
-+static int                      IntelY = 1024;
-+static DisplayState             *lds = NULL;
-+static uint8_t                  *old_data = NULL;
-+static uint32_t                 intel_fb_base, intel_mmio_base;
-+static uint32_t                 map_s, map_d, map_size;
-+static int                      refresh;
-+
-+static void set_data_mappings(void);
-+static void unset_data_mappings(int mapping);
-+static void set_data_pointer(void);
-+static void intel_resize(DisplayState *ds);
-+
-+static inline unsigned int intel_get_reg(unsigned int reg)
-+{
-+    return *(unsigned int*)(intel_mmio + reg);
-+}
-+
-+static inline int is_linear(void)
-+{
-+    unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
-+    if (((*dspacntr) & (1 << 10)) == 0)
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+static inline unsigned int intel_get_pitch(void)
-+{
-+    unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
-+    return *dspastride;
-+}
-+
-+static inline unsigned int intel_get_offset(DisplaySurface *ds, int x, int y)
-+{
-+    return (y * ds->width + x) * 4;
-+}
-+
-+static void intel_update_linear(DisplaySurface *ds, int x, int y, int w, int h)
-+{
-+    int i, bpp = ds->pf.depth / 8;
-+    unsigned char *s, *d;
-+    s = ds->data;
-+    d = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
-+    s += (ds->linesize * y) + bpp * x;
-+    d += (ds->linesize * y) + bpp * x;
-+    for (i = 0; i < h; i++) {
-+        memcpy(d, s, w * bpp);
-+        s += ds->linesize;
-+        d += ds->linesize;
-+    }
-+}
-+
-+static void intel_force_linear(int linesize)
-+{
-+    unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
-+    unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF);
-+    unsigned int *dspasurf = (unsigned int *)(intel_mmio + REG_DR_DSPASURF);
-+    unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
-+
-+    unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
-+    unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF);
-+    unsigned int *dspbsurf = (unsigned int *)(intel_mmio + REG_DR_DSPBSURF);
-+    unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
-+
-+    unsigned int surfa = 0, surfb = 0, pipea = 0, pipeb = 0;
-+    char pipebenabled = !!(*pipebconf & (1 << 30));
-+
-+
-+    INTEL_DEBUG("DSPASURF CTRL: 0x%x\n", intel_get_reg(REG_DR_DSPACNTR));
-+
-+    /* Disable surface */
-+    pipea = *pipeaconf & (0x3 << 18);
-+    *pipeaconf &= ~(0x3 << 18);
-+    *dspacntr |= (1 << 31);
-+    /* Address of the surface to map to */
-+    surfa = *dspasurf;
-+    *dspasurf = 0x00000000;
-+    *dspacntr &= ~(1 << 31);
-+    *dspasurf = 0x00000000;
-+    *pipeaconf |= pipea;
-+
-+    if (pipebenabled) {
-+        INTEL_DEBUG("PIPEBCONF enabled.\n");
-+
-+        /* Disable surface */
-+        pipeb = *pipebconf & (0x3 << 18);
-+        *pipebconf &= ~(0x3 << 18);
-+        *dspbcntr |= (1 << 31);
-+        /* Address of the surface to map to */
-+        surfb = *dspbsurf;
-+        *dspbsurf = 0x00000000;
-+        *dspbcntr &= ~(1 << 31);
-+        *dspbsurf = 0x00000000;
-+        *pipebconf |= pipeb;
-+    }
-+
-+    usleep(20000);
-+
-+    *pipeaconf &= ~(0x3 << 18);
-+    /* Enable surface linear mode */
-+    *dspacntr &= ~(1 << 10);
-+    if (linesize) *dspastride = linesize;
-+    *dspasurf = surfa;
-+    *dspacntr |= (1 << 31);
-+    *pipeaconf |= pipea;
-+
-+    if (pipebenabled) {
-+        *pipebconf &= ~(0x3 << 18);
-+        /* Enable surface linear mode */
-+        *dspbcntr &= ~(1 << 10);
-+        if (linesize) *dspbstride = linesize;
-+        *dspbsurf = surfb;
-+        *dspbcntr |= (1 << 31);
-+        *pipebconf |= pipeb;
-+    }
-+
-+    usleep(20000);
-+}
-+
-+static void intel_update(DisplayState *ds, int x, int y, int w, int h)
-+{
-+    if (intel_have_focus && !old_data && !map_size)
-+        intel_update_linear(ds->surface, x, y, w, h);
-+}
-+
-+static void set_fb_mapping(void)
-+{
-+    DisplaySurface *surf = lds->surface;
-+    int rc;
-+    unsigned long nr_pfn;
-+
-+    unset_vga_acc();
-+    fprintf(stderr, "set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_reg(REG_DR_DSPASURF)), guest_framebuffer);
-+    nr_pfn = (surf->linesize * surf->height) >> TARGET_PAGE_BITS;
-+
-+    rc = xc_domain_memory_mapping(xc_handle,
-+            domid,
-+            (guest_framebuffer >> TARGET_PAGE_BITS),
-+            ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS),
-+            nr_pfn,
-+            DPCI_ADD_MAPPING);
-+    if (rc) {
-+        fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
-+        return;
-+    }
-+    map_s = ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS);
-+    map_d = (guest_framebuffer >> TARGET_PAGE_BITS);
-+    map_size = nr_pfn;
-+}
-+
-+static void unset_fb_mapping(void)
-+{
-+    int rc;
-+
-+    fprintf(stderr, "unset_fb_mapping: %x %x\n", map_d, map_s);
-+
-+    rc = xc_domain_memory_mapping(xc_handle,
-+            domid,
-+            map_d,
-+            map_s,
-+            map_size,
-+            DPCI_REMOVE_MAPPING);
-+    if (rc) {
-+        fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
-+        return;
-+    }
-+
-+    set_vga_acc();
-+    map_s = 0;
-+    map_d = 0;
-+    map_size = 0;
-+}
-+
-+static void intel_setdata(DisplayState *ds)
-+{
-+    if (map_size)
-+        unset_fb_mapping();
-+    set_fb_mapping();
-+}
-+
-+static void intel_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
-+{
-+    DisplaySurface *surf = ds->surface;
-+
-+    if (!intel_have_focus) {
-+        surf->width = w;
-+        surf->height = h;
-+        intel_resize(ds);
-+        return;
-+    }
-+    if (depth == 32 && w == IntelX && h == IntelY)
-+        surf->flags = QEMU_ALLOCATED_FLAG;
-+    else
-+        surf->flags &= ~QEMU_ALLOCATED_FLAG;
-+    if (surf->flags & QEMU_ALLOCATED_FLAG) {
-+        surf->width = w;
-+        surf->height = h;
-+        surf->pf.depth = 32;
-+        surf->linesize = linesize;
-+        /* adjust linesize */
-+        intel_force_linear(linesize);
-+        set_data_mappings();
-+        if (refresh) {
-+            memcpy(surf->data, pixels, surf->linesize * surf->height);
-+            refresh = 0;
-+        }
-+        surf->data = pixels;
-+        intel_setdata(ds);
-+    } else {
-+        surf->width = w;
-+        surf->height = h;
-+        intel_resize(ds);
-+    }
-+}
-+
-+static void intel_resize(DisplayState *ds)
-+{
-+    DisplaySurface *surf = ds->surface;
-+    int old_linesize = surf->linesize;
-+
-+    if (surf->pf.depth == 32 && surf->width == IntelX && surf->height == IntelY)
-+      surf->flags = QEMU_ALLOCATED_FLAG;
-+    else
-+      surf->flags &= ~QEMU_ALLOCATED_FLAG;
-+
-+    if (is_buffer_shared(surf))
-+    {
-+      INTEL_DEBUG("intel_resize_shared: enable shared buffer, linesize %d\n",
-+                  surf->linesize);
-+      intel_force_linear(surf->linesize);
-+      set_data_mappings();
-+      if (refresh)
-+      {
-+        // Pixels doesn't exist anymore ??
-+        //memcpy(surf->data, pixels, surf->linesize * surf->height);
-+        refresh = 0;
-+      }
-+      intel_setdata(ds);
-+      return;
-+    }
-+    
-+    INTEL_DEBUG("intel_resize: no shared buffer, linesize=%d\n", surf->linesize);
-+    surf->linesize = intel_get_pitch();
-+    if (map_size) {
-+        unset_fb_mapping();
-+        unset_data_mappings(1);
-+    }
-+    if (intel_have_focus && !is_linear()) {
-+        intel_force_linear(0);
-+    }
-+    surf->flags &= ~QEMU_ALLOCATED_FLAG;
-+    if (intel_have_focus && !old_data &&
-+        surf->width * surf->height <= IntelX * IntelY)
-+        set_data_mappings();
-+    else if (intel_have_focus && old_data &&
-+             surf->width * surf->height > IntelX * IntelY)
-+        unset_data_mappings(0);
-+    if (!old_data) {
-+        qemu_free(surf->data);
-+        surf->data = qemu_mallocz(surf->height * surf->linesize);
-+    } else {
-+        INTEL_DEBUG("intel_resize: set_data_pointer\n");
-+        set_data_pointer();
-+    }
-+    if (intel_have_focus)
-+        memset((unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)), 0x0, IntelX * IntelY);
-+    if (refresh) {
-+        if (old_data) {
-+            unsigned char *s, *d;
-+            int i;
-+            s = old_data;
-+            d = surf->data;
-+            for (i = 0; i < surf->height; i++) {
-+                memcpy(d, s, surf->width * 4);
-+                s += old_linesize;
-+                d += surf->linesize;
-+            }
-+        }
-+        refresh = 0;
-+    }
-+}
-+
-+static void intel_refresh(DisplayState *ds)
-+{
-+    vga_hw_update();
-+}
-+
-+static void intel_init_mapping(void)
-+{
-+    struct pci_access   *pci_bus;
-+    struct pci_dev      *pci_dev;
-+
-+    mmio_fd = open("/dev/mem", O_RDWR);
-+    if (mmio_fd == -1)
-+    {
-+        perror("open");
-+        exit(1);
-+    }
-+    mem_fd = open("/dev/mem", O_RDWR);
-+    if (mem_fd == -1)
-+    {
-+        perror("open");
-+        exit(1);
-+    }
-+
-+    pci_bus = pci_alloc();
-+    pci_init(pci_bus);
-+    pci_dev = pci_get_dev(pci_bus, 0, 0, 2, 0);
-+    pci_fill_info(pci_dev, PCI_FILL_BASES);
-+    intel_fb_base = pci_dev->base_addr[2] & 0xfffff000;
-+    intel_mmio_base = pci_dev->base_addr[0] & 0xfffff000;
-+    pci_free_dev(pci_dev);
-+    pci_cleanup(pci_bus);
-+
-+    INTEL_DEBUG("Map intel main mem 0x%x\n", intel_fb_base);
-+    intel_mem = mmap(NULL, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED,
-+                     mem_fd, intel_fb_base);
-+    if (intel_mem == MAP_FAILED)
-+    {
-+        perror("mmap");
-+        exit(1);
-+    }
-+
-+    INTEL_DEBUG("Map intel mmio 0x%x\n", intel_mmio_base);
-+    intel_mmio = mmap(NULL, 4 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED,
-+                      mmio_fd, intel_mmio_base);
-+    if (intel_mem == MAP_FAILED)
-+    {
-+        perror("mmap");
-+        exit(1);
-+    }
-+}
-+
-+static void set_data_pointer(void)
-+{
-+    DisplaySurface *surf = lds->surface;
-+
-+    surf->data = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
-+    surf->data = surf->data +
-+                surf->linesize * ((IntelY - surf->height) / 2) +
-+                4 * ((IntelX - surf->width) / 2);
-+}
-+
-+static void set_data_mappings(void)
-+{
-+    INTEL_DEBUG("set_data_mappings\n");
-+    if (!old_data)
-+        old_data = lds->surface->data;
-+    set_data_pointer();
-+}
-+
-+static void unset_data_mappings(int mapping)
-+{
-+    DisplaySurface *surf = lds->surface;
-+    if (!old_data)
-+        return;
-+    if (mapping) {
-+        uint8_t * buffer_pointer = surf->data;
-+        surf->data = old_data;
-+        old_data = NULL;
-+        surf->data = realloc(surf->data, surf->linesize * surf->height);
-+        memcpy(surf->data,
-+                (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)),
-+                surf->linesize * surf->height);
-+        memcpy(buffer_pointer,
-+                surf->data,
-+                surf->linesize * surf->height);
-+    } else {
-+        uint8_t * buffer_pointer = surf->data;
-+        surf->data = old_data;
-+        old_data = NULL;
-+        surf->data = realloc(surf->data, surf->linesize * surf->height);
-+        memcpy(surf->data,
-+                buffer_pointer,
-+                surf->linesize * surf->height);
-+    }
-+    INTEL_DEBUG("unset_data_mappings %d: success\n", mapping);
-+}
-+
-+static int intel_getfocus(void)
-+{
-+    return intel_have_focus;
-+}
-+
-+static void intel_focus(int focus)
-+{
-+    if (intel_have_focus == focus)
-+        return;
-+
-+    INTEL_DEBUG("intel_focus %d\n", focus);
-+    intel_have_focus = focus;
-+    if (focus) {
-+        if (!is_linear()) {
-+          IntelPitch = intel_get_reg(REG_DR_DSPASTRIDE);
-+          IntelX = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1;
-+          IntelY = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1;
-+          INTEL_DEBUG("Resolution is %dx%d\n", IntelX, IntelY);
-+        }
-+        refresh = 1;
-+        lds->listeners->dpy_resize = intel_resize;
-+        lds->listeners->dpy_setdata = intel_setdata;
-+        vga_hw_invalidate();
-+    } else {
-+        if (map_size) {
-+            unset_fb_mapping();
-+            unset_data_mappings(1);
-+        } else if (old_data) {
-+            unset_data_mappings(0);
-+        }
-+        lds->listeners->dpy_resize = NULL;
-+        lds->listeners->dpy_setdata = NULL;
-+        lds->surface->flags &= ~QEMU_ALLOCATED_FLAG;
-+    }
-+}
-+
-+int intel_enter(void)
-+{
-+    intel_focus(1);
-+    return 1;
-+}
-+
-+int intel_leave(void)
-+{
-+    intel_focus(0);
-+    return 1;
-+}
-+
-+void intel_display_init(DisplayState *ds)
-+{
-+    DisplaySurface *surf = ds->surface;
-+
-+    INTEL_DEBUG("\n");
-+
-+    intel_init_mapping();
-+
-+    INTEL_DEBUG("Frambuffer is at 0x%x\n", intel_get_reg(REG_DR_DSPASURF));
-+
-+    surf->flags = 0;
-+    surf->width = 640;
-+    surf->height = 480;
-+    surf->pf.depth = 32;
-+    intel_resize(ds);
-+    lds = ds;
-+
-+    ds->listeners->dpy_update = intel_update;
-+    ds->listeners->dpy_resize = intel_resize;
-+    ds->listeners->dpy_refresh = intel_refresh;
-+}
-diff --git a/vl.c b/vl.c
-index 0ffe1ec..d6379a9 100644
---- a/vl.c
-+++ b/vl.c
-@@ -235,6 +235,7 @@ int win2k_install_hack = 0;
- int rtc_td_hack = 0;
- int vga_passthrough = 0;
- const char *dom0_input = NULL;
-+int intel = 0;
- #endif
- int usb_enabled = 0;
- int smp_cpus = 1;
-@@ -4293,6 +4294,7 @@ enum {
-     QEMU_OPTION_vcpus,
-     QEMU_OPTION_vga_passthrough,
-     QEMU_OPTION_dom0_input,
-+    QEMU_OPTION_intel,
-     /* Debug/Expert options: */
-     QEMU_OPTION_serial,
-@@ -4468,6 +4470,7 @@ static const QEMUOption qemu_options[] = {
-     { "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
-     { "vga-passthrough", 0, QEMU_OPTION_vga_passthrough },
-     { "dom0-input", 1, QEMU_OPTION_dom0_input },
-+    { "intel", 0, QEMU_OPTION_dom0_input },
- #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
-     { "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
-     { "xen-create", 0, QEMU_OPTION_xen_create },
-@@ -5307,6 +5310,9 @@ int main(int argc, char **argv, char **envp)
-             case QEMU_OPTION_dom0_input:
-                 dom0_input = optarg;
-                 break;
-+            case QEMU_OPTION_intel:
-+                intel = 1;
-+                break;
-             case QEMU_OPTION_direct_pci:
-                direct_pci = optarg;
-                 break;
-diff --git a/xen-hooks.mak b/xen-hooks.mak
-index f243df1..55dd477 100644
---- a/xen-hooks.mak
-+++ b/xen-hooks.mak
-@@ -39,6 +39,7 @@ OBJS += xen_acpi_wmi.o
- OBJS += thermal_mgmt.o
- OBJS += dom0_driver.o
- OBJS += hid-linux.o
-+OBJS += intel.o
- ifdef CONFIG_STUBDOM
- CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
diff --git a/xen-3.4/ioemu-compil b/xen-3.4/ioemu-compil
deleted file mode 100644 (file)
index 477838b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-diff --git a/xen-hooks.mak b/xen-hooks.mak
-index c6b4f8c..d2f09fb 100644
---- a/xen-hooks.mak
-+++ b/xen-hooks.mak
-@@ -52,7 +52,7 @@ endif
- ifdef CONFIG_STUBDOM
- CONFIG_PASSTHROUGH=1
- else
--  ifeq (,$(wildcard /usr/include/pci))
-+  ifeq (,$(wildcard $(PCI_PREFIX_DIR)/usr/include/pci))
- $(warning === pciutils-dev package not found - missing /usr/include/pci)
- $(warning === PCI passthrough capability has been disabled)
-   else
-@@ -62,6 +62,9 @@ endif
- ifdef CONFIG_PASSTHROUGH
- OBJS+= pass-through.o pt-msi.o
-+ifdef PCI_PREFIX_DIR
-+LIBS += -L$(PCI_PREFIX_DIR)/usr/lib
-+endif
- LIBS += -lpci
- CFLAGS += -DCONFIG_PASSTHROUGH 
- $(info === PCI passthrough capability has been enabled ===)
-diff --git a/xen-setup b/xen-setup
-index 8ca0019..24defda 100755
---- a/xen-setup
-+++ b/xen-setup
-@@ -9,7 +9,7 @@ rm -f config-host.mak
- if test -f config-host.h; then mv config-host.h config-host.h~; fi
--./configure --disable-gfx-check --disable-curses --disable-slirp "$@" --prefix=/usr
-+./configure --disable-gfx-check --disable-curses --disable-slirp --disable-vnc-tls --disable-sdl "$@" --prefix=/usr
- target=i386-dm
-@@ -17,6 +17,8 @@ if [ "x$XEN_ROOT" != x ]; then
-       echo "XEN_ROOT=$XEN_ROOT" >>config-host.mak
- fi
-+echo "PCI_PREFIX_DIR=${STAGING_ROOT}" >>config-host.mak
-+
- ln -sf ../Makefile.target $target/Makefile
- ln -sf ../xen-config.mak $target/config.mak
- cat xen-config-host.mak >>config-host.mak
diff --git a/xen-3.4/oem-features b/xen-3.4/oem-features
deleted file mode 100644 (file)
index 7110652..0000000
+++ /dev/null
@@ -1,973 +0,0 @@
-diff --git a/hw/acpi-wmi.h b/hw/acpi-wmi.h
-new file mode 100644
-index 0000000..af99c1c
---- /dev/null
-+++ b/hw/acpi-wmi.h
-@@ -0,0 +1,99 @@
-+/******************************************************************************
-+ * acpi-wmi.h
-+ *
-+ * Interface to /proc/misc/xen-acpi-wmi
-+ *
-+ * Copyright (c) 2009 Kamala Narasimhan
-+ * Copyright (c) 2009 Citrix Systems, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+/*  NOTE:  This header is a duplicate of drivers/xen/acpi-wmi/acpi-wmi.h in our
-+ *  kernel repo.  As we don't share headers between kernel and userspace, we have
-+ *  the same header in two places.  It is important to keep the two headers in sync
-+ *  to avoid incompatibilities.
-+ */ 
-+
-+#ifndef _XEN_WMI_ACPI
-+#define _XEN_WMI_ACPI
-+
-+/*
-+ * Userspace Interface
-+ */
-+
-+#define XEN_WMI_DEVICE_NAME              "xen-acpi-wmi"
-+#define XEN_WMI_GUID_SIZE                16
-+
-+#define XEN_WMI_SUCCESS                  0
-+#define XEN_WMI_UNSUPPORTED_TYPE        -1
-+#define XEN_WMI_BUFFER_TOO_SMALL        -11
-+#define XEN_WMI_NOT_ENOUGH_MEMORY       -12
-+#define XEN_WMI_EFAULT                  -14
-+#define XEN_WMI_INVALID_ARGUMENT        -22
-+#define XEN_WMI_ENOIOCTLCMD             -515
-+ 
-+#define XEN_WMI_IOCTL_CALL_METHOD        100
-+#define XEN_WMI_IOCTL_QUERY_OBJECT       101
-+#define XEN_WMI_IOCTL_SET_OBJECT         102
-+#define XEN_WMI_IOCTL_GET_EVENT_DATA     103
-+
-+typedef unsigned char byte;
-+
-+typedef struct xen_wmi_buffer {
-+    size_t       length; 
-+    void        *pointer;
-+    size_t      *copied_length;
-+} xen_wmi_buffer_t;
-+
-+typedef struct xen_wmi_obj_invocation_data { 
-+    byte                       guid[XEN_WMI_GUID_SIZE];
-+    union {
-+        struct {
-+            ushort             instance;
-+            uint               method_id;
-+            xen_wmi_buffer_t   in_buf;
-+            xen_wmi_buffer_t   out_buf;
-+        } xen_wmi_method_arg;
-+
-+        struct {
-+            ushort             instance;
-+            xen_wmi_buffer_t   out_buf;
-+        } xen_wmi_query_obj_arg;
-+
-+        struct {
-+            ushort             instance;
-+            xen_wmi_buffer_t   in_buf;
-+        } xen_wmi_set_obj_arg;
-+
-+        struct {
-+            ushort             event_id;
-+            xen_wmi_buffer_t   out_buf;
-+        } xen_wmi_event_data_arg;
-+    } xen_wmi_arg;
-+} xen_wmi_obj_invocation_data_t;
-+
-+#endif /* _XEN_WMI_ACPI */
-+
-diff --git a/hw/pc.h b/hw/pc.h
-index a261c8a..2e3cade 100644
---- a/hw/pc.h
-+++ b/hw/pc.h
-@@ -111,6 +111,8 @@ void acpi_power_button_pressed(void);
- void acpi_sleep_button_pressed(void);
- void acpi_lid_state_changed(void);
-+void acpi_oem_event(void);
-+
- /* hpet.c */
- extern int no_hpet;
-diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index c218782..cf214a4 100644
---- a/hw/piix4acpi.c
-+++ b/hw/piix4acpi.c
-@@ -29,6 +29,7 @@
- #include "sysemu.h"
- #include "qemu-xen.h"
- #include "battery_mgmt.h"
-+#include "xen_acpi_wmi.h"
- #include <xen/hvm/ioreq.h>
- #include <xen/hvm/params.h>
-@@ -58,6 +59,7 @@
- #define ACPI_POWER_BUTTON_BIT 0x1
- #define ACPI_SLEEP_BUTTON_BIT 0x0
- #define ACPI_LID_STATE_BIT 0x17
-+#define ACPI_OEM_EVENT_BIT 0x18
- typedef struct AcpiDeviceState AcpiDeviceState;
- AcpiDeviceState *acpi_device_table;
-@@ -195,6 +197,7 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
-     register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
-     battery_mgmt_init(pci_dev);
-+    xen_acpi_wmi_init(pci_dev);
- }
- static inline int test_bit(uint8_t *map, int bit)
-@@ -261,6 +262,19 @@ void acpi_lid_state_changed(void)
-     }
- }
-+void acpi_oem_event(void)
-+{
-+    GPEState *s = &gpe_state;
-+
-+    if ( !test_bit(&s->gpe0_sts[0], ACPI_OEM_EVENT_BIT) &&
-+          test_bit(&s->gpe0_en[0], ACPI_OEM_EVENT_BIT) ) {
-+        set_bit(&s->gpe0_sts[0], ACPI_OEM_EVENT_BIT);
-+        s->sci_asserted = 1;
-+        fprintf(logfile, "Raising oem event irq\n");
-+        qemu_irq_raise(sci_irq);
-+    }
-+}
-+
- #ifdef CONFIG_PASSTHROUGH
- static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
-diff --git a/hw/xen_acpi_wmi.c b/hw/xen_acpi_wmi.c
-new file mode 100644
-index 0000000..e759e89
---- /dev/null
-+++ b/hw/xen_acpi_wmi.c
-@@ -0,0 +1,654 @@
-+/*
-+ * xen_acpi_wmi.c
-+ *
-+ * Copyright (c) 2009  Kamala Narasimhan
-+ * Copyright (c) 2009  Citrix Systems, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+/* Xen ACPI WMI implementation - 
-+ * OEMs expose their value add functionalites through firmware level WMI 
-+ * acpi objects.  To support the underlying OEM value add within guest 
-+ * space, we expose a WMI psuedo device object at our vACPI layer.  That 
-+ * vACPI layer relies on the below implementation to communication to the
-+ * base firmware (through xen wmi module and linux acpi wmi wrapper 
-+ * driver) either it be to execute a WMI method or query or set 
-+ * data or recieve wmi event data. 
-+ */
-+
-+/* NOTE:  As the vACPI layer is written to send request and take response in a 
-+ * synchronized way, there isn't a need to add synchronization logic here.
-+ */
-+
-+#include "hw.h"
-+#include "pc.h"
-+#include "qemu-xen.h"
-+#include "isa.h" 
-+#include "xen_acpi_wmi.h"
-+#include <sys/ioctl.h>
-+
-+#ifndef CONFIG_NO_XEN_ACPI_WMI
-+
-+#define XEN_WMI_DEFAULT_OUTPUT_BUFFER_SIZE 256
-+
-+static xen_acpi_wmi_cmd_info_t cmd_info;
-+static int xen_wmi_device = -ENODEV;  
-+extern FILE *logfile;
-+
-+/* #define XEN_ACPI_WMI_DEBUG */
-+/* #define XEN_ACPI_WMI_DEBUG_EXT */
-+
-+/*
-+ * xen_acpi_wmi_set_guid
-+ */
-+void xen_acpi_wmi_set_guid(uint8_t val)
-+{
-+    if ( cmd_info.invocation_type == XEN_ACPI_WMI_UNDEFINED )
-+    {
-+        fprintf(logfile, 
-+            "XEN WMI: Unable to set guid with invalid invocation type!\n");
-+        return;
-+    }
-+
-+    if ( cmd_info.current_index >= XEN_WMI_GUID_SIZE )
-+    {
-+        fprintf(logfile, "XEN WMI: Guid array index out of range - %d!!!\n", 
-+                cmd_info.current_index);
-+        cmd_info.invocation_type = XEN_ACPI_WMI_UNDEFINED;  
-+        return;
-+    }
-+
-+    cmd_info.invocation_data.guid[cmd_info.current_index] = val;
-+    cmd_info.current_index++;
-+}
-+
-+/*
-+ * xen_acpi_wmi_set_cmd_instance
-+ */
-+void xen_acpi_wmi_set_cmd_instance(uint32_t val)
-+{
-+    if ( cmd_info.invocation_type == XEN_ACPI_WMI_UNDEFINED ) 
-+    {
-+        fprintf(logfile, 
-+            "XEN WMI: Unable to set cmd instance with invalid invocation type!\n");
-+        return;
-+    }
-+
-+    switch( cmd_info.invocation_type )
-+    {
-+        case XEN_ACPI_WMI_EXEC_METHOD:
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.instance = val;
-+            break;
-+        case XEN_ACPI_WMI_QUERY_OBJECT:
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_query_obj_arg.instance = val;
-+            break;
-+        case XEN_ACPI_WMI_SET_OBJECT:
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.instance = val;
-+            break;
-+        default:
-+            fprintf(logfile, 
-+                "Invalid attempt to set instance for current invocation type!\n");
-+            break;
-+    }
-+}
-+
-+/*
-+ * xen_acpi_wmi_set_method_id
-+ */
-+void xen_acpi_wmi_set_method_id(uint32_t val)
-+{
-+    if ( cmd_info.invocation_type != XEN_ACPI_WMI_EXEC_METHOD )
-+    {
-+        fprintf(logfile,
-+            "Unable to set method id for the current invocation type!\n");
-+        return;
-+    }
-+
-+    cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.method_id = val;
-+}
-+
-+/*
-+ * xen_acpi_wmi_get_input_buffer
-+ */
-+xen_wmi_buffer_t *xen_acpi_wmi_get_input_buffer(void)
-+{
-+    if ( cmd_info.invocation_type != XEN_ACPI_WMI_EXEC_METHOD  &&
-+         cmd_info.invocation_type != XEN_ACPI_WMI_SET_OBJECT )
-+        return 0;
-+
-+    if ( cmd_info.invocation_type == XEN_ACPI_WMI_EXEC_METHOD )
-+        return &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.in_buf;
-+    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_SET_OBJECT )
-+        return &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.in_buf;
-+
-+    return 0;
-+}
-+
-+/*
-+ * xen_acpi_wmi_set_buffer_size
-+ * Guest vACPI layer passes to us the size of the input buffer it is 
-+ * about to transfer to ioemu  and this method stores the passed in size  
-+ * apart from allocating a buffer with the provided size. 
-+ */
-+void xen_acpi_wmi_set_in_buffer_size(uint32_t val)
-+{
-+    xen_wmi_buffer_t *buffer;
-+
-+    buffer = xen_acpi_wmi_get_input_buffer();
-+    if ( buffer == NULL )
-+        return;
-+
-+    cmd_info.current_index = 0;
-+    buffer->length = val;
-+    buffer->pointer = malloc(val); 
-+}
-+
-+/*
-+ * xen_acpi_wmi_set_in_buffer
-+ */
-+void xen_acpi_wmi_set_in_buffer(uint8_t val)
-+{
-+    xen_wmi_buffer_t *buffer;
-+
-+    buffer = xen_acpi_wmi_get_input_buffer();
-+    if ( buffer == NULL )
-+        return;
-+
-+    if ( cmd_info.current_index >= buffer->length )
-+    {
-+        fprintf(logfile, 
-+            "XEN WMI: Cannot write beyond allocated input buffer size!!!\n");
-+        return;
-+    }
-+
-+    ((byte *)buffer->pointer)[cmd_info.current_index] = val;
-+    cmd_info.current_index++;
-+}
-+
-+/*
-+ * xen_wmi_get_output_buffer
-+ */
-+xen_wmi_buffer_t *xen_acpi_wmi_get_output_buffer(void)
-+{
-+    if ( cmd_info.invocation_type != XEN_ACPI_WMI_EXEC_METHOD &&
-+         cmd_info.invocation_type != XEN_ACPI_WMI_QUERY_OBJECT &&
-+         cmd_info.invocation_type != XEN_ACPI_WMI_GET_EVENT_DATA )
-+    {
-+        fprintf(logfile,
-+            "XEN WMI: Output buffer not available for current invocation type!\n"); 
-+        return 0;
-+    }
-+
-+    if ( cmd_info.invocation_type == XEN_ACPI_WMI_EXEC_METHOD )
-+        return  &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.out_buf;
-+    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_QUERY_OBJECT )
-+        return &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_query_obj_arg.out_buf;
-+    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_GET_EVENT_DATA )
-+        return  &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_event_data_arg.out_buf;
-+
-+    return 0;
-+}
-+
-+/*
-+ * xen_acpi_wmi_allocate_output_buffer
-+ */
-+void xen_acpi_wmi_allocate_output_buffer(size_t length)
-+{
-+    xen_wmi_buffer_t *buffer;
-+
-+    buffer = xen_acpi_wmi_get_output_buffer();
-+    if ( buffer == NULL )
-+        return;
-+
-+    buffer->length = (length > 0) ? length : XEN_WMI_DEFAULT_OUTPUT_BUFFER_SIZE;
-+    buffer->pointer = malloc(buffer->length); 
-+    memset(buffer->pointer, 0, buffer->length);
-+
-+    buffer->copied_length = malloc(sizeof(size_t));
-+    memset(buffer->copied_length, 0, sizeof(size_t));
-+}
-+
-+/*
-+ * xen_acpi_wmi_reallocate_output_buffer
-+ */
-+int xen_acpi_wmi_reallocate_output_buffer(void)
-+{
-+    xen_wmi_buffer_t *buffer;
-+
-+    buffer = xen_acpi_wmi_get_output_buffer();
-+    if ( buffer == NULL || buffer->copied_length == NULL || buffer->pointer == NULL )
-+        return XEN_WMI_NOT_ENOUGH_MEMORY; 
-+
-+    /* If required length is less than allocated length,
-+     * we shouldn't have failed; no point in rellocating.
-+     * @TODO: Rename copied_length to something more appropriate.
-+     */
-+    if ( *buffer->copied_length <= buffer->length )
-+        return XEN_WMI_NOT_ENOUGH_MEMORY;
-+
-+    free(buffer->pointer);
-+    buffer->pointer = malloc(*buffer->copied_length);
-+    memset(buffer->pointer, 0, *buffer->copied_length);
-+    buffer->length = *buffer->copied_length;
-+    return XEN_WMI_SUCCESS;
-+}
-+
-+/*
-+ * xen_acpi_wmi_free_input_buffer 
-+ */
-+void xen_acpi_wmi_free_input_buffer(void)
-+{
-+    xen_wmi_buffer_t *buffer;
-+
-+    buffer = xen_acpi_wmi_get_input_buffer();
-+    if ( buffer == NULL )
-+        return;
-+
-+    if ( buffer->length > 0 )
-+        free(buffer->pointer);
-+    buffer->length = 0;
-+}
-+
-+#ifdef XEN_ACPI_WMI_DEBUG
-+
-+/*
-+ * xen_acpi_wmi_print_input_buffer
-+ */
-+void xen_acpi_wmi_print_input_buffer(xen_wmi_buffer_t *in_buf)
-+{
-+    int count;
-+
-+    fprintf(logfile, "In buffer length - %d\n", in_buf->length);
-+    fprintf(logfile, "In buffer:  ");
-+    for( count = 0; count < in_buf->length; count++ )
-+        fprintf(logfile, " %d,  ", ((byte *)in_buf->pointer)[count]);
-+    fprintf(logfile, "\n");
-+}
-+
-+/*
-+ * xen_acpi_wmi_print_input_info
-+ */
-+void xen_acpi_wmi_print_input_info(void)
-+{
-+    int count;
-+
-+    fprintf(logfile, "Command invocation type - %d\n", cmd_info.invocation_type);
-+    fprintf(logfile, "Invocation Data:  \n");
-+    fprintf(logfile, "Guid: ");
-+
-+    for (count=0; count < XEN_WMI_GUID_SIZE; count++)
-+        fprintf(logfile,"%d  ", cmd_info.invocation_data.guid[count]);
-+
-+    fprintf(logfile, "\n");
-+
-+    if ( cmd_info.invocation_type == XEN_ACPI_WMI_EXEC_METHOD )
-+    {
-+        fprintf(logfile, 
-+            "Instance id - %d\n", 
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.instance);
-+        fprintf(logfile,
-+            "Method id - %d\n", 
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.method_id);
-+        xen_acpi_wmi_print_input_buffer(
-+            &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_method_arg.in_buf);
-+    }
-+    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_QUERY_OBJECT )
-+    {
-+        fprintf(logfile,
-+            "Instance id - %d\n", 
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_query_obj_arg.instance);
-+    }
-+    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_SET_OBJECT )
-+    {
-+        fprintf(logfile,
-+            "Instance id - %d\n", 
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.instance);
-+        xen_acpi_wmi_print_input_buffer(
-+            &cmd_info.invocation_data.xen_wmi_arg.xen_wmi_set_obj_arg.in_buf);
-+    }
-+    else if ( cmd_info.invocation_type == XEN_ACPI_WMI_GET_EVENT_DATA )
-+    {
-+        fprintf(logfile,
-+            "Event id - %d\n",
-+            cmd_info.invocation_data.xen_wmi_arg.xen_wmi_event_data_arg.event_id);
-+    } 
-+}
-+
-+/*
-+ * xen_acpi_wmi_print_output_buffer
-+ */
-+void xen_acpi_wmi_print_output_buffer(void)
-+{
-+    int count;
-+    xen_wmi_buffer_t *buffer = xen_acpi_wmi_get_output_buffer();
-+
-+    if ( buffer == NULL || buffer->copied_length == NULL || *buffer->copied_length == 0 )
-+        return;
-+
-+    fprintf(logfile, "XEN WMI: Output buffer size is - %d\n",
-+            *buffer->copied_length);
-+    fprintf(logfile, "XEN WMI output buffer is - ");
-+    for (count=0; count < *buffer->copied_length; count++)
-+        fprintf(logfile," %d, ", ((byte *)buffer->pointer)[count]);
-+
-+    fprintf(logfile, "\n");
-+}
-+
-+#endif /* XEN_ACPI_WMI_DEBUG */
-+
-+/*
-+ * xen_acpi_wmi_execute
-+ */
-+void xen_acpi_wmi_execute(void)
-+{
-+    int request, ret;
-+
-+    if ( cmd_info.invocation_type == XEN_ACPI_WMI_UNDEFINED )
-+    {
-+        fprintf(logfile,
-+            "Unable to execute command for the given invocation type!\n");
-+        return;
-+    }
-+
-+    switch ( cmd_info.invocation_type )
-+    {
-+        case XEN_ACPI_WMI_EXEC_METHOD:
-+            request = XEN_WMI_IOCTL_CALL_METHOD;
-+            break;
-+        case XEN_ACPI_WMI_QUERY_OBJECT:
-+            request = XEN_WMI_IOCTL_QUERY_OBJECT; 
-+            break;
-+        case XEN_ACPI_WMI_SET_OBJECT:
-+            request = XEN_WMI_IOCTL_SET_OBJECT;
-+            break;
-+        case XEN_ACPI_WMI_GET_EVENT_DATA:
-+            request = XEN_WMI_IOCTL_GET_EVENT_DATA;
-+            break;
-+        default:
-+            fprintf(logfile,
-+                "Unable to execute command for the given invocation type!\n");
-+            return;
-+    } 
-+
-+    xen_acpi_wmi_allocate_output_buffer(0);
-+#ifdef XEN_ACPI_WMI_DEBUG
-+    fprintf(logfile, "XEN WMI Invoking ioctl - %d\n", cmd_info.invocation_type);
-+    xen_acpi_wmi_print_input_info();
-+#endif
-+    ret = ioctl(xen_wmi_device, request, &cmd_info.invocation_data);
-+    if ( ret == XEN_WMI_BUFFER_TOO_SMALL )
-+    {
-+        if ( xen_acpi_wmi_reallocate_output_buffer() == XEN_WMI_SUCCESS )
-+            ret = ioctl(xen_wmi_device, request, &cmd_info.invocation_data);
-+    }
-+
-+    if ( ret != XEN_WMI_SUCCESS )
-+        fprintf(logfile, "Xen WMI ioctl failed with error - %d\n", ret);
-+
-+#ifdef XEN_ACPI_WMI_DEBUG
-+    xen_acpi_wmi_print_output_buffer();
-+#endif
-+
-+    xen_acpi_wmi_free_input_buffer();
-+}
-+
-+/*
-+ * xen_acpi_wmi_set_event_id
-+ */
-+void xen_acpi_wmi_set_event_id(uint8_t event_id)
-+{
-+    if ( cmd_info.invocation_type != XEN_ACPI_WMI_GET_EVENT_DATA )
-+    {
-+        fprintf(logfile, 
-+            "XEN WMI: Request to set event ID with incorrect invocation type!!!\n");        
-+        return;
-+    }
-+
-+    cmd_info.invocation_data.xen_wmi_arg.xen_wmi_event_data_arg.event_id = event_id;
-+}
-+
-+/*
-+ * xen_acpi_wmi_cmd_port_read
-+ */
-+static uint32_t xen_acpi_wmi_cmd_port_read(void *opaque, uint32_t addr)
-+{
-+#ifdef XEN_ACPI_WMI_DEBUG_EXT
-+    fprintf(logfile, "XEN WMI: In cmd port read - %d\n",
-+        cmd_info.cmd_type);
-+#endif
-+    return cmd_info.cmd_type;
-+}   
-+
-+/*
-+ * xen_acpi_wmi_cmd_port_write
-+ */
-+static void xen_acpi_wmi_cmd_port_write(void *opaque, uint32_t addr, uint32_t val)
-+{
-+#ifdef XEN_ACPI_WMI_DEBUG_EXT
-+    fprintf(logfile, "XEN WMI: In cmd port write - %d\n", val);
-+#endif
-+    cmd_info.cmd_type = val;
-+    if ( val < XEN_ACPI_WMI_CMD_INIT || val >= XEN_ACPI_WMI_CMD_UNDEFINED )
-+    {
-+        fprintf(logfile,"XEN WMI: Unknown xen acpi wmi command - %d\n", val);
-+        cmd_info.invocation_type = XEN_ACPI_WMI_UNDEFINED;
-+        cmd_info.current_index = 0;
-+        return; 
-+    } 
-+
-+    if ( val == XEN_ACPI_WMI_CMD_EXECUTE )
-+        xen_acpi_wmi_execute();
-+}
-+
-+/*
-+ * xen_acpi_wmi_data_port_readb
-+ */
-+static uint32_t xen_acpi_wmi_data_port_readb(void *opaque, uint32_t addr)
-+{
-+    xen_wmi_buffer_t *buffer;
-+    byte ret;
-+
-+    if ( cmd_info.cmd_type == XEN_ACPI_WMI_CMD_OUT_BUFFER )
-+    {
-+        buffer = xen_acpi_wmi_get_output_buffer();
-+        if ( buffer == NULL || buffer->copied_length == NULL )
-+            return 0x0;
-+
-+        if ( *buffer->copied_length == 0 )
-+            return 0x0;
-+
-+        if ( cmd_info.current_index >= *buffer->copied_length )
-+        {
-+            fprintf(logfile, 
-+                "XEN WMI: Output buffer index overflow. Current - %d Max - %d\n",
-+                 cmd_info.current_index, *buffer->copied_length);
-+            cmd_info.cmd_type = XEN_ACPI_WMI_CMD_UNDEFINED; 
-+            return 0x0;
-+        }
-+
-+        ret = ((byte*)buffer->pointer)[cmd_info.current_index];
-+        if ( cmd_info.current_index == buffer->length-1 )
-+        {
-+            /* @TODO: We expect that the firmware would read all of
-+             * the output buffer before releasing it.  This
-+             * could result in a leak if the firmware chooses
-+             * to ignore the return buffer. It might make sense to
-+             * introduce a cleanup command. */ 
-+            cmd_info.cmd_type = XEN_ACPI_WMI_CMD_UNDEFINED; 
-+            buffer->length = 0;
-+            free(buffer->pointer);
-+            buffer->pointer = NULL;
-+            free(buffer->copied_length);
-+            buffer->copied_length = NULL;
-+        }
-+
-+#ifdef XEN_ACPI_WMI_DEBUG_EXT 
-+        fprintf(logfile, "XEN WMI: Data port read returned - %d\n", ret);
-+#endif
-+        cmd_info.current_index++;
-+        return ret;
-+    } 
-+
-+    fprintf(logfile, "XEN WMI: Data port read byte.  Shouldn't be here!!!\n");
-+    return 0x0;
-+}  
-+
-+/*
-+ * xen_acpi_wmi_data_port_writeb
-+ */
-+static void xen_acpi_wmi_data_port_writeb(void *opaque, uint32_t addr, uint32_t val)
-+{
-+#ifdef XEN_ACPI_WMI_DEBUG_EXT
-+    fprintf(logfile, "XEN WMI: In data port write byte - %d\n", val);
-+#endif
-+
-+    switch( cmd_info.cmd_type )
-+    {
-+        case XEN_ACPI_WMI_CMD_INIT:
-+            cmd_info.invocation_type = val;
-+            cmd_info.current_index = 0;
-+            memset(&cmd_info.invocation_data, 0, sizeof(cmd_info.invocation_data));
-+            break;
-+        case XEN_ACPI_WMI_CMD_GUID:
-+            xen_acpi_wmi_set_guid(val);
-+            break;
-+        case XEN_ACPI_WMI_CMD_IN_BUFFER:
-+            xen_acpi_wmi_set_in_buffer(val);
-+            break;
-+        case XEN_ACPI_WMI_CMD_EVENT_ID:
-+            xen_acpi_wmi_set_event_id(val);
-+            break;
-+        default:
-+            fprintf(logfile, 
-+                "XEN WMI: Attempting to write to data(byte) port with incompatible cmd type %d\n",    
-+                    cmd_info.cmd_type);
-+             break;
-+    }    
-+}
-+
-+/*
-+ * xen_acpi_wmi_data_port_readl
-+ */
-+static uint32_t xen_acpi_wmi_data_port_readl(void *opaque, uint32_t addr)
-+{
-+    xen_wmi_buffer_t *buffer;
-+
-+    if ( cmd_info.cmd_type == XEN_ACPI_WMI_CMD_OUT_BUFFER_SIZE )
-+    {
-+        buffer = xen_acpi_wmi_get_output_buffer();
-+        if ( buffer == NULL || buffer->copied_length == NULL )
-+            return 0x0;
-+
-+        if (*buffer->copied_length == 0 )
-+            return 0x0;
-+
-+        cmd_info.current_index = 0;
-+#ifdef XEN_ACPI_WMI_DEBUG_EXT
-+       fprintf(logfile, "XEN WMI: Output buffer length is - %d\n", *buffer->copied_length);
-+#endif
-+        return *buffer->copied_length;
-+    }
-+
-+    fprintf(logfile, "XEN WMI: Data port read long.  Shouldn't be here!!!\n");
-+    return 0x0;
-+} 
-+
-+/*
-+ * xen_acpi_wmi_data_port_writel
-+ */
-+static void xen_acpi_wmi_data_port_writel(void *opaque, uint32_t addr, uint32_t val)
-+{
-+#ifdef XEN_ACPI_WMI_DEBUG_EXT
-+    fprintf(logfile, "XEN WMI: In data port write long - %d\n", val);
-+#endif
-+
-+    switch( cmd_info.cmd_type )
-+    {
-+        case XEN_ACPI_WMI_CMD_OBJ_INSTANCE:
-+            xen_acpi_wmi_set_cmd_instance(val);
-+            break;
-+        case XEN_ACPI_WMI_CMD_METHOD_ID:
-+            xen_acpi_wmi_set_method_id(val);
-+            break;
-+        case XEN_ACPI_WMI_CMD_IN_BUFFER_SIZE:
-+            xen_acpi_wmi_set_in_buffer_size(val);
-+            break;
-+        default:
-+            fprintf(logfile,
-+                "XEN WMI: Attempting to write to data(long) port with incompatible cmd type %d\n",
-+                    cmd_info.cmd_type);
-+             break;
-+    }
-+}
-+
-+/*
-+ * xen_acpi_wmi_init
-+ */
-+void xen_acpi_wmi_init(PCIDevice *device)
-+{
-+    char dev_name[64];
-+    char *oem_buffer;
-+
-+    cmd_info.invocation_type = XEN_ACPI_WMI_UNDEFINED;
-+    cmd_info.current_index = 0;
-+
-+    oem_buffer = xenstore_device_model_read(domid, "oem_features", NULL);
-+    if ( oem_buffer == NULL )
-+    {
-+#ifdef XEN_ACPI_WMI_DEBUG 
-+        fprintf(logfile,"OEM value add disabled!\n");
-+#endif
-+        return;
-+    }
-+
-+    sprintf(dev_name, "/dev/%s", XEN_WMI_DEVICE_NAME);
-+    xen_wmi_device = open(dev_name, 0);
-+    if ( xen_wmi_device < 0 )
-+    {
-+        fprintf(logfile, 
-+            "XEN WMI: Unable to open device - %s\n", XEN_WMI_DEVICE_NAME);
-+        return;
-+    }
-+
-+    register_ioport_read(XEN_ACPI_WMI_CMD_PORT, 1, 1, xen_acpi_wmi_cmd_port_read, device);   
-+    register_ioport_write(XEN_ACPI_WMI_CMD_PORT, 1, 1, xen_acpi_wmi_cmd_port_write, device); 
-+    register_ioport_read(XEN_ACPI_WMI_DATA_PORTB, 1, 1, xen_acpi_wmi_data_port_readb, device);
-+    register_ioport_write(XEN_ACPI_WMI_DATA_PORTB, 1, 1, xen_acpi_wmi_data_port_writeb, device);
-+    register_ioport_read(XEN_ACPI_WMI_DATA_PORTL, 4, 4, xen_acpi_wmi_data_port_readl, device);
-+    register_ioport_write(XEN_ACPI_WMI_DATA_PORTL, 4, 4, xen_acpi_wmi_data_port_writel, device);
-+
-+    xenstore_register_for_oem_events();
-+#ifdef XEN_ACPI_WMI_DEBUG
-+    fprintf(logfile, "XEN WMI:  XEN ACPI WMI registration succeeded!!!\n");
-+#endif
-+}
-+
-+/*
-+ * xen_acpi_wmi_cleanup(void)
-+ */
-+void xen_acpi_wmi_cleanup(void)
-+{
-+    if ( xen_wmi_device > 0 )
-+        close(xen_wmi_device);
-+}
-+
-+#else
-+
-+void xen_acpi_wmi_init(PCIDevice *device) { }
-+void xen_acpi_wmi_cleanup(void) { }
-+
-+#endif /* CONFIG_NO_XEN_ACPI_WMI */
-+ 
-diff --git a/hw/xen_acpi_wmi.h b/hw/xen_acpi_wmi.h
-new file mode 100644
-index 0000000..df289f2
---- /dev/null
-+++ b/hw/xen_acpi_wmi.h
-@@ -0,0 +1,89 @@
-+/*
-+ * xen_acpi_wmi.h
-+ *
-+ * Copyright (c) 2009  Kamala Narasimhan
-+ * Copyright (c) 2009  Citrix Systems, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _XEN_ACPI_WMI_H
-+#define _XEN_ACPI_WMI_H
-+
-+#ifdef CONFIG_STUBDOM
-+#define CONFIG_NO_XEN_ACPI_WMI
-+#endif
-+
-+#include "acpi-wmi.h"
-+
-+#define XEN_ACPI_WMI_CMD_PORT   0x96
-+#define XEN_ACPI_WMI_DATA_PORTB 0x98
-+#define XEN_ACPI_WMI_DATA_PORTL 0x9A
-+
-+/* Values written to WMI command port */
-+enum XEN_ACPI_WMI_COMMAND { XEN_ACPI_WMI_CMD_INIT = 100,
-+                            XEN_ACPI_WMI_CMD_GUID,
-+                            XEN_ACPI_WMI_CMD_OBJ_INSTANCE,
-+                            XEN_ACPI_WMI_CMD_METHOD_ID,
-+                            XEN_ACPI_WMI_CMD_IN_BUFFER,
-+                            XEN_ACPI_WMI_CMD_IN_BUFFER_SIZE, 
-+                            XEN_ACPI_WMI_CMD_EXECUTE,
-+                            XEN_ACPI_WMI_CMD_OUT_BUFFER,
-+                            XEN_ACPI_WMI_CMD_OUT_BUFFER_SIZE, 
-+                            XEN_ACPI_WMI_CMD_EVENT_ID,
-+                            XEN_ACPI_WMI_CMD_UNDEFINED }; 
-+
-+enum XEN_ACPI_WMI_OBJ_INVOCATION_TYPE { XEN_ACPI_WMI_EXEC_METHOD = 1,
-+                                        XEN_ACPI_WMI_QUERY_OBJECT,
-+                                        XEN_ACPI_WMI_SET_OBJECT,
-+                                        XEN_ACPI_WMI_GET_EVENT_DATA,
-+                                        XEN_ACPI_WMI_UNDEFINED };
-+
-+typedef struct xen_acpi_wmi_cmd_info {
-+    enum XEN_ACPI_WMI_COMMAND cmd_type;
-+    enum XEN_ACPI_WMI_OBJ_INVOCATION_TYPE invocation_type;
-+    xen_wmi_obj_invocation_data_t invocation_data;
-+    uint32_t current_index;
-+} xen_acpi_wmi_cmd_info_t; 
-+
-+void xen_acpi_wmi_init(PCIDevice *device);
-+void xen_acpi_wmi_cleanup(void);
-+
-+#ifndef CONFIG_NO_XEN_ACPI_WMI
-+
-+void xen_acpi_wmi_set_guid(uint8_t val);
-+void xen_acpi_wmi_set_cmd_instance(uint32_t val);
-+void xen_acpi_wmi_set_method_id(uint32_t val);
-+xen_wmi_buffer_t *xen_acpi_wmi_get_input_buffer(void);
-+void xen_acpi_wmi_set_in_buffer_size(uint32_t val);
-+void xen_acpi_wmi_set_in_buffer(uint8_t val);
-+xen_wmi_buffer_t *xen_acpi_wmi_get_output_buffer(void);
-+void xen_acpi_wmi_allocate_output_buffer(size_t length);
-+int xen_acpi_wmi_reallocate_output_buffer(void);
-+void xen_acpi_wmi_free_input_buffer(void);
-+void xen_acpi_wmi_execute(void);
-+void xen_acpi_wmi_set_event_id(uint8_t event_id);
-+static uint32_t xen_acpi_wmi_cmd_port_read(void *opaque, uint32_t addr);
-+static void xen_acpi_wmi_cmd_port_write(void *opaque, uint32_t addr, uint32_t val);
-+static uint32_t xen_acpi_wmi_data_port_readb(void *opaque, uint32_t addr);
-+static void xen_acpi_wmi_data_port_writeb(void *opaque, uint32_t addr, uint32_t val);
-+static uint32_t xen_acpi_wmi_data_port_readl(void *opaque, uint32_t addr);
-+static void xen_acpi_wmi_data_port_writel(void *opaque, uint32_t addr, uint32_t val);
-+
-+#endif
-+
-+#endif /* _XEN_ACPI_WMI_H */
-+
-+
-diff --git a/qemu-xen.h b/qemu-xen.h
-index 8c1debd..60ee108 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -128,6 +128,7 @@ int xenstore_refresh_battery_status(void);
- void xenstore_register_for_pm_events(void);
- int xenstore_read_ac_adapter_state(void);
- int xenstore_read_lid_state(void);
-+void xenstore_register_for_oem_events(void);
- int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
-                                          uint32_t build_nr);
-diff --git a/xen-hooks.mak b/xen-hooks.mak
-index d2f09fb..03d670e 100644
---- a/xen-hooks.mak
-+++ b/xen-hooks.mak
-@@ -35,6 +35,7 @@ OBJS += exec-dm.o
- OBJS += pci_emulation.o
- OBJS += helper2.o
- OBJS += battery_mgmt.o
-+OBJS += xen_acpi_wmi.o
- ifdef CONFIG_STUBDOM
- CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
-diff --git a/xenstore.c b/xenstore.c
-index 6f5b073..7cd4d54 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -1011,6 +1011,11 @@ void xenstore_process_event(void *opaque)
-         goto out;
-     }
-+    if (!strcmp(vec[XS_WATCH_TOKEN], "oemevt")) {
-+        acpi_oem_event();
-+        goto out;
-+    }
-+
-     if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
-         strlen(vec[XS_WATCH_TOKEN]) != 3)
-         goto out;
-@@ -1467,6 +1472,11 @@ void xenstore_register_for_pm_events(void)
-    xs_watch(xsh, "/pm/events/sleepbuttonpressed", "slpbuttonpressedevt");
- }
-+void xenstore_register_for_oem_events(void)
-+{
-+   xs_watch(xsh, "/oem/event", "oemevt");
-+}
-+
- int xenstore_read_ac_adapter_state(void)
- {
-     return xenstore_extended_power_mgmt_read_int("ac_adapter", 1);
diff --git a/xen-3.4/series b/xen-3.4/series
deleted file mode 100644 (file)
index 5f501b9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-ioemu-compil
-xenstore-watch-callbacks
-dm-ready
-
-battery-management
-oem-features
-thermal-management
-fix-build-warnings
-
-
-vga-passthrough
-dom0-driver
-intel
-use-vga-cmdline
-disable-aio
diff --git a/xen-3.4/status b/xen-3.4/status
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/xen-3.4/thermal-management b/xen-3.4/thermal-management
deleted file mode 100644 (file)
index 47e74bc..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index cf214a4..edede92 100644
---- a/hw/piix4acpi.c
-+++ b/hw/piix4acpi.c
-@@ -30,6 +30,7 @@
- #include "qemu-xen.h"
- #include "battery_mgmt.h"
- #include "xen_acpi_wmi.h"
-+#include "thermal_mgmt.h"
- #include <xen/hvm/ioreq.h>
- #include <xen/hvm/params.h>
-@@ -198,6 +199,7 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
-     battery_mgmt_init(pci_dev);
-     xen_acpi_wmi_init(pci_dev);
-+    thermal_mgmt_init(pci_dev);
- }
- static inline int test_bit(uint8_t *map, int bit)
-diff --git a/hw/thermal_mgmt.c b/hw/thermal_mgmt.c
-new file mode 100644
-index 0000000..649b622
---- /dev/null
-+++ b/hw/thermal_mgmt.c
-@@ -0,0 +1,79 @@
-+/*
-+ * thermal_mgmt.c
-+ *
-+ * Copyright (c) 2009  Kamala Narasimhan
-+ * Copyright (c) 2009  Citrix Systems, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+/* Implementation Notes:  Following provides a minimal thermal zone implementation for
-+ * HVM guest.  The vACPI layer exposes a single thermal zone with critical and current
-+ * temperature objects which when invoked relies on the below to return back the critical
-+ * and current temperature provided by the underlying firmware.
-+ */
-+
-+#include "hw.h"
-+#include "pc.h"
-+#include "qemu-xen.h"
-+#include "isa.h" 
-+#include "thermal_mgmt.h"
-+
-+#ifndef CONFIG_NO_THERMAL_MGMT
-+
-+/* #define THERMAL_MGMT_DBG */
-+
-+extern FILE *logfile;
-+
-+static uint32_t thermal_port_1_readw(void *opaque, uint32_t addr)
-+{
-+    int current_temp;
-+
-+    xenstore_refresh_thermal_info();
-+    current_temp = xenstore_read_current_temperature();
-+#ifdef THERMAL_MGMT_DBG
-+    fprintf(logfile, "Current temperature - %d\n", current_temp);
-+#endif
-+    return current_temp;
-+}
-+
-+static uint32_t thermal_port_2_readw(void *opaque, uint32_t addr)
-+{
-+    int critical_temp;
-+
-+    xenstore_refresh_thermal_info();
-+    critical_temp = xenstore_read_critical_temperature();
-+#ifdef THERMAL_MGMT_DBG
-+    fprintf(logfile, "Critical trip point temperature - %d\n", critical_temp);
-+#endif
-+    return critical_temp;
-+}
-+
-+void thermal_mgmt_init(PCIDevice *device)
-+{
-+#ifdef THERMAL_MGMT_DBG
-+    fprintf(logfile, "In thermal management init\n");
-+#endif
-+
-+    register_ioport_read(THERMAL_PORT_1, 1, 2, thermal_port_1_readw, device);
-+    register_ioport_read(THERMAL_PORT_2, 1, 2, thermal_port_2_readw, device);
-+}
-+
-+#else
-+
-+void thermal_mgmt_init(PCIDevice *device) { }
-+
-+#endif
-+
-diff --git a/hw/thermal_mgmt.h b/hw/thermal_mgmt.h
-new file mode 100644
-index 0000000..d83273b
---- /dev/null
-+++ b/hw/thermal_mgmt.h
-@@ -0,0 +1,35 @@
-+/*
-+ * thermal_mgmt.h
-+ *
-+ * Copyright (c) 2009  Kamala Narasimhan
-+ * Copyright (c) 2009  Citrix Systems, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _THERMAL_MGMT_H
-+#define _THERMAL_MGMT_H
-+
-+#ifdef CONFIG_STUBDOM
-+#define CONFIG_NO_THERMAL_MGMT
-+#endif
-+
-+#define THERMAL_PORT_1 0x90
-+#define THERMAL_PORT_2 0x92
-+
-+void thermal_mgmt_init(PCIDevice *device);
-+
-+#endif
-+
-diff --git a/qemu-xen.h b/qemu-xen.h
-index 60ee108..0cc5dd8 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -125,9 +125,12 @@ char *xenstore_device_model_read(int domid, const char *key, unsigned int *len);
- int xenstore_extended_power_mgmt_read_int(const char *key, int default_value);
- char *xenstore_read_battery_data(int battery_status);
- int xenstore_refresh_battery_status(void);
-+int xenstore_refresh_thermal_info(void);
- void xenstore_register_for_pm_events(void);
- int xenstore_read_ac_adapter_state(void);
- int xenstore_read_lid_state(void);
-+int xenstore_read_current_temperature(void);
-+int xenstore_read_critical_temperature(void);
- void xenstore_register_for_oem_events(void);
- int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
-                                          uint32_t build_nr);
-diff --git a/xen-hooks.mak b/xen-hooks.mak
-index 03d670e..7c94718 100644
---- a/xen-hooks.mak
-+++ b/xen-hooks.mak
-@@ -36,6 +36,7 @@ OBJS += pci_emulation.o
- OBJS += helper2.o
- OBJS += battery_mgmt.o
- OBJS += xen_acpi_wmi.o
-+OBJS += thermal_mgmt.o
- ifdef CONFIG_STUBDOM
- CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
-diff --git a/xenstore.c b/xenstore.c
-index 7cd4d54..01afcf0 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -1464,6 +1464,11 @@ int xenstore_refresh_battery_status(void)
-     return xenstore_extended_power_mgmt_event_trigger("refreshbatterystatus", "1");
- }
-+int xenstore_refresh_thermal_info(void)
-+{
-+    return xenstore_extended_power_mgmt_event_trigger("refreshthermalinfo", "1");
-+}
-+
- void xenstore_register_for_pm_events(void)
- {
-    xs_watch(xsh, "/pm/events/acadapterstatechanged", "acadapterstatechangeevt");
-@@ -1487,6 +1492,16 @@ int xenstore_read_lid_state(void)
-     return xenstore_extended_power_mgmt_read_int("lid_state", 1);
- }
-+int xenstore_read_current_temperature(void)
-+{
-+    return xenstore_extended_power_mgmt_read_int("current_temperature", 0);
-+}
-+
-+int xenstore_read_critical_temperature(void)
-+{
-+    return xenstore_extended_power_mgmt_read_int("critical_temperature", 100);
-+}
-+
- /*
-  * Create a store entry for a device (e.g., monitor, serial/parallel lines).
-  * The entry is <domain-path><storeString>/tty and the value is the name
diff --git a/xen-3.4/use-vga-cmdline b/xen-3.4/use-vga-cmdline
deleted file mode 100644 (file)
index 4006998..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-diff --git a/vl.c b/vl.c
-index ae32f82..05d12ae 100644
---- a/vl.c
-+++ b/vl.c
-@@ -4598,24 +4598,20 @@ static void select_soundhw (const char *optarg)
- static void select_vgahw (const char *p)
- {
-     const char *opts;
-+    std_vga_enabled = 0;
-+    cirrus_vga_enabled = 0;
-+    vmsvga_enabled = 0;
--    if (strstart(p, "std", &opts)) {
-+    if (strstart(p, "std", &opts)) 
-         std_vga_enabled = 1;
--        cirrus_vga_enabled = 0;
--        vmsvga_enabled = 0;
--    } else if (strstart(p, "cirrus", &opts)) {
-+    else if (strstart(p, "cirrus", &opts)) 
-         cirrus_vga_enabled = 1;
--        std_vga_enabled = 0;
--        vmsvga_enabled = 0;
--    } else if (strstart(p, "vmware", &opts)) {
--        cirrus_vga_enabled = 0;
--        std_vga_enabled = 0;
-+    else if (strstart(p, "vmware", &opts)) 
-         vmsvga_enabled = 1;
--    } else if (strstart(p, "none", &opts)) {
--        cirrus_vga_enabled = 0;
--        std_vga_enabled = 0;
--        vmsvga_enabled = 0;
--    } else {
-+    else if (strstart(p, "passthrough", &opts))
-+        vga_passthrough = 1;
-+    else if (!strstart(p, "none", &opts)) 
-+    {
-     invalid_vga:
-         fprintf(stderr, "Unknown vga type: %s\n", p);
-         exit(1);
-@@ -5272,6 +5268,9 @@ int main(int argc, char **argv, char **envp)
-                 break;
-             case QEMU_OPTION_vga_passthrough:
-                 vga_passthrough = 1;
-+                std_vga_enabled = 0;
-+                cirrus_vga_enabled = 0;
-+                vmsvga_enabled = 0;
-                 break;
-             case QEMU_OPTION_dom0_input:
-                 dom0_input = optarg;
diff --git a/xen-3.4/vga-passthrough b/xen-3.4/vga-passthrough
deleted file mode 100644 (file)
index d2adba9..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-diff --git a/hw/pass-through.c b/hw/pass-through.c
-index 6a53137..3420e95 100644
---- a/hw/pass-through.c
-+++ b/hw/pass-through.c
-@@ -90,6 +90,8 @@
- #include "qemu-xen.h"
- #include <unistd.h>
-+extern int vga_passthrough;
-+
- struct php_dev {
-     struct pt_dev *pt_dev;
-     uint8_t valid;
-@@ -1573,10 +1575,11 @@ static int pt_dev_is_virtfn(struct pci_dev *dev)
- static int pt_register_regions(struct pt_dev *assigned_device)
- {
--    int i = 0;
-+    int i = 0, ret = 0;
-     uint32_t bar_data = 0;
-     struct pci_dev *pci_dev = assigned_device->pci_dev;
-     PCIDevice *d = &assigned_device->dev;
-+    uint16_t vendor_id, class;
-     /* Register PIO/MMIO BARs */
-     for ( i = 0; i < PCI_BAR_ENTRIES; i++ )
-@@ -1632,6 +1635,28 @@ static int pt_register_regions(struct pt_dev *assigned_device)
-             (uint32_t)(pci_dev->rom_size), (uint32_t)(pci_dev->rom_base_addr));
-     }
-+    /* Map legacy ioport and iomem, for specific devices */
-+    vendor_id = pci_read_word(pci_dev, 0x00);
-+    class = pci_read_word(pci_dev, 0x0a);
-+
-+    PT_LOG("Real device vendor_id=0x%x class=0x%x\n", vendor_id, class);
-+    if ( vga_passthrough && class == 0x0300 )
-+    {
-+        PT_LOG("add an intel graphic card\n");
-+
-+        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, 0x3B0, 0xb,
-+                                      DPCI_ADD_MAPPING);
-+        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, 0x3C0, 32,
-+                                      DPCI_ADD_MAPPING);
-+        ret |= xc_domain_memory_mapping(xc_handle, domid, 0xa0, 0xa0, 32,
-+                                       DPCI_ADD_MAPPING);
-+        if ( ret != 0 )
-+        {
-+            PT_LOG("legacy mapping failed !\n");
-+            return ret;
-+        }
-+    }
-+
-     return 0;
- }
-@@ -1640,6 +1665,7 @@ static void pt_unregister_regions(struct pt_dev *assigned_device)
-     int i, type, ret;
-     uint32_t e_size;
-     PCIDevice *d = (PCIDevice*)assigned_device;
-+    uint16_t class, vendor_id;
-     for ( i = 0; i < PCI_NUM_REGIONS; i++ )
-     {
-@@ -1681,6 +1707,26 @@ static void pt_unregister_regions(struct pt_dev *assigned_device)
-     }
-+    /* unmap legacy ioport and iomem, for specific devices */
-+    vendor_id = pci_read_word(assigned_device->pci_dev, 0x00);
-+    class = pci_read_word(assigned_device->pci_dev, 0x0a);
-+
-+    PT_LOG("Real device vendor_id=0x%x class=0x%x\n", vendor_id, class);
-+    if ( vga_passthrough && class == 0x0300 )
-+    {
-+        PT_LOG("remove an intel graphic card\n");
-+
-+        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, 0x3B0, 0xb,
-+                                      DPCI_REMOVE_MAPPING);
-+        ret = xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, 0x3C0, 32,
-+                                       DPCI_REMOVE_MAPPING);
-+        ret |= xc_domain_memory_mapping(xc_handle, domid, 0xa0, 0xa0, 32,
-+                                        DPCI_REMOVE_MAPPING);
-+        if ( ret != 0 )
-+        {
-+            PT_LOG("legacy unmapping failed !\n");
-+        }
-+    }
- }
- static uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
-@@ -4084,3 +4130,41 @@ err:
-     return status;
- }
-+u8      pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr)
-+{
-+    struct pci_dev*     pci_dev;
-+    u8                  val;
-+
-+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
-+    if (!pci_dev)
-+        return 0;
-+    val = pci_read_byte(pci_dev, addr);
-+    pci_free_dev(pci_dev);
-+    return val;
-+}
-+
-+u16     pt_pci_host_read_word(int bus, int dev, int fn, u32 addr)
-+{
-+    struct pci_dev*     pci_dev;
-+    u16                 val;
-+
-+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
-+    if (!pci_dev)
-+        return 0;
-+    val = pci_read_word(pci_dev, addr);
-+    pci_free_dev(pci_dev);
-+    return val;
-+}
-+
-+u32     pt_pci_host_read_long(int bus, int dev, int fn, u32 addr)
-+{
-+    struct pci_dev*     pci_dev;
-+    u32                 val;
-+
-+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
-+    if (!pci_dev)
-+        return 0;
-+    val = pci_read_long(pci_dev, addr);
-+    pci_free_dev(pci_dev);
-+    return val;
-+}
-diff --git a/hw/pass-through.h b/hw/pass-through.h
-index a503e80..1752e8d 100644
---- a/hw/pass-through.h
-+++ b/hw/pass-through.h
-@@ -392,5 +392,9 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base)
-     return base & PCI_ADDR_MEM_MASK;
- }
-+u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr);
-+u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr);
-+u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr);
-+
- #endif /* __PASSTHROUGH_H__ */
-diff --git a/hw/pci.c b/hw/pci.c
-index d7c516e..b2f4d43 100644
---- a/hw/pci.c
-+++ b/hw/pci.c
-@@ -28,11 +28,14 @@
- #include "virtio-net.h"
- #include "sysemu.h"
-+#include "pass-through.h"
- #include "exec-all.h"
- #include "qemu-xen.h"
- //#define DEBUG_PCI
-+extern int vga_passthrough;
-+
- struct PCIBus {
-     int bus_num;
-     int devfn_min;
-@@ -611,7 +614,30 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
-         goto the_end;
-     }
-     config_addr = addr & 0xff;
--    val = pci_dev->config_read(pci_dev, config_addr, len);
-+    if (vga_passthrough && pci_dev->devfn == 0x00) //Host Bridge
-+    {
-+      val = pci_dev->config_read(pci_dev, config_addr, len);
-+
-+        if (config_addr == 0x52) // GMCH
-+            val = pt_pci_host_read_word(0, 0, 0, 0x52);
-+        if (config_addr == 0x02) // Device ID
-+      {
-+          if (len == 2)
-+              val = pt_pci_host_read_word(0, 0, 0, 0x02);
-+      }
-+      if (config_addr == 0x0)
-+      {
-+          if (len == 2)
-+              val = pt_pci_host_read_word(0, 0, 0, 0x00);
-+          else if (len == 4)
-+              val = pt_pci_host_read_long(0, 0, 0, 0x00);
-+      }
-+    }
-+    else if (vga_passthrough && pci_dev->devfn == 0x10 && // intel graphic card
-+          config_addr == 0xfc) // OpRegion address
-+      val = 0; // force to fall back to SMI mode
-+    else
-+      val = pci_dev->config_read(pci_dev, config_addr, len);
- #if defined(DEBUG_PCI)
-     printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
-            pci_dev->name, config_addr, val, len);
-diff --git a/vl.c b/vl.c
-index b273c75..e519705 100644
---- a/vl.c
-+++ b/vl.c
-@@ -233,6 +233,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
- #ifdef TARGET_I386
- int win2k_install_hack = 0;
- int rtc_td_hack = 0;
-+int vga_passthrough = 0;
- #endif
- int usb_enabled = 0;
- int smp_cpus = 1;
-@@ -4275,6 +4276,7 @@ enum {
-     QEMU_OPTION_domainname,
-     QEMU_OPTION_acpi,
-     QEMU_OPTION_vcpus,
-+    QEMU_OPTION_vga_passthrough,
-     /* Debug/Expert options: */
-     QEMU_OPTION_serial,
-@@ -4448,6 +4450,7 @@ static const QEMUOption qemu_options[] = {
-     { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
-     { "vncunused", 0, QEMU_OPTION_vncunused },
-     { "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
-+    { "vga-passthrough", 0, QEMU_OPTION_vga_passthrough },
- #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
-     { "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
-     { "xen-create", 0, QEMU_OPTION_xen_create },
-@@ -5281,6 +5284,9 @@ int main(int argc, char **argv, char **envp)
-             case QEMU_OPTION_disable_opengl:
-                 opengl_enabled = 0;
-                 break;
-+            case QEMU_OPTION_vga_passthrough:
-+                vga_passthrough = 1;
-+                break;
-             case QEMU_OPTION_direct_pci:
-                direct_pci = optarg;
-                 break;
diff --git a/xen-3.4/xenstore-watch-callbacks b/xen-3.4/xenstore-watch-callbacks
deleted file mode 100644 (file)
index 916f5f4..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-Improved the way to do xenstore watchs.
-
-diff --git a/qemu-xen.h b/qemu-xen.h
-index ec4cd94..9f7feda 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -78,6 +78,19 @@ int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
-                                              const char *inst,
-                                              const char *token);
-+typedef void (*xenstore_callback) (const char *path, void *opaque);
-+int xenstore_watch_screenshot_node(DisplayState *ds);
-+int xenstore_watch_new_callback(const char *path, xenstore_callback fptr, void *opaque);
-+
-+char *xenstore_dom_read(int domid, const char *key, unsigned int *len);
-+int xenstore_dom_write(int domid, const char *key, const char *value);
-+void xenstore_dom_watch(int domid, const char *key, xenstore_callback ftp, void *opaque);
-+void xenstore_dom_chmod(int domid, const char *key, const char *perms);
-+
-+char *xenstore_read(const char *path);
-+int xenstore_write(const char *path, const char *val);
-+
-+
-  /* `danger' means that this parameter, variable or function refers to
-   * an area of xenstore which is writeable by the guest and thus must
-   * not be trusted by qemu code.  For variables containing xenstore
-@@ -92,7 +105,7 @@ int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
- int xenstore_vm_write(int domid, const char *key, const char *val);
- char *xenstore_vm_read(int domid, const char *key, unsigned int *len);
--char *xenstore_device_model_read(int domid, char *key, unsigned int *len);
-+char *xenstore_device_model_read(int domid, const char *key, unsigned int *len);
- char *xenstore_read_battery_data(int battery_status);
- int xenstore_refresh_battery_status(void);
- int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
-diff --git a/xenstore.c b/xenstore.c
-index ef7b5f3..ea39dce 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -37,6 +37,52 @@ static QEMUTimer *insert_timer = NULL;
- #define UWAIT_MAX (30*1000000) /* thirty seconds */
- #define UWAIT     (100000)     /* 1/10th second  */
-+struct xenstore_watch_cb_t
-+{
-+    char                *path;
-+    xenstore_callback   cb;
-+    void                *opaque;
-+};
-+
-+static struct xenstore_watch_cb_t *xenstore_watch_callbacks = NULL;
-+
-+int xenstore_watch_new_callback(const char          *path,
-+                                xenstore_callback   fptr,
-+                                void                *opaque)
-+{
-+    int         i = 0, ret = 0;
-+
-+    ret = xs_watch(xsh, path, path);
-+    if (ret == 0)
-+        return 0;
-+
-+    if (!xenstore_watch_callbacks)
-+    {
-+        xenstore_watch_callbacks = malloc(sizeof (struct xenstore_watch_cb_t));
-+        xenstore_watch_callbacks[0].path = NULL;
-+    }
-+
-+    while (xenstore_watch_callbacks[i].path)
-+    {
-+      if (!strcmp(xenstore_watch_callbacks[i].path, path))
-+      {
-+          xenstore_watch_callbacks[i].cb = fptr;
-+          xenstore_watch_callbacks[i].opaque = opaque;
-+          return ret;
-+      }
-+        i++;
-+    }
-+
-+    xenstore_watch_callbacks = realloc(xenstore_watch_callbacks,
-+                                       (i + 2) * sizeof (struct xenstore_watch_cb_t));
-+    xenstore_watch_callbacks[i].path = strdup(path);
-+    xenstore_watch_callbacks[i].cb = fptr;
-+    xenstore_watch_callbacks[i].opaque = opaque;
-+    xenstore_watch_callbacks[i + 1].path = NULL;
-+    return ret;
-+}
-+
-+
- static int pasprintf(char **buf, const char *fmt, ...)
- {
-     va_list ap;
-@@ -904,12 +950,18 @@ void xenstore_record_dm_state(const char *state)
- void xenstore_process_event(void *opaque)
- {
-     char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
--    unsigned int len, num, hd_index;
-+    unsigned int len, num, hd_index, i;
-     vec = xs_read_watch(xsh, &num);
-     if (!vec)
-         return;
-+    for (i = 0; xenstore_watch_callbacks &&  xenstore_watch_callbacks[i].path; i++)
-+      if (xenstore_watch_callbacks[i].cb &&
-+          !strcmp(vec[XS_WATCH_TOKEN], xenstore_watch_callbacks[i].path))
-+            xenstore_watch_callbacks[i].cb(vec[XS_WATCH_TOKEN],
-+                                           xenstore_watch_callbacks[i].opaque);
-+
-     if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
-         xenstore_process_logdirty_event();
-         goto out;
-@@ -1272,7 +1324,7 @@ int xenstore_vm_write(int domid, const char *key, const char *value)
-     return rc;
- }
--char *xenstore_device_model_read(int domid, char *key, unsigned int *len)
-+char *xenstore_device_model_read(int domid, const char *key, unsigned int *len)
- {
-     char *path = NULL, *value = NULL;
-@@ -1438,3 +1490,122 @@ void xenstore_store_serial_port_info(int i, CharDriverState *chr,
-     if (i == 0) /* serial 0 is also called the console */
-         store_dev_info(devname, domid, chr, "/console");
- }
-+
-+char *xenstore_dom_read(int domid, const char *key, unsigned int *len)
-+{
-+    char *buf = NULL, *path = NULL, *value = NULL;
-+
-+    if (xsh == NULL)
-+        goto out;
-+
-+    path = xs_get_domain_path(xsh, domid);
-+    if (path == NULL) {
-+        fprintf(logfile, "xs_get_domain_path(%d): error\n", domid);
-+        goto out;
-+    }
-+
-+    pasprintf(&buf, "%s/%s", path, key);
-+    value = xs_read(xsh, XBT_NULL, buf, len);
-+    if (value == NULL) {
-+        fprintf(logfile, "xs_read(%s): read error\n", buf);
-+        goto out;
-+    }
-+
-+ out:
-+    free(path);
-+    free(buf);
-+    return value;
-+}
-+
-+void xenstore_dom_watch(int domid, const char *key, xenstore_callback fptr, void *opaque)
-+{
-+    char *buf = NULL, *path = NULL;
-+    int rc = -1;
-+
-+    if (xsh == NULL)
-+        goto out;
-+
-+    path = xs_get_domain_path(xsh, domid);
-+    if (path == NULL) {
-+        fprintf(logfile, "xs_get_domain_path: error\n");
-+        goto out;
-+    }
-+
-+    pasprintf(&buf, "%s/%s", path, key);
-+      xenstore_watch_new_callback(buf, fptr, opaque);
-+
-+ out:
-+    free(path);
-+    free(buf);
-+}
-+
-+void xenstore_dom_chmod(int domid, const char *key, const char *perms)
-+{
-+    char *buf = NULL, *path = NULL;
-+    int rc = -1;
-+      struct xs_permissions p;
-+
-+    if (xsh == NULL)
-+        goto out;
-+
-+    path = xs_get_domain_path(xsh, domid);
-+    if (path == NULL) {
-+        fprintf(logfile, "xs_get_domain_path: error\n");
-+        goto out;
-+    }
-+
-+    pasprintf(&buf, "%s/%s", path, key);
-+
-+      xs_strings_to_perms(&p, 1, perms);
-+      xs_set_permissions(xsh, XBT_NULL, buf, &p, 1);
-+
-+ out:
-+    free(path);
-+    free(buf);
-+}
-+
-+int xenstore_dom_write(int domid, const char *key, const char *value)
-+{
-+    char *buf = NULL, *path = NULL;
-+    int rc = -1;
-+
-+    if (xsh == NULL)
-+        goto out;
-+
-+    path = xs_get_domain_path(xsh, domid);
-+    if (path == NULL) {
-+        fprintf(logfile, "xs_get_domain_path: error\n");
-+        goto out;
-+    }
-+
-+    pasprintf(&buf, "%s/%s", path, key);
-+    rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value));
-+    if (rc == 0) {
-+        fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key);
-+        goto out;
-+    }
-+
-+ out:
-+    free(path);
-+    free(buf);
-+    return rc;
-+}
-+
-+char *xenstore_read(const char *path)
-+{
-+    char *value = NULL;
-+    unsigned int len;
-+
-+    if (xsh == NULL)
-+        return NULL;
-+    return xs_read(xsh, XBT_NULL, path, &len);
-+}
-+
-+int xenstore_write(const char *path, const char *val)
-+{
-+    if (xsh == NULL)
-+        return 1;
-+    return xs_write(xsh, XBT_NULL, path, val, strlen(val));
-+}
-+
-+