diff --git a/hw/xenner_emudev.c b/hw/xenner_emudev.c
new file mode 100644
index 0000000..dea617e
--- /dev/null
+++ b/hw/xenner_emudev.c
@@ -0,0 +1,107 @@
+/*
+ *  Copyright (C) Red Hat 2007
+ *  Copyright (C) Novell Inc. 2010
+ *
+ *  Author(s): Gerd Hoffmann <kraxel@redhat.com>
+ *             Alexander Graf <agraf@suse.de>
+ *
+ *  Xenner communication device
+ *
+ *  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; under version 2 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <inttypes.h>
+
+#include "xenner_emudev.h"
+
+void emudev_write_entry(struct emudev_state *e, uint32_t value)
+{
+    e->entry = value;
+}
+
+void emudev_write_value(struct emudev_state *e, uint32_t value)
+{
+    uint16_t type, index;
+    int high_32;
+
+    type = e->entry >> 16;
+    high_32 = type & EMUDEV_CONF_HIGH_32;
+    type &= ~EMUDEV_CONF_HIGH_32;
+    index = e->entry & 0xffff;
+    switch (type) {
+    case EMUDEV_CONF_GRANT_TABLE_PFNS:
+        if (index < EMUDEV_CONF_GRANT_TABLE_COUNT)
+            e->gnttab[index] = value;
+        break;
+    case EMUDEV_CONF_EVTCHN_TO_PIN:
+        if (index < EMUDEV_CONF_EVTCHN_TO_PIN_COUNT)
+            e->evtchn[index] = value;
+        break;
+    case EMUDEV_CONF_COMMAND_RESULT:
+        if (index < EMUDEV_CONF_COMMAND_RESULT_COUNT)
+            e->result[index] = value;
+        break;
+    default:
+        if (type >= EMUDEV_CONF_SIMPLE_COUNT) {
+            break;
+        }
+        if (high_32) {
+            e->config[type] = (e->config[type] & 0x00000000ffffffffULL)
+                            | ((uint64_t)value << 32);
+        } else {
+            e->config[type] = (e->config[type] & 0xffffffff00000000ULL)
+                            | ((uint64_t)value);
+        }
+        break;
+    }
+}
+
+uint32_t emudev_read_value(struct emudev_state *e)
+{
+    uint16_t type, index;
+    int high_32;
+    uint64_t r = -1;
+
+    type = e->entry >> 16;
+    high_32 = type & EMUDEV_CONF_HIGH_32;
+    type &= ~EMUDEV_CONF_HIGH_32;
+    index = e->entry & 0xffff;
+    switch (type) {
+    case EMUDEV_CONF_GRANT_TABLE_PFNS:
+        if (index < EMUDEV_CONF_GRANT_TABLE_COUNT) {
+            r = e->gnttab[index];
+        }
+        break;
+    case EMUDEV_CONF_EVTCHN_TO_PIN:
+        if (index < EMUDEV_CONF_EVTCHN_TO_PIN_COUNT) {
+            r = e->evtchn[index];
+        }
+        break;
+    case EMUDEV_CONF_COMMAND_RESULT:
+        if (index < EMUDEV_CONF_COMMAND_RESULT_COUNT) {
+            r = e->result[index];
+        }
+        break;
+    default:
+        if (type < EMUDEV_CONF_SIMPLE_COUNT) {
+            r = e->config[type];
+        }
+        break;
+    }
+
+    if (high_32) {
+        return (uint32_t)(r >> 32);
+    }
+
+    return (uint32_t)r;
+}
diff --git a/hw/xenner_emudev.h b/hw/xenner_emudev.h
new file mode 100644
index 0000000..e6b8676
--- /dev/null
+++ b/hw/xenner_emudev.h
@@ -0,0 +1,108 @@
+/*
+ *  Copyright (C) Red Hat 2007
+ *  Copyright (C) Novell Inc. 2010
+ *
+ *  Author(s): Gerd Hoffmann <kraxel@redhat.com>
+ *             Alexander Graf <agraf@suse.de>
+ *
+ *  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; under version 2 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __XENNER_EMUDEV_H__
+#define __XENNER_EMUDEV_H__ 1
+
+/*
+ * I/O ports for the virtual emu device
+ *     - CONF_ENTRY (write)
+ *       bits 31 .. 16  --  config type
+ *       bits 15 ..  0  --  config index
+ *     - CONF_VALUE (read/write)
+ *       32bit config value
+ *     - COMMAND (write)
+ *       bits 32 .. 16  --  command
+ *       bits 15 ..  0  --  argument
+ */
+#define EMUDEV_REG_BASE                      (0xe0)
+#define EMUDEV_REG_CONF_ENTRY                (EMUDEV_REG_BASE)
+#define EMUDEV_REG_CONF_VALUE                (EMUDEV_REG_BASE+4)
+#define EMUDEV_REG_COMMAND                   (EMUDEV_REG_BASE+8)
+#define EMUDEV_REG_RESERVED                  (EMUDEV_REG_BASE+12)
+
+/* simple entries, read */
+#define EMUDEV_CONF_DEBUG_LEVEL              0x00
+#define EMUDEV_CONF_EMU_START_PFN            0x01
+#define EMUDEV_CONF_EMU_PAGE_COUNT           0x02
+#define EMUDEV_CONF_M2P_START_PFN            0x03
+#define EMUDEV_CONF_M2P_PAGE_COUNT           0x04
+#define EMUDEV_CONF_GUEST_START_PFN          0x05
+#define EMUDEV_CONF_GUEST_PAGE_COUNT         0x06
+#define EMUDEV_CONF_TOTAL_PAGE_COUNT         0x07
+#define EMUDEV_CONF_NR_VCPUS                 0x08
+#define EMUDEV_CONF_HVM_XENSTORE_PFN         0x09
+#define EMUDEV_CONF_HVM_XENSTORE_EVTCHN      0x0a
+#define EMUDEV_CONF_MFN_CONSOLE              0x0b
+#define EMUDEV_CONF_MFN_XENSTORE             0x0c
+#define EMUDEV_CONF_PFN_START_INFO           0x0d
+#define EMUDEV_CONF_PV_VIRT_ENTRY            0x10
+#define EMUDEV_CONF_PV_VIRT_BASE             0x11
+#define EMUDEV_CONF_HYPERCALL_PAGE           0x12
+#define EMUDEV_CONF_EVTCH_CONSOLE            0x13
+#define EMUDEV_CONF_EVTCH_XENSTORE           0x14
+#define EMUDEV_CONF_PFN_INIT_PT              0x15
+#define EMUDEV_CONF_PFN_CMDLINE              0x16
+#define EMUDEV_CONF_PFN_INITRD               0x17
+#define EMUDEV_CONF_INITRD_LEN               0x18
+#define EMUDEV_CONF_PFN_MFN_LIST             0x19
+/* simple entries, write */
+#define EMUDEV_CONF_BOOT_CTXT_PFN            0x40
+#define EMUDEV_CONF_NEXT_SECONDARY_VCPU      0x42
+#define EMUDEV_CONF_HVM_CALLBACK_IRQ         0x43
+#define EMUDEV_CONF_VMINFO_PFN               0x70 /* temporary */
+/* simple count */
+#define EMUDEV_CONF_SIMPLE_COUNT             0x80
+/* high dword marker */
+#define EMUDEV_CONF_HIGH_32                  0x8000
+
+/* indexed config entries */
+#define EMUDEV_CONF_GRANT_TABLE_PFNS         0x80
+#define EMUDEV_CONF_GRANT_TABLE_COUNT        16
+#define EMUDEV_CONF_EVTCHN_TO_PIN            0x81
+#define EMUDEV_CONF_EVTCHN_TO_PIN_COUNT      64
+#define EMUDEV_CONF_COMMAND_RESULT           0x82
+#define EMUDEV_CONF_COMMAND_RESULT_COUNT     64
+
+/* commands */
+#define EMUDEV_CMD_NOP                       1
+#define EMUDEV_CMD_WRITE_CHAR                2
+#define EMUDEV_CMD_CONFIGURATION_DONE        3
+#define EMUDEV_CMD_EVTCHN_ALLOC              4
+#define EMUDEV_CMD_EVTCHN_SEND               5
+#define EMUDEV_CMD_INIT_SECONDARY_VCPU       6
+#define EMUDEV_CMD_GUEST_SHUTDOWN            7
+#define EMUDEV_CMD_EVTCHN_CLOSE              8
+
+/* --------- host side bits --------- */
+
+struct emudev_state {
+    uint32_t   entry;
+    uint64_t   config[EMUDEV_CONF_SIMPLE_COUNT];
+    uint32_t   gnttab[EMUDEV_CONF_GRANT_TABLE_COUNT];
+    uint32_t   evtchn[EMUDEV_CONF_EVTCHN_TO_PIN_COUNT];
+    uint32_t   result[EMUDEV_CONF_COMMAND_RESULT_COUNT];
+};
+
+void emudev_write_entry(struct emudev_state *e, uint32_t value);
+void emudev_write_value(struct emudev_state *e, uint32_t value);
+uint32_t emudev_read_value(struct emudev_state *e);
+
+#endif /* __XENNER_EMUDEV_H__ */
