]> xenbits.xensource.com Git - qemu-xen-3.3-testing.git/commitdiff
Merge with xen-unstable tip 17958
authorIan Jackson <iwj@mariner.uk.xensource.com>
Fri, 4 Jul 2008 15:35:26 +0000 (16:35 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 4 Jul 2008 15:35:26 +0000 (16:35 +0100)
This was achieved with
  hg diff -r{17831,17958} tools/ioemu
and feeding the result to patch and fixing up conflicts.

As an exception, xenfb.c was done the other way around:
 * hg update 17737, apply vga-patch-from-xen-unstable-17737\:c93a913c221f
 * diff that against git 79a235b20a6833fe5bdc78b52921cdd2ad12f284
   (current qemu-xen tip)
 * cp hg 17958's xenfb.c into git, apply patch from above, fixing up
   changes; one change dropped (removal of call to fbfront_resize
   in xenfb_pv_resize_shared)

18 files changed:
hw/pass-through.c
hw/pc.c
hw/pci.h
hw/pci_emulation.c [new file with mode: 0644]
hw/pci_emulation.h [new file with mode: 0644]
hw/pt-msi.c
hw/pt-msi.h
hw/usb-msd.c
hw/usb.h
hw/xen_console.c
hw/xenfb.c
hw/xenfb.h
i386-dm/exec-dm.c
monitor.c
vl.c
xen-hooks.mak
xenfbfront.c [new file with mode: 0644]
xenstore.c

index 996ffc138a3f13332a4ded58a432ac02381caf89..b10bd214519f0ffee001eccc2d2d49815548a902 100644 (file)
@@ -515,6 +515,7 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
         PT_LOG("Error: couldn't locate device in libpci structures\n");
         return NULL;
     }
+    pci_fill_info(pci_dev, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES);
 
     if ( e_devfn == PT_VIRT_DEVFN_AUTO ) {
         /*indicate a static assignment(not hotplug), so find a free PCI hot plug slot */
diff --git a/hw/pc.c b/hw/pc.c
index fa3ca1ac21ff9c82f674611b3da761e4539761d4..c87117a4ee5ea9b4734067ae00e0361fa993ef57 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1110,6 +1110,13 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
            }
         }
     }
