diff --git a/hw/battery_mgmt.c b/hw/battery_mgmt.c
-index fa919ca..b88fd7a 100644
+index 3ddeb09..883b150 100644
--- a/hw/battery_mgmt.c
+++ b/hw/battery_mgmt.c
-@@ -229,16 +229,22 @@ static uint32_t battery_port_2_readb(void *opaque, uint32_t addr)
+@@ -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)
{
+ 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)
{
- memset(&battery_info, 0, sizeof(battery_state_info));
@@ -290,6 +296,7 @@ void battery_mgmt_init(PCIDevice *device)
}
#ifdef BATTERY_MGMT_DEBUG
fprintf(logfile, "Power management mode set to - %d\n", power_mgmt_mode);
diff --git a/hw/pass-through.c b/hw/pass-through.c
-index e74f1b0..4349ab7 100644
+index 3420e95..e7c968d 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
-@@ -46,7 +46,9 @@ struct dpci_infos {
+@@ -107,7 +107,9 @@ struct dpci_infos {
PCIBus *e_bus;
struct pci_access *pci_access;
char mapped_machine_irq[PT_NR_IRQS] = {0};
-@@ -836,6 +838,12 @@ static int pci_slot_match(int bus, int dev, int func, int slot)
+@@ -899,6 +901,12 @@ static int pci_slot_match(int bus, int dev, int func, int slot)
return 0;
}
* input dom:bus:dev.func@slot, chose free one if slot == AUTO_PHP_SLOT
* return -2: requested slot not available
diff --git a/hw/pass-through.h b/hw/pass-through.h
-index 7cd5a2b..77b733f 100644
+index 1752e8d..96d802a 100644
--- a/hw/pass-through.h
+++ b/hw/pass-through.h
-@@ -391,5 +391,7 @@ u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr);
+@@ -396,5 +396,7 @@ 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/pc.h b/hw/pc.h
-index 0f7044a..e1ce52d 100644
+index 8b71d48..cc6246a 100644
--- a/hw/pc.h
+++ b/hw/pc.h
-@@ -105,6 +105,9 @@ void acpi_bios_init(void);
+@@ -106,6 +106,9 @@ int acpi_table_add(const char *table_desc);
void acpi_php_add(int);
void acpi_php_del(int);
/* hpet.c */
extern int no_hpet;
diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index b4a0c1a..d25f004 100644
+index 7844cb8..99359ff 100644
--- a/hw/piix4acpi.c
+++ b/hw/piix4acpi.c
@@ -53,6 +53,10 @@
+#define ACPI_PHP_SLOT_NUM NR_PCI_DEV
+#define ACPI_AC_POWER_STATE_BIT 0x1c
+#define ACPI_POWER_BUTTON_BIT 0x1
-+#define ACPI_LID_STATE_BIT 0x17
++#define ACPI_LID_STATE_BIT 0x17
typedef struct AcpiDeviceState AcpiDeviceState;
AcpiDeviceState *acpi_device_table;
+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);
+ set_bit(&s->gpe0_sts[0], ACPI_POWER_BUTTON_BIT);
+ s->sci_asserted = 1;
+ qemu_irq_raise(sci_irq);
-+ }
++ }
+}
+
+void acpi_lid_state_changed(void)
static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
{
#if defined(DEBUG)
-@@ -237,11 +277,8 @@ static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
+@@ -238,11 +278,8 @@ static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
case ACPI_PHP_IO_ADDR:
val = hotplug_slots->plug_evt;
break;
val = hotplug_slots->status[num];
}
-@@ -254,7 +291,7 @@ static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
+@@ -255,7 +292,7 @@ static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
{
PHPSlots *hotplug_slots = opaque;
fprintf(logfile, "ACPI PCI hotplug: write addr=0x%x, val=0x%x.\n",
addr, val);
-@@ -262,21 +299,17 @@ static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
+@@ -263,21 +300,17 @@ static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
switch (addr)
{
case ACPI_PHP_IO_ADDR:
/* signal the CP ACPI hot remove done. */
xenstore_record_dm_state("pci-removed");
}
-@@ -285,47 +318,44 @@ static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
-
- static void pcislots_save(QEMUFile* f, void* opaque)
- {
-- PHPSlots *hotplug_slots = opaque;
-+ PHPSlots *s = (PHPSlots*)opaque;
- int i;
-- for ( i = 0; i < NR_PCI_DEV; i++ ) {
-- qemu_put_8s( f, &hotplug_slots->status[i]);
-+ for ( i = 0; i < ACPI_PHP_SLOT_NUM; i++ ) {
-+ qemu_put_8s( f, &s->status[i]);
- }
-- qemu_put_8s(f, &hotplug_slots->plug_evt);
-- qemu_put_8s(f, &hotplug_slots->plug_slot);
-+ qemu_put_8s(f, &s->plug_evt);
- }
-
- static int pcislots_load(QEMUFile* f, void* opaque, int version_id)
- {
-- PHPSlots *hotplug_slots = opaque;
-+ PHPSlots *s = (PHPSlots*)opaque;
- int i;
- if (version_id != 1)
- return -EINVAL;
-- for ( i = 0; i < NR_PCI_DEV; i++ ) {
-- qemu_get_8s( f, &hotplug_slots->status[i]);
-+ for ( i = 0; i < ACPI_PHP_SLOT_NUM; i++ ) {
-+ qemu_get_8s( f, &s->status[i]);
- }
-- qemu_get_8s(f, &hotplug_slots->plug_evt);
-- qemu_get_8s(f, &hotplug_slots->plug_slot);
-+ qemu_get_8s(f, &s->plug_evt);
- return 0;
- }
-
- static void php_slots_init(void)
- {
-+ PHPSlots *slots = &php_slots;
- int i;
-- memset(&php_slots, 0, sizeof(PHPSlots));
-+ memset(slots, 0, sizeof(PHPSlots));
-
- /* update the pci slot status */
- for ( i = 0; i < NR_PCI_DEV; i++ ) {
-- if ( test_pci_slot(i) )
-- php_slots.status[i] = 0xf;
-+ if ( test_pci_slot(i) && !pcibus_devnfn_in_use(i) )
-+ slots->status[i] = 0xf;
- }
-
-+
- /* ACPI PCI hotplug controller */
-- register_ioport_read(ACPI_PHP_IO_ADDR, NR_PCI_DEV, 1,
-- acpi_php_readb, &php_slots);
-- register_ioport_write(ACPI_PHP_IO_ADDR, NR_PCI_DEV, 1,
-- acpi_php_writeb, &php_slots);
-- register_savevm("pcislots", 0, 1, pcislots_save, pcislots_load,
-- &php_slots);
-+ register_ioport_read(ACPI_PHP_IO_ADDR, ACPI_PHP_SLOT_NUM + 1, 1, acpi_php_readb, slots);
-+ register_ioport_write(ACPI_PHP_IO_ADDR, ACPI_PHP_SLOT_NUM + 1, 1, acpi_php_writeb, slots);
-+ register_savevm("pcislots", 0, 1, pcislots_save, pcislots_load, slots);
- }
-
- /* GPEx_STS occupy 1st half of the block, while GPEx_EN 2nd half */
-@@ -562,9 +592,9 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+@@ -563,9 +596,9 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
d->pm1_control = SCI_EN;
acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d);
#endif
diff --git a/qemu-xen.h b/qemu-xen.h
-index 73eeb31..61c0f25 100644
+index 387ca35..2654b67 100644
--- a/qemu-xen.h
+++ b/qemu-xen.h
-@@ -115,6 +115,9 @@ char *xenstore_vm_read(int domid, const char *key, unsigned int *len);
+@@ -130,6 +130,9 @@ 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);
char *xenstore_read_battery_data(int battery_status);
int xenstore_refresh_battery_status(void);
uint32_t build_nr);
diff --git a/xenstore.c b/xenstore.c
-index 20d54a0..3fa6115 100644
+index 383e010..659bc00 100644
--- a/xenstore.c
+++ b/xenstore.c
@@ -27,6 +27,7 @@
#include "qemu-timer.h"
#include "qemu-xen.h"
-@@ -962,6 +963,21 @@ void xenstore_process_event(void *opaque)
+@@ -981,6 +982,21 @@ void xenstore_process_event(void *opaque)
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;
-@@ -1691,3 +1707,37 @@ int *xenstore_get_domids(int *len)
+@@ -1710,3 +1726,37 @@ int *xenstore_get_domids(int *len)
return tab;
}
diff --git a/console.h b/console.h
-index 3919e88..88d971f 100644
+index 14b42f3..97214c0 100644
--- a/console.h
+++ b/console.h
-@@ -336,4 +336,19 @@ const char *readline_get_history(unsigned int index);
+@@ -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);
+void hid_linux_probe(int grab);
+
#endif
-diff --git a/dom0_driver.c b/dom0_driver.c
-new file mode 100644
-index 0000000..c58d188
---- /dev/null
-+++ b/dom0_driver.c
-@@ -0,0 +1,691 @@
-+/*
-+ * 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;
-+
-+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
-+ {
-+ 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/hw/battery_mgmt.c b/hw/battery_mgmt.c
-index 0cce054..fa919ca 100644
---- a/hw/battery_mgmt.c
-+++ b/hw/battery_mgmt.c
-@@ -59,7 +59,6 @@
- static enum POWER_MGMT_MODE power_mgmt_mode = PM_MODE_NONE;
- static battery_state_info battery_info;
- extern FILE *logfile;
--extern int domid;
-
- int is_battery_pt_feasible(void)
- {
diff --git a/qemu-xen.h b/qemu-xen.h
-index e967a4a..e8ca8e6 100644
+index 0cc5dd8..2646ec7 100644
--- a/qemu-xen.h
+++ b/qemu-xen.h
-@@ -92,7 +92,13 @@ int xenstore_write(const char *path, const char *val);
+@@ -107,7 +107,13 @@ int xenstore_write(const char *path, const char *val);
void xenstore_dm_finished_startup(void);
* 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 2a9c5d5..6b5af55 100644
+index e519705..0ffe1ec 100644
--- a/vl.c
+++ b/vl.c
-@@ -225,6 +225,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
+@@ -234,6 +234,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
int win2k_install_hack = 0;
int rtc_td_hack = 0;
int vga_passthrough = 0;
#endif
int usb_enabled = 0;
int smp_cpus = 1;
-@@ -272,6 +273,20 @@ uint8_t qemu_uuid[16];
+@@ -278,6 +279,20 @@ uint8_t qemu_uuid[16];
#include "xen-vl-extra.c"
/***********************************************************/
/* x86 ISA bus support */
-@@ -4208,6 +4223,7 @@ enum {
+@@ -4277,6 +4292,7 @@ enum {
QEMU_OPTION_acpi,
QEMU_OPTION_vcpus,
QEMU_OPTION_vga_passthrough,
/* Debug/Expert options: */
QEMU_OPTION_serial,
-@@ -4381,6 +4397,7 @@ static const QEMUOption qemu_options[] = {
+@@ -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 },
- #ifdef CONFIG_XEN
+ #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
{ "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
{ "xen-create", 0, QEMU_OPTION_xen_create },
-@@ -5253,6 +5270,9 @@ int main(int argc, char **argv, char **envp)
+@@ -5287,6 +5304,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_vga_passthrough:
vga_passthrough = 1;
break;
case QEMU_OPTION_direct_pci:
direct_pci = optarg;
break;
-@@ -5973,6 +5993,9 @@ int main(int argc, char **argv, char **envp)
- close(fd);
+@@ -6053,6 +6073,9 @@ int main(int argc, char **argv, char **envp)
+ close(fd);
}
+ if (dom0_input)
main_loop();
diff --git a/xen-hooks.mak b/xen-hooks.mak
-index d2f09fb..bed869a 100644
+index 7c94718..f243df1 100644
--- a/xen-hooks.mak
+++ b/xen-hooks.mak
-@@ -35,6 +35,8 @@ OBJS += exec-dm.o
- OBJS += pci_emulation.o
- OBJS += helper2.o
+@@ -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 8b1a2e9..2e96f8a 100644
+index ccd167f..244f906 100644
--- a/xenstore.c
+++ b/xenstore.c
-@@ -1631,3 +1631,63 @@ void xenstore_dm_finished_startup(void)
+@@ -1728,3 +1728,63 @@ void xenstore_dm_finished_startup(void)
free(buf);
free(path);
}
-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/pci.h b/hw/pci.h
-index a48ac30..b27696e 100644
---- a/hw/pci.h
-+++ b/hw/pci.h
-@@ -156,9 +156,13 @@ typedef struct PCIIORegion {
+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_DEVSEL 0x600
#define PCI_STATUS_RESERVED_MASK_LO (PCI_STATUS_RESERVED1 | \
-diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index 5383032..841986c 100644
---- a/hw/piix4acpi.c
-+++ b/hw/piix4acpi.c
-@@ -30,6 +30,8 @@
- #include "qemu-xen.h"
- #include "battery_mgmt.h"
- #include "xen_acpi_wmi.h"
-+#include "thermal_mgmt.h"
-+#include "pass-through.h"
-
- #include <xen/hvm/ioreq.h>
- #include <xen/hvm/params.h>
-@@ -216,8 +218,6 @@ static inline void clear_bit(uint8_t *map, int bit)
- map[bit / 8] &= ~(1 << (bit % 8));
- }
-
--extern FILE *logfile;
--
- void acpi_ac_adapter_state_changed(void)
- {
- GPEState *s = &gpe_state;
-diff --git a/hw/xen_acpi_wmi.c b/hw/xen_acpi_wmi.c
-index 5d378d0..e759e89 100644
---- a/hw/xen_acpi_wmi.c
-+++ b/hw/xen_acpi_wmi.c
-@@ -38,6 +38,7 @@
- #include "qemu-xen.h"
- #include "isa.h"
- #include "xen_acpi_wmi.h"
-+#include <sys/ioctl.h>
-
- #ifndef CONFIG_NO_XEN_ACPI_WMI
-
-@@ -46,7 +47,6 @@
- static xen_acpi_wmi_cmd_info_t cmd_info;
- static int xen_wmi_device = -ENODEV;
- extern FILE *logfile;
--extern int domid;
-
- /* #define XEN_ACPI_WMI_DEBUG */
- /* #define XEN_ACPI_WMI_DEBUG_EXT */
-@@ -224,7 +224,7 @@ void xen_acpi_wmi_allocate_output_buffer(size_t length)
- /*
- * xen_acpi_wmi_reallocate_output_buffer
- */
--int xen_acpi_wmi_reallocate_output_buffer()
-+int xen_acpi_wmi_reallocate_output_buffer(void)
- {
- xen_wmi_buffer_t *buffer;
-
-diff --git a/hw/xen_acpi_wmi.h b/hw/xen_acpi_wmi.h
-index 91e4c00..df289f2 100644
---- a/hw/xen_acpi_wmi.h
-+++ b/hw/xen_acpi_wmi.h
-@@ -61,6 +61,29 @@ typedef struct xen_acpi_wmi_cmd_info {
- 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/hw/xen_platform.c b/hw/xen_platform.c
-index e77ee9f..351e4cc 100644
---- a/hw/xen_platform.c
-+++ b/hw/xen_platform.c
-@@ -29,7 +29,7 @@
- #include "irq.h"
- #include "qemu-xen.h"
- #include "net.h"
--
-+#include "xen_platform.h"
- #include <assert.h>
- #include <xenguest.h>
-
-diff --git a/hw/xen_platform.h b/hw/xen_platform.h
-index 33af766..f7db3ce 100644
---- a/hw/xen_platform.h
-+++ b/hw/xen_platform.h
-@@ -6,4 +6,7 @@
- void pci_xen_platform_init(PCIBus *bus);
- void platform_fixed_ioport_init(void);
-
-+void platform_fixed_ioport_save(QEMUFile *f, void *opaque);
-+int platform_fixed_ioport_load(QEMUFile *f, void *opaque, int version_id);
-+
- #endif
-diff --git a/qemu-xen.h b/qemu-xen.h
-index 1410d4f..f694f0b 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -24,7 +24,6 @@ void timeoffset_get(void);
-
- /* xen_platform.c */
- #ifndef QEMU_TOOL
--void pci_xen_platform_init(PCIBus *bus);
- void xen_vga_populate_vram(uint64_t vram_addr, uint32_t size);
- void xen_vga_vram_map(uint64_t vram_addr, uint32_t size);
- void set_vram_mapping(void *opaque, unsigned long begin, unsigned long end);
-@@ -113,6 +112,7 @@ int *xenstore_get_domids(int *len);
- 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);
- int xenstore_refresh_thermal_info(void);
-diff --git a/xenstore.c b/xenstore.c
-index 690b78e..9e97e87 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -1379,7 +1379,7 @@ static char *xenstore_extended_power_mgmt_read(const char *key, unsigned int *le
- return value;
- }
-
--int xenstore_extended_power_mgmt_read_int(char *key, int default_value)
-+int xenstore_extended_power_mgmt_read_int(const char *key, int default_value)
- {
- int value = default_value;
- char *buffer;
diff --git a/console.h b/console.h
-index 88d971f..e682988 100644
+index 97214c0..4c51c50 100644
--- a/console.h
+++ b/console.h
-@@ -284,6 +284,9 @@ void vga_hw_update(void);
+@@ -290,6 +290,9 @@ void vga_hw_update(void);
void vga_hw_invalidate(void);
void vga_hw_screen_dump(const char *filename);
int is_graphic_console(void);
int is_fixedsize_console(void);
CharDriverState *text_console_init(const char *p);
-@@ -351,4 +354,8 @@ void hid_linux_add_binding(const int *, void (*)(void*), void *);
+@@ -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);
+int intel_leave(void);
+void intel_display_init(DisplayState *ds);
#endif
-diff --git a/dom0_driver.c b/dom0_driver.c
-index c58d188..1b5cd06 100644
---- a/dom0_driver.c
-+++ b/dom0_driver.c
-@@ -43,6 +43,7 @@
- #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);
-@@ -676,6 +677,11 @@ void dom0_driver_init(const char *position)
- 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;
diff --git a/hw/vga.c b/hw/vga.c
-index e47a23f..a4a1ef7 100644
+index 90bd544..b0f9f9c 100644
--- a/hw/vga.c
+++ b/hw/vga.c
-@@ -160,6 +160,18 @@ static uint8_t expand4to8[16];
-
+@@ -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;
static void vga_dumb_update_retrace_info(VGAState *s)
{
(void) s;
-@@ -2494,8 +2506,6 @@ static void vga_bios_init(VGAState *s)
+@@ -2473,8 +2485,6 @@ static void vga_bios_init(VGAState *s)
}
/* 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 6b5af55..ae32f82 100644
+index 0ffe1ec..d6379a9 100644
--- a/vl.c
+++ b/vl.c
-@@ -226,6 +226,7 @@ int win2k_install_hack = 0;
+@@ -235,6 +235,7 @@ 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;
-@@ -4224,6 +4225,7 @@ enum {
+@@ -4293,6 +4294,7 @@ enum {
QEMU_OPTION_vcpus,
QEMU_OPTION_vga_passthrough,
QEMU_OPTION_dom0_input,
/* Debug/Expert options: */
QEMU_OPTION_serial,
-@@ -4398,6 +4400,7 @@ static const QEMUOption qemu_options[] = {
+@@ -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 },
- #ifdef CONFIG_XEN
+ #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
{ "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
{ "xen-create", 0, QEMU_OPTION_xen_create },
-@@ -5273,6 +5276,9 @@ int main(int argc, char **argv, char **envp)
+@@ -5307,6 +5310,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_dom0_input:
dom0_input = optarg;
break;
-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 e1ce52d..dbd691a 100644
+index a261c8a..2e3cade 100644
--- a/hw/pc.h
+++ b/hw/pc.h
-@@ -109,6 +109,8 @@ void acpi_ac_adapter_state_changed(void);
- void acpi_power_button_pressed(void);
+@@ -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);
extern int no_hpet;
diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index d25f004..277f106 100644
+index c218782..3803824 100644
--- a/hw/piix4acpi.c
+++ b/hw/piix4acpi.c
@@ -29,6 +29,7 @@
#include <xen/hvm/ioreq.h>
#include <xen/hvm/params.h>
-@@ -57,6 +58,7 @@
- #define ACPI_AC_POWER_STATE_BIT 0x1c
+@@ -58,6 +59,7 @@
#define ACPI_POWER_BUTTON_BIT 0x1
- #define ACPI_LID_STATE_BIT 0x17
+ #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;
-@@ -194,6 +196,7 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
+@@ -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);
}
static inline int test_bit(uint8_t *map, int bit)
-@@ -248,6 +251,19 @@ void acpi_lid_state_changed(void)
+@@ -261,6 +264,19 @@ void acpi_lid_state_changed(void)
}
}
#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..5d378d0
---- /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"
-+
-+#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;
-+extern int domid;
-+
-+/* #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()
-+{
-+ 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..91e4c00
---- /dev/null
-+++ b/hw/xen_acpi_wmi.h
-@@ -0,0 +1,66 @@
-+/*
-+ * 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);
-+
-+#endif /* _XEN_ACPI_WMI_H */
-+
-+
diff --git a/qemu-xen.h b/qemu-xen.h
-index 61c0f25..81a2e33 100644
+index 8c1debd..60ee108 100644
--- a/qemu-xen.h
+++ b/qemu-xen.h
-@@ -118,6 +118,7 @@ int xenstore_refresh_battery_status(void);
+@@ -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);
uint32_t build_nr);
diff --git a/xen-hooks.mak b/xen-hooks.mak
-index d52e99d..cdf7b59 100644
+index d2f09fb..03d670e 100644
--- a/xen-hooks.mak
+++ b/xen-hooks.mak
@@ -35,6 +35,7 @@ OBJS += exec-dm.o
OBJS += helper2.o
OBJS += battery_mgmt.o
+OBJS += xen_acpi_wmi.o
- OBJS += dom0_driver.o
- OBJS += hid-linux.o
- OBJS += intel.o
+
+ ifdef CONFIG_STUBDOM
+ CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
diff --git a/xenstore.c b/xenstore.c
-index 3fa6115..5c33301 100644
+index 2ae1763..ebacace 100644
--- a/xenstore.c
+++ b/xenstore.c
-@@ -978,6 +978,11 @@ void xenstore_process_event(void *opaque)
+@@ -1011,6 +1011,11 @@ void xenstore_process_event(void *opaque)
goto out;
}
+ goto out;
+ }
+
- if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
- xenstore_process_logdirty_event();
+ if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
+ strlen(vec[XS_WATCH_TOKEN]) != 3)
goto out;
-@@ -1714,6 +1719,11 @@ void xenstore_register_for_pm_events(void)
- xs_watch(xsh, "/pm/events/powerbuttonpressed", "pwrbuttonpressedevt");
+@@ -1552,6 +1557,11 @@ void xenstore_register_for_pm_events(void)
+ xs_watch(xsh, "/pm/events/sleepbuttonpressed", "slpbuttonpressedevt");
}
+void xenstore_register_for_oem_events(void)
+
int xenstore_read_ac_adapter_state(void)
{
- int ac_state = 1;
+ return xenstore_extended_power_mgmt_read_int("ac_adapter", 1);
ioemu-compil
xenstore-watch-callbacks
dm-ready
+
+battery-management
+oem-features
+thermal-management
+fix-build-warnings
+
+
vga-passthrough
dom0-driver
intel
-battery_management
use-vga-cmdline
disable-aio
-oem-features
-sleep-btn-support
-thermal-management
-fix-build-warnings
+#sleep-btn-support
-diff --git a/hw/pc.h b/hw/pc.h
-index dbd691a..e43d490 100644
---- a/hw/pc.h
-+++ b/hw/pc.h
-@@ -107,6 +107,7 @@ 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);
-
- void acpi_oem_event(void);
diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index 277f106..3e7a7d6 100644
+index c6e4c4e..dd7d241 100644
--- a/hw/piix4acpi.c
+++ b/hw/piix4acpi.c
-@@ -57,6 +57,7 @@
- #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
- #define ACPI_OEM_EVENT_BIT 0x18
-
-@@ -239,6 +240,18 @@ void acpi_power_button_pressed(void)
- }
+@@ -254,6 +254,18 @@ void acpi_sleep_button_pressed(void)
+ }
}
+void acpi_sleep_button_pressed(void)
{
GPEState *s = &gpe_state;
diff --git a/xenstore.c b/xenstore.c
-index 5c33301..9e5d904 100644
+index 244f906..1a2e466 100644
--- a/xenstore.c
+++ b/xenstore.c
-@@ -973,6 +973,10 @@ void xenstore_process_event(void *opaque)
- goto out;
+@@ -1006,6 +1006,10 @@ void xenstore_process_event(void *opaque)
+ acpi_sleep_button_pressed();
}
+ if (!strcmp(vec[XS_WATCH_TOKEN], "slpbuttonpressedevt")) {
if (!strcmp(vec[XS_WATCH_TOKEN], "lidstatechangeevt")) {
acpi_lid_state_changed();
goto out;
-@@ -1717,6 +1721,7 @@ 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");
- }
-
- void xenstore_register_for_oem_events(void)
-diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
-index 3e7a7d6..5383032 100644
---- a/hw/piix4acpi.c
-+++ b/hw/piix4acpi.c
-@@ -198,6 +198,7 @@ static void acpi_map(PCIDevice *pci_dev, int region_num,
+diff -Nur a/hw/piix4acpi.c b/hw/piix4acpi.c
+--- a/hw/piix4acpi.c 2009-05-13 16:23:59.000000000 -0400
++++ b/hw/piix4acpi.c 2009-05-13 16:38:20.000000000 -0400
+@@ -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 @@
battery_mgmt_init(pci_dev);
xen_acpi_wmi_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
+diff -Nur a/hw/thermal_mgmt.c b/hw/thermal_mgmt.c
+--- a/hw/thermal_mgmt.c 1969-12-31 19:00:00.000000000 -0500
++++ b/hw/thermal_mgmt.c 2009-05-13 16:36:41.000000000 -0400
@@ -0,0 +1,79 @@
+/*
+ * thermal_mgmt.c
+
+#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
+diff -Nur a/hw/thermal_mgmt.h b/hw/thermal_mgmt.h
+--- a/hw/thermal_mgmt.h 1969-12-31 19:00:00.000000000 -0500
++++ b/hw/thermal_mgmt.h 2009-05-13 16:36:42.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ * thermal_mgmt.h
+
+#endif
+
-diff --git a/qemu-xen.h b/qemu-xen.h
-index 81a2e33..1410d4f 100644
---- a/qemu-xen.h
-+++ b/qemu-xen.h
-@@ -115,9 +115,12 @@ 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);
+diff -Nur a/qemu-xen.h b/qemu-xen.h
+--- a/qemu-xen.h 2009-05-13 16:21:56.000000000 -0400
++++ b/qemu-xen.h 2009-05-13 16:35:27.000000000 -0400
+@@ -111,9 +111,12 @@
+ 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_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 cdf7b59..55dd477 100644
---- a/xen-hooks.mak
-+++ b/xen-hooks.mak
-@@ -36,6 +36,7 @@ OBJS += pci_emulation.o
+diff -Nur a/xen-hooks.mak b/xen-hooks.mak
+--- a/xen-hooks.mak 2009-05-13 16:22:31.000000000 -0400
++++ b/xen-hooks.mak 2009-05-13 16:34:35.000000000 -0400
+@@ -36,6 +36,7 @@
OBJS += helper2.o
OBJS += battery_mgmt.o
OBJS += xen_acpi_wmi.o
+OBJS += thermal_mgmt.o
- OBJS += dom0_driver.o
- OBJS += hid-linux.o
- OBJS += intel.o
-diff --git a/xenstore.c b/xenstore.c
-index 9e5d904..690b78e 100644
---- a/xenstore.c
-+++ b/xenstore.c
-@@ -1379,6 +1379,20 @@ static char *xenstore_extended_power_mgmt_read(const char *key, unsigned int *le
- return value;
- }
-+int xenstore_extended_power_mgmt_read_int(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;
-@@ -1431,6 +1445,11 @@ int xenstore_refresh_battery_status(void)
+ ifdef CONFIG_STUBDOM
+ CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \
+diff -Nur a/xenstore.c b/xenstore.c
+--- a/xenstore.c 2009-05-13 16:21:26.000000000 -0400
++++ b/xenstore.c 2009-05-13 16:33:22.000000000 -0400
+@@ -1412,6 +1412,11 @@
return xenstore_extended_power_mgmt_event_trigger("refreshbatterystatus", "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
-@@ -1731,28 +1750,21 @@ void xenstore_register_for_oem_events(void)
-
- int xenstore_read_ac_adapter_state(void)
- {
-- int ac_state = 1;
-- char *buffer;
--
-- buffer = xenstore_extended_power_mgmt_read("ac_adapter", NULL);
-- if ( buffer == NULL )
-- return ac_state;
--
-- ac_state = strtoull(buffer, NULL, 10);
-- free(buffer);
-- return ac_state;
-+ return xenstore_extended_power_mgmt_read_int("ac_adapter", 1);
+@@ -1520,3 +1525,13 @@
+ return xenstore_extended_power_mgmt_read_int("lid_state", 1);
}
- int xenstore_read_lid_state(void)
- {
-- int lid_state = 1;
-- char * buffer;
-+ return xenstore_extended_power_mgmt_read_int("lid_state", 1);
-+}
-
-- buffer = xenstore_extended_power_mgmt_read("lid_state", NULL);
-- if ( buffer == NULL )
-- return lid_state;
+int xenstore_read_current_temperature(void)
+{
+ return xenstore_extended_power_mgmt_read_int("current_temperature", 0);
+}
-
-- lid_state = strtoull(buffer, NULL, 10);
-- free(buffer);
-- return lid_state;
++
+int xenstore_read_critical_temperature(void)
+{
+ return xenstore_extended_power_mgmt_read_int("critical_temperature", 100);
- }
++}
+
diff --git a/hw/pass-through.c b/hw/pass-through.c
-index b82fdf9..e74f1b0 100644
+index 6a53137..3420e95 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
-@@ -29,6 +29,8 @@
+@@ -90,6 +90,8 @@
#include "qemu-xen.h"
#include <unistd.h>
struct php_dev {
struct pt_dev *pt_dev;
uint8_t valid;
-@@ -1515,10 +1517,11 @@ static int pt_dev_is_virtfn(struct pci_dev *dev)
+@@ -1573,10 +1575,11 @@ static int pt_dev_is_virtfn(struct pci_dev *dev)
static int pt_register_regions(struct pt_dev *assigned_device)
{
/* Register PIO/MMIO BARs */
for ( i = 0; i < PCI_BAR_ENTRIES; i++ )
-@@ -1574,6 +1577,28 @@ static int pt_register_regions(struct pt_dev *assigned_device)
+@@ -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 )
+ {
return 0;
}
-@@ -1582,6 +1607,7 @@ static void pt_unregister_regions(struct pt_dev *assigned_device)
+@@ -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;
for ( i = 0; i < PCI_NUM_REGIONS; i++ )
{
-@@ -1623,6 +1649,26 @@ static void pt_unregister_regions(struct pt_dev *assigned_device)
+@@ -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 )
+ {
}
static uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
-@@ -3977,3 +4023,41 @@ err:
+@@ -4084,3 +4130,41 @@ err:
return status;
}
+ return val;
+}
diff --git a/hw/pass-through.h b/hw/pass-through.h
-index 3132387..7cd5a2b 100644
+index a503e80..1752e8d 100644
--- a/hw/pass-through.h
+++ b/hw/pass-through.h
-@@ -387,5 +387,9 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base)
+@@ -392,5 +392,9 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base)
return base & PCI_ADDR_MEM_MASK;
}
#endif /* __PASSTHROUGH_H__ */
diff --git a/hw/pci.c b/hw/pci.c
-index 62298d1..975f7c3 100644
+index d7c516e..b2f4d43 100644
--- a/hw/pci.c
+++ b/hw/pci.c
-@@ -27,11 +27,14 @@
- #include "net.h"
+@@ -28,11 +28,14 @@
#include "virtio-net.h"
+ #include "sysemu.h"
+#include "pass-through.h"
#include "exec-all.h"
struct PCIBus {
int bus_num;
int devfn_min;
-@@ -489,7 +492,30 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
+@@ -611,7 +614,30 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
goto the_end;
}
config_addr = addr & 0xff;
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 a20b6bf..2a9c5d5 100644
+index b273c75..e519705 100644
--- a/vl.c
+++ b/vl.c
-@@ -224,6 +224,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
+@@ -233,6 +233,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
#ifdef TARGET_I386
int win2k_install_hack = 0;
int rtc_td_hack = 0;
#endif
int usb_enabled = 0;
int smp_cpus = 1;
-@@ -4206,6 +4207,7 @@ enum {
+@@ -4275,6 +4276,7 @@ enum {
QEMU_OPTION_domainname,
QEMU_OPTION_acpi,
QEMU_OPTION_vcpus,
/* Debug/Expert options: */
QEMU_OPTION_serial,
-@@ -4378,6 +4380,7 @@ static const QEMUOption qemu_options[] = {
+@@ -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 },
- #ifdef CONFIG_XEN
+ #if defined(CONFIG_XEN) && !defined(CONFIG_DM)
{ "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
{ "xen-create", 0, QEMU_OPTION_xen_create },
-@@ -5247,6 +5250,9 @@ int main(int argc, char **argv, char **envp)
+@@ -5281,6 +5284,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_disable_opengl:
opengl_enabled = 0;
break;