+
+    if (pci_enabled) {
+        PCI_EMULATION_INFO *p;
+        for (p = PciEmulationInfoHead; p != NULL; p = p->next) {
+            pci_emulation_init(pci_bus, p);
+        }
+    }
 }
 
 static void pc_init_pci(ram_addr_t ram_size, int vga_ram_size,
index afe5df05b906eff67a4740132673cff6144f9913..250c8ab041bb1dbd1e661d234ff5bbfd564fc557 100644 (file)
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -115,6 +115,9 @@ int bdf_to_slot(char*);
 int power_on_php_slot(int);
 int power_off_php_slot(int);
 
+/* pci_emulation.c */
+#include "hw/pci_emulation.h"
 void do_pci_add(char *devname);
 void do_pci_del(char *devname);
 
diff --git a/hw/pci_emulation.c b/hw/pci_emulation.c
new file mode 100644 (file)
index 0000000..0a4a7b4
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Changes to PCI emulation made by Marathon Technologies, June 2008
+ */
+
+#include "vl.h"
+
+typedef struct {
+    PCIDevice dev;
+}   PCI_EMULATION_State;
+
+void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info)
+{
+    char *p;
+    int i;
+    int ret;
+    for (p = config_text, i = 0; *p != '\0'; p++) {
+        if (*p == ':') {
+            break;
+        }
+        if (i < sizeof(pci_emulation_info->name) - 1) {
+            pci_emulation_info->name[i] = *p;
+            i++;
+        }
+    }
+    pci_emulation_info->name[i] = '\0';
+    if (*p == '\0') return;
+    p++;
+    ret = sscanf(p, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
+                 &(pci_emulation_info->vendorid),
+                 &(pci_emulation_info->deviceid),
+                 &(pci_emulation_info->command),
+                 &(pci_emulation_info->status),
+                 &(pci_emulation_info->revision),
+                 &(pci_emulation_info->classcode),
+                 &(pci_emulation_info->headertype),
+                 &(pci_emulation_info->subvendorid),
+                 &(pci_emulation_info->subsystemid),
+                 &(pci_emulation_info->interruputline),
+                 &(pci_emulation_info->interruputpin));
+#ifdef DEBUG
+    fprintf(logfile, "qemu: pciemulation %s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
+            pci_emulation_info->name,
+            pci_emulation_info->vendorid,
+            pci_emulation_info->deviceid,
+            pci_emulation_info->command,
+            pci_emulation_info->status,
+            pci_emulation_info->revision,
+            pci_emulation_info->classcode,
+            pci_emulation_info->headertype,
+            pci_emulation_info->subvendorid,
+            pci_emulation_info->subsystemid,
+            pci_emulation_info->interruputline,
+            pci_emulation_info->interruputpin);
+#endif
+    return;
+}
+
+static void pci_emulation_save(QEMUFile *f, void *opaque)
+{
+    PCIDevice *d = opaque;
+
+    pci_device_save(d, f);
+}
+
+static int pci_emulation_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PCIDevice *d = opaque;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    return pci_device_load(d, f);
+}
+
+
+void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info)
+{
+    int instance_id;
+    PCI_EMULATION_State *d;
+    uint8_t *pci_conf;
+
+#ifdef DEBUG
+    fprintf(logfile, "qemu: pciinit\n");
+#endif
+    
+    d = (PCI_EMULATION_State *)pci_register_device(bus,
+                                                   pci_emulation_info->name, 
+                                                   sizeof(PCI_EMULATION_State),
+                                                   -1, 
+                                                    NULL, NULL);
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = pci_emulation_info->vendorid & 0xff;
+    pci_conf[0x01] = (pci_emulation_info->vendorid & 0xff00) >> 8;
+    pci_conf[0x02] = pci_emulation_info->deviceid & 0xff;
+    pci_conf[0x03] = (pci_emulation_info->deviceid & 0xff00) >> 8;
+    pci_conf[0x04] = pci_emulation_info->command & 0xff;
+    pci_conf[0x05] = (pci_emulation_info->command & 0xff00) >> 8;
+    pci_conf[0x06] = pci_emulation_info->status & 0xff;
+    pci_conf[0x07] = (pci_emulation_info->status & 0xff00) >> 8;
+    pci_conf[0x08] = pci_emulation_info->revision & 0xff;
+    pci_conf[0x09] = pci_emulation_info->classcode & 0xff;
+    pci_conf[0x0a] = (pci_emulation_info->classcode & 0xff00) >> 8;
+    pci_conf[0x0b] = (pci_emulation_info->classcode & 0xff0000) >> 16;
+    pci_conf[0x0e] = pci_emulation_info->headertype & 0xff;
+    pci_conf[0x2c] = pci_emulation_info->subvendorid & 0xff;
+    pci_conf[0x2d] = (pci_emulation_info->subvendorid & 0xff00) >> 8;
+    pci_conf[0x2e] = pci_emulation_info->subsystemid & 0xff;
+    pci_conf[0x2f] = (pci_emulation_info->subsystemid & 0xff00) >> 8;
+    pci_conf[0x3c] = pci_emulation_info->interruputline & 0xff;
+    pci_conf[0x3d] = pci_emulation_info->interruputpin & 0xff;
+
+    instance_id = pci_bus_num(bus) << 8 | d->dev.devfn;
+    register_savevm(pci_emulation_info->name, instance_id,
+                    1, pci_emulation_save, pci_emulation_load, d);
+
+
+    return;    
+}
diff --git a/hw/pci_emulation.h b/hw/pci_emulation.h
new file mode 100644 (file)
index 0000000..abb7572
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Changes to PCI emulation made by Marathon Technologies, June 2008
+ */
+
+typedef struct PCI_EMULATION_INFO_t {
+    struct PCI_EMULATION_INFO_t *next;
+    char name[32];
+    unsigned int vendorid;
+    unsigned int deviceid;
+    unsigned int command;
+    unsigned int status;
+    unsigned int revision;
+    unsigned int classcode;
+    unsigned int headertype;
+    unsigned int subvendorid;
+    unsigned int subsystemid;
+    unsigned int interruputline;
+    unsigned int interruputpin;
+}   PCI_EMULATION_INFO;
+    
+void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info);
+void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info);
+
+extern PCI_EMULATION_INFO *PciEmulationInfoHead;
index 0af05e788f5b45fad533846f5ae7296a44251eaa..5e7c4795515f5689c2c4e6833a7ebb58358f6971 100644 (file)
@@ -94,6 +94,13 @@ static int pt_msi_setup(struct pt_dev *dev)
         PT_LOG("error map msi\n");
         return -1;
     }
+
+    if ( pirq < 0 )
+    {
+        PT_LOG("invalid pirq number\n");
+        return -1;
+    }
+
     dev->msi->pirq = pirq;
     PT_LOG("msi mapped with pirq %x\n", pirq);
 
index c0d542913c20cd971a0ed2a8f32038ef3d67600f..d08d890157b52ba5f0560021ce48e7270fc025b4 100644 (file)
@@ -2,10 +2,32 @@
 #define _PT_MSI_H
 
 #include "vl.h"
-#include "pci/header.h"
 #include "pci/pci.h"
 #include "pass-through.h"
 
+#define  PCI_CAP_ID_MSI     0x05    /* Message Signalled Interrupts */
+#define  PCI_CAP_ID_MSIX    0x11    /* MSI-X */
+
+/* Message Signalled Interrupts registers */
+#define PCI_MSI_FLAGS       2   /* Various flags */
+#define  PCI_MSI_FLAGS_64BIT    0x80    /* 64-bit addresses allowed */
+#define  PCI_MSI_FLAGS_QSIZE    0x70    /* Message queue size configured */
+#define  PCI_MSI_FLAGS_QMASK    0x0e    /* Maximum queue size available */
+#define  PCI_MSI_FLAGS_ENABLE   0x01    /* MSI feature enabled */
+#define PCI_MSI_RFU         3   /* Rest of capability flags */
+#define PCI_MSI_ADDRESS_LO  4   /* Lower 32 bits */
+#define PCI_MSI_ADDRESS_HI  8   /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+#define PCI_MSI_DATA_32     8   /* 16 bits of data for 32-bit devices */
+#define PCI_MSI_DATA_64     12  /* 16 bits of data for 64-bit devices */
+
+/* MSI-X */
+#define  PCI_MSIX_ENABLE    0x8000
+#define  PCI_MSIX_MASK      0x4000
+#define  PCI_MSIX_TABSIZE   0x03ff
+#define PCI_MSIX_TABLE      4
+#define PCI_MSIX_PBA        8
+#define  PCI_MSIX_BIR       0x7
+
 #define MSI_FLAG_UNINIT 0x1000
 #define PT_MSI_MAPPED   0x2000
 
@@ -29,7 +51,7 @@
    + */
 
 #define MSI_ADDR_HEADER                0xfee00000
-#define MSI_TARGET_CPU_SHIFT                  12
+#define MSI_TARGET_CPU_SHIFT           12
 
 #define MSI_ADDR_DESTID_MASK           0xfff0000f
 #define     MSI_ADDR_DESTID_CPU(cpu)   ((cpu) << MSI_TARGET_CPU_SHIFT)
index 01d492d42de0bb43fc755a843de8caaaa9341c22..b3ec88ec0ccff1ef2dd1ace520a15a664d24eb52 100644 (file)
@@ -513,7 +513,7 @@ static void usb_msd_handle_destroy(USBDevice *dev)
     qemu_free(s);
 }
 
-USBDevice *usb_msd_init(const char *filename)
+USBDevice *usb_msd_init(const char *filename, BlockDriver *drv)
 {
     MSDState *s;
     BlockDriverState *bdrv;
@@ -523,7 +523,7 @@ USBDevice *usb_msd_init(const char *filename)
         return NULL;
 
     bdrv = bdrv_new("usb");
-    if (bdrv_open(bdrv, filename, 0) < 0)
+    if (bdrv_open2(bdrv, filename, 0, drv) < 0)
         goto fail;
     if (qemu_key_check(bdrv, filename))
         goto fail;
index 9b759d456002dff56fc339f10b2246c74f2bf648..e3859334da4e646b4d23714d6584e4eae4c35083 100644 (file)
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -217,7 +217,7 @@ USBDevice *usb_tablet_init(void);
 USBDevice *usb_keyboard_init(void);
 
 /* usb-msd.c */
-USBDevice *usb_msd_init(const char *filename);
+USBDevice *usb_msd_init(const char *filename, BlockDriver *drv);
 
 /* usb-wacom.c */
 USBDevice *usb_wacom_init(void);
index 14c2c8794e9b7bf36d938383d7b7df5897cd5272..9ec08e8d90ba051b46b21f54dde5ef91df4aa76a 100644 (file)
@@ -163,16 +163,18 @@ int xs_gather(struct xs_handle *xs, const char *dir, ...)
 
 static int domain_create_ring(struct domain *dom)
 {
-       int err, remote_port, ring_ref, rc;
+       int err, remote_port, ring_ref, limit, rc;
 
        err = xs_gather(dom->xsh, dom->serialpath,
                        "ring-ref", "%u", &ring_ref,
                        "port", "%i", &remote_port,
+                       "limit", "%i", &limit,
                        NULL);
        if (err) {
                err = xs_gather(dom->xsh, dom->conspath,
                                "ring-ref", "%u", &ring_ref,
                                "port", "%i", &remote_port,
+                               "limit", "%i", &limit,
                                NULL);
                if (err) {
                        fprintf(stderr, "Console: failed to find ring-ref/port yet\n");
@@ -181,7 +183,9 @@ static int domain_create_ring(struct domain *dom)
                dom->use_consolepath = 1;
        } else
                dom->use_consolepath = 0;
-       fprintf(stderr, "Console: got ring-ref %d port %d\n", ring_ref, remote_port);
+       dom->buffer.max_capacity = limit;
+       fprintf(stderr, "Console: got ring-ref %d port %d limit %d\n", 
+               ring_ref, remote_port, limit);
 
        if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
                goto out;
index c684cdceff4deeff93f43d6b4339f1c9db222a30..41ede97c5caa03dae209ed21b4980008848872a4 100644 (file)
 #include "qemu-common.h"
 #include "config.h"
 
-#ifdef CONFIG_STUBDOM
-#include <semaphore.h>
-#include <sched.h>
-#include <fbfront.h>
-#endif
-
 #ifndef BTN_LEFT
 #define BTN_LEFT 0x110 /* from <linux/input.h> */
 #endif
@@ -97,7 +91,7 @@ static int xenfb_register_console(struct xenfb *xenfb);
  * Scancodes are hardware-specific.  These maps assumes a 
  * standard AT or PS/2 keyboard which is what QEMU feeds us.
  */
-static const unsigned char atkbd_set2_keycode[512] = {
+const unsigned char atkbd_set2_keycode[512] = {
 
          0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
          0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
@@ -119,7 +113,7 @@ static const unsigned char atkbd_set2_keycode[512] = {
 
 };
 
-static const unsigned char atkbd_unxlate_table[128] = {
+const unsigned char atkbd_unxlate_table[128] = {
 
          0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
         21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
@@ -1347,333 +1341,6 @@ static int xenfb_register_console(struct xenfb *xenfb) {
         return 0;
 }
 
-#ifdef CONFIG_STUBDOM
-typedef struct XenFBState {
-    struct semaphore kbd_sem;
-    struct kbdfront_dev *kbd_dev;
-    struct fbfront_dev *fb_dev;
-    void *vga_vram, *nonshared_vram;
-    DisplayState *ds;
-} XenFBState;
-
-XenFBState *xs;
-
-static char *kbd_path, *fb_path;
-
-static unsigned char linux2scancode[KEY_MAX + 1];
-
-static void xenfb_pv_colourdepth(DisplayState *ds, int depth);
-
-int xenfb_connect_vkbd(const char *path)
-{
-    kbd_path = strdup(path);
-    return 0;
-}
-
-int xenfb_connect_vfb(const char *path)
-{
-    fb_path = strdup(path);
-    return 0;
-}
-
-static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    if (!fb_dev)
-        return;
-    fbfront_update(fb_dev, x, y, w, h);
-}
-
-static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    int offset;
-    fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize);
-    xenfb_pv_colourdepth(ds, depth);
-    ds->width = w;
-    ds->height = h;
-    if (!linesize)
-        ds->shared_buf = 0;
-    if (!ds->shared_buf)
-        linesize = w * 4;
-    ds->linesize = linesize;
-    if (!fb_dev)
-        return;
-    if (ds->shared_buf) {
-        offset = pixels - xs->vga_vram;
-        ds->data = pixels;
-        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
-    } else {
-        ds->data = xs->nonshared_vram;
-        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
-    }
-}
-
-static void xenfb_pv_resize(DisplayState *ds, int w, int h)
-{
-    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
-}
-
-static void xenfb_pv_colourdepth(DisplayState *ds, int depth)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    static int lastdepth = -1;
-    if (!depth) {
-        ds->shared_buf = 0;
-        ds->depth = 32;
-    } else {
-        ds->shared_buf = 1;
-        ds->depth = depth;
-    }
-    if (depth != lastdepth) {
-        fprintf(stderr,"redepth to %d required\n", depth);
-        lastdepth = depth;
-    } else return;
-    if (!fb_dev)
-        return;
-    if (ds->shared_buf) {
-        ds->data = NULL;
-    } else {
-        ds->data = xs->nonshared_vram;
-    }
-}
-
-static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    int offset = pixels - xs->vga_vram;
-    ds->data = pixels;
-    if (!fb_dev)
-        return;
-    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
-}
-
-static void xenfb_pv_refresh(DisplayState *ds)
-{
-    vga_hw_update();
-}
-
-static void xenfb_fb_handler(void *opaque)
-{
-#define FB_NUM_BATCH 4
-    union xenfb_in_event buf[FB_NUM_BATCH];
-    int n, i;
-    XenFBState *xs = opaque;
-    DisplayState *ds = xs->ds;
-
-    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
-    for (i = 0; i < n; i++) {
-        switch (buf[i].type) {
-        case XENFB_TYPE_REFRESH_PERIOD:
-            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
-                /* Sleeping interval */
-                ds->idle = 1;
-                ds->gui_timer_interval = 500;
-            } else {
-                /* Set interval */
-                ds->idle = 0;
-                ds->gui_timer_interval = buf[i].refresh_period.period;
-            }
-        default:
-            /* ignore unknown events */
-            break;
-        }
-    }
-}
-
-static void xenfb_kbd_handler(void *opaque)
-{
-#define KBD_NUM_BATCH 64
-    union xenkbd_in_event buf[KBD_NUM_BATCH];
-    int n, i;
-    XenFBState *xs = opaque;
-    DisplayState *s = xs->ds;
-    static int buttons;
-    static int x, y;
-
-    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
-    for (i = 0; i < n; i++) {
-        switch (buf[i].type) {
-
-            case XENKBD_TYPE_MOTION:
-                fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
-                break;
-
-            case XENKBD_TYPE_POS:
-            {
-                int new_x = buf[i].pos.abs_x;
-                int new_y = buf[i].pos.abs_y;
-                if (new_x >= s->width)
-                    new_x = s->width - 1;
-                if (new_y >= s->height)
-                    new_y = s->height - 1;
-                if (kbd_mouse_is_absolute()) {
-                    kbd_mouse_event(
-                            new_x * 0x7FFF / (s->width - 1),
-                            new_y * 0x7FFF / (s->height - 1),
-                            buf[i].pos.rel_z,
-                            buttons);
-                } else {
-                    kbd_mouse_event(
-                            new_x - x,
-                            new_y - y,
-                            buf[i].pos.rel_z,
-                            buttons);
-                }
-                x = new_x;
-                y = new_y;
-                break;
-            }
-
-            case XENKBD_TYPE_KEY:
-            {
-                int keycode = buf[i].key.keycode;
-                int button = 0;
-
-                if (keycode == BTN_LEFT)
-                    button = MOUSE_EVENT_LBUTTON;
-                else if (keycode == BTN_RIGHT)
-                    button = MOUSE_EVENT_RBUTTON;
-                else if (keycode == BTN_MIDDLE)
-                    button = MOUSE_EVENT_MBUTTON;
-
-                if (button) {
-                    if (buf[i].key.pressed)
-                        buttons |=  button;
-                    else
-                        buttons &= ~button;
-                    if (kbd_mouse_is_absolute())
-                        kbd_mouse_event(
-                                x * 0x7FFF / (s->width - 1),
-                                y * 0x7FFF / (s->height - 1),
-                                0,
-                                buttons);
-                    else
-                        kbd_mouse_event(0, 0, 0, buttons);
-                } else {
-                    int scancode = linux2scancode[keycode];
-                    if (!scancode) {
-                        fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
-                        break;
-                    }
-                    if (scancode & 0x80) {
-                        kbd_put_keycode(0xe0);
-                        scancode &= 0x7f;
-                    }
-                    if (!buf[i].key.pressed)
-                        scancode |= 0x80;
-                    kbd_put_keycode(scancode);
-                }
-                break;
-            }
-        }
-    }
-}
-
-static void kbdfront_thread(void *p)
-{
-    int scancode, keycode;
-    XenFBState *xs = p;
-    xs->kbd_dev = init_kbdfront(kbd_path, 1);
-    if (!xs->kbd_dev) {
-        fprintf(stderr,"can't open keyboard\n");
-        exit(1);
-    }
-    up(&xs->kbd_sem);
-    for (scancode = 0; scancode < 128; scancode++) {
-        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
-        linux2scancode[keycode] = scancode;
-        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
-        linux2scancode[keycode] = scancode | 0x80;
-    }
-}
-
-int xenfb_pv_display_init(DisplayState *ds)
-{
-    if (!fb_path || !kbd_path)
-        return -1;
-
-    xs = qemu_mallocz(sizeof(XenFBState));
-    if (!xs)
-        return -1;
-
-    init_SEMAPHORE(&xs->kbd_sem, 0);
-    xs->ds = ds;
-
-    create_thread("kbdfront", kbdfront_thread, (void*) xs);
-
-    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
-    memset(ds->data, 0, VGA_RAM_SIZE);
-    ds->opaque = xs;
-    ds->depth = 32;
-    ds->bgr = 0;
-    ds->width = 640;
-    ds->height = 400;
-    ds->linesize = 640 * 4;
-    ds->dpy_update = xenfb_pv_update;
-    ds->dpy_resize = xenfb_pv_resize;
-    ds->dpy_resize_shared = xenfb_pv_resize_shared;
-    ds->dpy_setdata = xenfb_pv_setdata;
-    ds->dpy_refresh = xenfb_pv_refresh;
-    return 0;
-}
-
-int xenfb_pv_display_start(void *data)
-{
-    DisplayState *ds;
-    struct fbfront_dev *fb_dev;
-    int kbd_fd, fb_fd;
-    int offset = 0;
-    unsigned long *mfns;
-    int n = VGA_RAM_SIZE / PAGE_SIZE;
-    int i;
-
-    if (!fb_path || !kbd_path)
-        return 0;
-
-    ds = xs->ds;
-    xs->vga_vram = data;
-    mfns = malloc(2 * n * sizeof(*mfns));
-    for (i = 0; i < n; i++)
-        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
-    for (i = 0; i < n; i++)
-        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
-
-    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n);
-    free(mfns);
-    if (!fb_dev) {
-        fprintf(stderr,"can't open frame buffer\n");
-        exit(1);
-    }
-    free(fb_path);
-
-    if (ds->shared_buf) {
-        offset = (void*) ds->data - xs->vga_vram;
-    } else {
-        offset = VGA_RAM_SIZE;
-        ds->data = xs->nonshared_vram;
-    }
-    if (offset)
-        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
-
-    down(&xs->kbd_sem);
-    free(kbd_path);
-
-    kbd_fd = kbdfront_open(xs->kbd_dev);
-    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
-
-    fb_fd = fbfront_open(fb_dev);
-    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
-
-    xs->fb_dev = fb_dev;
-    return 0;
-}
-#endif
-
 /*
  * Local variables:
  *  c-indent-level: 8
index d782aa9abc08a12eda7c54069323d6df514d2757..9d2095094a381e667250b399fb6bd2c6fb1963ef 100644 (file)
@@ -9,5 +9,7 @@ struct xenfb;
 
 struct xenfb *xenfb_new(int domid, DisplayState *ds);
 void xenfb_shutdown(struct xenfb *xenfb);
+extern const unsigned char atkbd_set2_keycode[512];
+extern const unsigned char atkbd_unxlate_table[128];
 
 #endif
index 9e69d4e8495ecdbcddd34dce8423facf69ad802a..d511021c418c78fdeb3df9dba11aa2a1fd53d295 100644 (file)
@@ -484,9 +484,11 @@ static void memcpy_words(void *dst, void *src, size_t n)
 }
 #endif
 
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
-                            int len, int is_write)
+void cpu_physical_memory_rw(target_phys_addr_t _addr, uint8_t *buf, 
+                            int _len, int is_write)
 {
+    target_phys_addr_t addr = _addr;
+    int len = _len;
     int l, io_index;
     uint8_t *ptr;
     uint32_t val;
@@ -521,6 +523,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
             } else if ((ptr = phys_ram_addr(addr)) != NULL) {
                 /* Writing to RAM */
                 memcpy_words(ptr, buf, l);
+#ifndef CONFIG_STUBDOM
                 if (logdirty_bitmap != NULL) {
                     /* Record that we have dirtied this frame */
                     unsigned long pfn = addr >> TARGET_PAGE_BITS;
@@ -532,6 +535,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                             |= 1UL << pfn % HOST_LONG_BITS;
                     }
                 }
+#endif
 #ifdef __ia64__
                 sync_icache(ptr, l);
 #endif 
@@ -567,6 +571,13 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
         addr += l;
     }
 
+#ifdef CONFIG_STUBDOM
+    if (logdirty_bitmap != NULL)
+        xc_hvm_modified_memory(xc_handle, domid, _addr >> TARGET_PAGE_BITS,
+                (_addr + _len + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS
+                    - _addr >> TARGET_PAGE_BITS);
+#endif
+
     mapcache_unlock();
 }
 #endif
index 8c5d934c271a7833f328930b43f723f35f3af3bd..aa00078561dfc75815b675a9c42d65b9249adc00 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -418,7 +418,7 @@ static void do_change_block(const char *device, const char *filename)
     }
     if (eject_device(bs, 0) < 0)
         return;
-    bdrv_open(bs, filename, 0);
+    bdrv_open2(bs, filename, 0, &bdrv_raw);
     qemu_key_check(bs, filename);
 }
 
diff --git a/vl.c b/vl.c
index 65758ecec94ad913c60d9338b592f9919823d961..df0bfe425f856c7850a57de84172c82c9dbb4620 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -158,6 +158,9 @@ int inet_aton(const char *cp, struct in_addr *ia);
 /* XXX: use a two level table to limit memory usage */
 #define MAX_IOPORTS 65536
 
+/* Max number of PCI emulation */
+#define MAX_PCI_EMULATION 32
+
 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
 const char *bios_name = NULL;
 void *ioport_opaque[MAX_IOPORTS];
@@ -202,6 +205,9 @@ int opengl_enabled = 1;
 int opengl_enabled = 0;
 #endif
 static const char *direct_pci;
+static int nb_pci_emulation = 0;
+static char pci_emulation_config_text[MAX_PCI_EMULATION][256];
+PCI_EMULATION_INFO *PciEmulationInfoHead = NULL;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 #ifdef TARGET_I386
@@ -4733,6 +4739,17 @@ static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
     if (parse_host_port(&saddr, host_str) < 0)
         return -1;
 
+static int pci_emulation_add(char *config_text)
+{
+    PCI_EMULATION_INFO *new;
+    if ((new = qemu_mallocz(sizeof(PCI_EMULATION_INFO))) == NULL) {
+        return -1;
+    }
+    parse_pci_emulation_info(config_text, new);
+    new->next = PciEmulationInfoHead;
+    PciEmulationInfoHead = new;
+    return 0;
+}
 
     fd = net_socket_mcast_create(&saddr);
     if (fd < 0)
@@ -5408,7 +5425,9 @@ static int usb_device_add(const char *devname)
     } else if (!strcmp(devname, "keyboard")) {
         dev = usb_keyboard_init();
     } else if (strstart(devname, "disk:", &p)) {
-        dev = usb_msd_init(p);
+        dev = usb_msd_init(p, &bdrv_raw);
+    } else if (strstart(devname, "disk-qcow:", &p)) {
+        dev = usb_msd_init(p, 0);
     } else if (!strcmp(devname, "wacom-tablet")) {
         dev = usb_wacom_init();
     } else if (strstart(devname, "serial:", &p)) {
@@ -7254,6 +7273,7 @@ static void help(int exitcode)
            "-disable-opengl disable OpenGL rendering, using SDL"
 #endif
           "-direct-pci s   specify pci passthrough, with configuration string s\n"
+           "-pciemulation       name:vendorid:deviceid:command:status:revision:classcode:headertype:subvendorid:subsystemid:interruputline:interruputpin\n"
            "-vcpus          set CPU number of guest platform\n"
 #ifdef TARGET_I386
            "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
@@ -7451,6 +7471,7 @@ enum {
     QEMU_OPTION_domid,
     QEMU_OPTION_disable_opengl,
     QEMU_OPTION_direct_pci,
+    QEMU_OPTION_pci_emulation,
     QEMU_OPTION_vcpus,
     QEMU_OPTION_acpi,
     QEMU_OPTION_pidfile,
@@ -7564,6 +7585,7 @@ const QEMUOption qemu_options[] = {
     { "vcpus", 1, QEMU_OPTION_vcpus },
     { "acpi", 0, QEMU_OPTION_acpi }, /* deprecated, for xend compatibility */
     { "direct_pci", HAS_ARG, QEMU_OPTION_direct_pci },
+    { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
     { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
     { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
@@ -8182,6 +8204,16 @@ int main(int argc, char **argv)
                 }
                 ram_size = value;
                 break;
+            case QEMU_OPTION_pci_emulation:
+                if (nb_pci_emulation >= MAX_PCI_EMULATION) {
+                    fprintf(stderr, "Too many PCI emulations\n");
+                    exit(1);
+                }
+                pstrcpy(pci_emulation_config_text[nb_pci_emulation],
+                        sizeof(pci_emulation_config_text[0]),
+                        optarg);
+                nb_pci_emulation++;
+                break;
             }
             case QEMU_OPTION_domid:
                 domid = atoi(optarg);
@@ -8748,6 +8780,13 @@ int main(int argc, char **argv)
         }
     }
 
+    for (i = 0; i < nb_pci_emulation; i++) {
+        if(pci_emulation_add(pci_emulation_config_text[i]) < 0) {
+            fprintf(stderr, "Warning: could not add PCI device %s\n",
+                    pci_emulation_config_text[i]);
+        }
+    }
+
     machine->init(ram_size, vga_ram_size, boot_devices, ds,
                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model,
                  direct_pci);
index ec3a1df7265345ec76dde9fb48d877c8bef5196a..efa7fb9b86b59b3254a8d0f16e8337fb815bebf7 100644 (file)
@@ -31,6 +31,12 @@ OBJS += xen_console.o
 OBJS += xen_machine_fv.o
 OBJS += xen_blktap.o
 OBJS += exec-dm.o
+OBJS += pci_emulation.o
+
+ifdef CONFIG_STUBDOM
+CONFIG_PASSTHROUGH=1
+OBJS += xenfbfront.o
+endif
 
 ifdef CONFIG_PASSTHROUGH
 OBJS+= pass-through.o
diff --git a/xenfbfront.c b/xenfbfront.c
new file mode 100644 (file)
index 0000000..16691fd
--- /dev/null
@@ -0,0 +1,314 @@
+#include <stdint.h>
+#include <xen/io/fbif.h>
+#include <xen/io/kbdif.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <fbfront.h>
+
+#include <hw/xenfb.h>
+
+#include "vl.h"
+
+typedef struct XenFBState {
+    struct semaphore kbd_sem;
+    struct kbdfront_dev *kbd_dev;
+    struct fbfront_dev *fb_dev;
+    void *vga_vram, *nonshared_vram;
+    DisplayState *ds;
+} XenFBState;
+
+XenFBState *xs;
+
+static char *kbd_path, *fb_path;
+
+static unsigned char linux2scancode[KEY_MAX + 1];
+
+int xenfb_connect_vkbd(const char *path)
+{
+    kbd_path = strdup(path);
+    return 0;
+}
+
+int xenfb_connect_vfb(const char *path)
+{
+    fb_path = strdup(path);
+    return 0;
+}
+
+static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
+{
+    XenFBState *xs = ds->opaque;
+    struct fbfront_dev *fb_dev = xs->fb_dev;
+    if (!fb_dev)
+        return;
+    fbfront_update(fb_dev, x, y, w, h);
+}
+
+static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
+{
+    XenFBState *xs = ds->opaque;
+    struct fbfront_dev *fb_dev = xs->fb_dev;
+    int offset;
+
+    fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize);
+    ds->width = w;
+    ds->height = h;
+    if (!depth) {
+        ds->shared_buf = 0;
+        ds->depth = 32;
+    } else {
+        ds->shared_buf = 1;
+        ds->depth = depth;
+    }
+    if (!linesize)
+        ds->shared_buf = 0;
+    if (!ds->shared_buf)
+        linesize = w * 4;
+    ds->linesize = linesize;
+    if (!fb_dev)
+        return;
+    if (ds->shared_buf) {
+        offset = pixels - xs->vga_vram;
+        ds->data = pixels;
+    } else {
+        ds->data = xs->nonshared_vram;
+        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
+    }
+}
+
+static void xenfb_pv_resize(DisplayState *ds, int w, int h)
+{
+    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
+}
+
+static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
+{
+    XenFBState *xs = ds->opaque;
+    struct fbfront_dev *fb_dev = xs->fb_dev;
+    int offset = pixels - xs->vga_vram;
+    ds->data = pixels;
+    if (!fb_dev)
+        return;
+    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
+}
+
+static void xenfb_pv_refresh(DisplayState *ds)
+{
+    vga_hw_update();
+}
+
+static void xenfb_fb_handler(void *opaque)
+{
+#define FB_NUM_BATCH 4
+    union xenfb_in_event buf[FB_NUM_BATCH];
+    int n, i;
+    XenFBState *xs = opaque;
+    DisplayState *ds = xs->ds;
+
+    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
+    for (i = 0; i < n; i++) {
+        switch (buf[i].type) {
+        case XENFB_TYPE_REFRESH_PERIOD:
+            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
+                /* Sleeping interval */
+                ds->idle = 1;
+                ds->gui_timer_interval = 500;
+            } else {
+                /* Set interval */
+                ds->idle = 0;
+                ds->gui_timer_interval = buf[i].refresh_period.period;
+            }
+        default:
+            /* ignore unknown events */
+            break;
+        }
+    }
+}
+
+static void xenfb_kbd_handler(void *opaque)
+{
+#define KBD_NUM_BATCH 64
+    union xenkbd_in_event buf[KBD_NUM_BATCH];
+    int n, i;
+    XenFBState *xs = opaque;
+    DisplayState *s = xs->ds;
+    static int buttons;
+    static int x, y;
+
+    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
+    for (i = 0; i < n; i++) {
+        switch (buf[i].type) {
+
+            case XENKBD_TYPE_MOTION:
+                fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
+                break;
+
+            case XENKBD_TYPE_POS:
+            {
+                int new_x = buf[i].pos.abs_x;
+                int new_y = buf[i].pos.abs_y;
+                if (new_x >= s->width)
+                    new_x = s->width - 1;
+                if (new_y >= s->height)
+                    new_y = s->height - 1;
+                if (kbd_mouse_is_absolute()) {
+                    kbd_mouse_event(
+                            new_x * 0x7FFF / (s->width - 1),
+                            new_y * 0x7FFF / (s->height - 1),
+                            buf[i].pos.rel_z,
+                            buttons);
+                } else {
+                    kbd_mouse_event(
+                            new_x - x,
+                            new_y - y,
+                            buf[i].pos.rel_z,
+                            buttons);
+                }
+                x = new_x;
+                y = new_y;
+                break;
+            }
+
+            case XENKBD_TYPE_KEY:
+            {
+                int keycode = buf[i].key.keycode;
+                int button = 0;
+
+                if (keycode == BTN_LEFT)
+                    button = MOUSE_EVENT_LBUTTON;
+                else if (keycode == BTN_RIGHT)
+                    button = MOUSE_EVENT_RBUTTON;
+                else if (keycode == BTN_MIDDLE)
+                    button = MOUSE_EVENT_MBUTTON;
+
+                if (button) {
+                    if (buf[i].key.pressed)
+                        buttons |=  button;
+                    else
+                        buttons &= ~button;
+                    if (kbd_mouse_is_absolute())
+                        kbd_mouse_event(
+                                x * 0x7FFF / (s->width - 1),
+                                y * 0x7FFF / (s->height - 1),
+                                0,
+                                buttons);
+                    else
+                        kbd_mouse_event(0, 0, 0, buttons);
+                } else {
+                    int scancode = linux2scancode[keycode];
+                    if (!scancode) {
+                        fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
+                        break;
+                    }
+                    if (scancode & 0x80) {
+                        kbd_put_keycode(0xe0);
+                        scancode &= 0x7f;
+                    }
+                    if (!buf[i].key.pressed)
+                        scancode |= 0x80;
+                    kbd_put_keycode(scancode);
+                }
+                break;
+            }
+        }
+    }
+}
+
+static void kbdfront_thread(void *p)
+{
+    int scancode, keycode;
+    XenFBState *xs = p;
+    xs->kbd_dev = init_kbdfront(kbd_path, 1);
+    if (!xs->kbd_dev) {
+        fprintf(stderr,"can't open keyboard\n");
+        exit(1);
+    }
+    up(&xs->kbd_sem);
+    for (scancode = 0; scancode < 128; scancode++) {
+        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
+        linux2scancode[keycode] = scancode;
+        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
+        linux2scancode[keycode] = scancode | 0x80;
+    }
+}
+
+int xenfb_pv_display_init(DisplayState *ds)
+{
+    if (!fb_path || !kbd_path)
+        return -1;
+
+    xs = qemu_mallocz(sizeof(XenFBState));
+    if (!xs)
+        return -1;
+
+    init_SEMAPHORE(&xs->kbd_sem, 0);
+    xs->ds = ds;
+
+    create_thread("kbdfront", kbdfront_thread, (void*) xs);
+
+    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
+    memset(ds->data, 0, VGA_RAM_SIZE);
+    ds->opaque = xs;
+    ds->depth = 32;
+    ds->bgr = 0;
+    ds->width = 640;
+    ds->height = 400;
+    ds->linesize = 640 * 4;
+    ds->dpy_update = xenfb_pv_update;
+    ds->dpy_resize = xenfb_pv_resize;
+    ds->dpy_resize_shared = xenfb_pv_resize_shared;
+    ds->dpy_setdata = xenfb_pv_setdata;
+    ds->dpy_refresh = xenfb_pv_refresh;
+    return 0;
+}
+
+int xenfb_pv_display_start(void *data)
+{
+    DisplayState *ds;
+    struct fbfront_dev *fb_dev;
+    int kbd_fd, fb_fd;
+    int offset = 0;
+    unsigned long *mfns;
+    int n = VGA_RAM_SIZE / PAGE_SIZE;
+    int i;
+
+    if (!fb_path || !kbd_path)
+        return 0;
+
+    ds = xs->ds;
+    xs->vga_vram = data;
+    mfns = malloc(2 * n * sizeof(*mfns));
+    for (i = 0; i < n; i++)
+        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
+    for (i = 0; i < n; i++)
+        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
+
+    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n);
+    free(mfns);
+    if (!fb_dev) {
+        fprintf(stderr,"can't open frame buffer\n");
+        exit(1);
+    }
+    free(fb_path);
+
+    if (ds->shared_buf) {
+        offset = (void*) ds->data - xs->vga_vram;
+    } else {
+        offset = VGA_RAM_SIZE;
+        ds->data = xs->nonshared_vram;
+    }
+    if (offset)
+        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
+
+    down(&xs->kbd_sem);
+    free(kbd_path);
+
+    kbd_fd = kbdfront_open(xs->kbd_dev);
+    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
+
+    fb_fd = fbfront_open(fb_dev);
+    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
+
+    xs->fb_dev = fb_dev;
+    return 0;
+}
index 5f75073850b8c29ceb90b2fbf09bb64d3b4c98fa..0ba45a57d39a8aa7cd6df595876367f17d44362e 100644 (file)
@@ -333,7 +333,7 @@ void xenstore_parse_domain_config(int hvm_domid)
 
     /* get the pci pass-through parameter */
     if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/num_devs",
-                  domid, pci_devid) == -1)
+                  hvm_domid, pci_devid) == -1)
         goto out;
 
     free(params);
@@ -344,7 +344,7 @@ void xenstore_parse_domain_config(int hvm_domid)
 
     for ( i = 0; i < num; i++ ) {
         if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/dev-%d",
-                    domid, pci_devid, i) != -1) {
+                    hvm_domid, pci_devid, i) != -1) {
             free(dev);
             dev = xs_read(xsh, XBT_NULL, buf, &len);