]> git.proxmox.com Git - qemu.git/commitdiff
Merge remote-tracking branch 'luiz/queue/qmp' into staging
authorAnthony Liguori <aliguori@us.ibm.com>
Mon, 22 Apr 2013 13:04:21 +0000 (08:04 -0500)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 22 Apr 2013 13:04:21 +0000 (08:04 -0500)
# By Amos Kong (1) and Luiz Capitulino (1)
# Via Luiz Capitulino
* luiz/queue/qmp:
  virtio-balloon: fix integer overflow in BALLOON_CHANGE QMP event
  monitor: fix the wrong order of releasing keys

Message-id: 1366375833-995-1-git-send-email-lcapitulino@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
53 files changed:
block/ssh.c
cpus.c
default-configs/pci.mak
docs/specs/pci-testdev.txt [new file with mode: 0644]
hw/arm/armv7m.c
hw/arm/boot.c
hw/arm/musicpal.c
hw/arm/nseries.c
hw/arm/omap1.c
hw/arm/realview.c
hw/arm/versatilepb.c
hw/audio/marvell_88w8618.c
hw/block/fdc.c
hw/block/m25p80.c
hw/core/Makefile.objs
hw/core/qdev-addr.c [deleted file]
hw/display/pxa2xx_lcd.c
hw/display/sm501.c
hw/display/tcx.c
hw/dma/pxa2xx_dma.c
hw/dma/xilinx_axidma.c
hw/gpio/zaurus.c
hw/lm32/milkymist-hw.h
hw/microblaze/boot.c
hw/misc/Makefile.objs
hw/misc/macio/mac_dbdma.c
hw/misc/milkymist-pfpu.c
hw/misc/pci-testdev.c [new file with mode: 0644]
hw/net/mcf_fec.c
hw/net/milkymist-minimac2.c
hw/pci-host/versatile.c
hw/ppc/ppc405_boards.c
hw/ppc/virtex_ml507.c
hw/sparc/sun4m.c
include/hw/pci/pci.h
include/hw/qdev-addr.h [deleted file]
include/hw/virtio/virtio.h
include/qemu/bswap.h
include/sysemu/kvm.h
kvm-all.c
kvm-stub.c
linux-user/syscall.c
scripts/kvm/vmxcap
target-arm/cpu-qom.h
target-arm/cpu.c
target-arm/cpu.h
target-arm/machine.c
target-arm/translate.c
target-i386/cpu.h
target-i386/kvm.c
target-i386/machine.c
target-i386/translate.c
ui/cocoa.m

index 8f78e2e4b9cf868f428a57d91556275dbaf28c45..93a8b53ffd34b9e5c7fbb1097870e502fa94ea35 100644 (file)
@@ -109,7 +109,7 @@ static void ssh_state_free(BDRVSSHState *s)
 /* Wrappers around error_report which make sure to dump as much
  * information from libssh2 as possible.
  */
-static void
+static void GCC_FMT_ATTR(2, 3)
 session_error_report(BDRVSSHState *s, const char *fs, ...)
 {
     va_list args;
@@ -132,7 +132,7 @@ session_error_report(BDRVSSHState *s, const char *fs, ...)
     error_printf("\n");
 }
 
-static void
+static void GCC_FMT_ATTR(2, 3)
 sftp_error_report(BDRVSSHState *s, const char *fs, ...)
 {
     va_list args;
@@ -387,15 +387,13 @@ static int check_host_key(BDRVSSHState *s, const char *host, int port,
     }
 
     /* host_key_check=md5:xx:yy:zz:... */
-    if (strlen(host_key_check) >= 4 &&
-        strncmp(host_key_check, "md5:", 4) == 0) {
+    if (strncmp(host_key_check, "md5:", 4) == 0) {
         return check_host_key_hash(s, &host_key_check[4],
                                    LIBSSH2_HOSTKEY_HASH_MD5, 16);
     }
 
     /* host_key_check=sha1:xx:yy:zz:... */
-    if (strlen(host_key_check) >= 5 &&
-        strncmp(host_key_check, "sha1:", 5) == 0) {
+    if (strncmp(host_key_check, "sha1:", 5) == 0) {
         return check_host_key_hash(s, &host_key_check[5],
                                    LIBSSH2_HOSTKEY_HASH_SHA1, 20);
     }
diff --git a/cpus.c b/cpus.c
index c15ff6c5fee824c3c7a28664dfce2820d7915fef..5a98a370df92bebb3f634d00af3c78a42fc3c7c2 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -865,7 +865,7 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
         CONTEXT tcgContext;
 
         if (SuspendThread(cpu->hThread) == (DWORD)-1) {
-            fprintf(stderr, "qemu:%s: GetLastError:%d\n", __func__,
+            fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__,
                     GetLastError());
             exit(1);
         }
@@ -881,7 +881,7 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
         cpu_signal(0);
 
         if (ResumeThread(cpu->hThread) == (DWORD)-1) {
-            fprintf(stderr, "qemu:%s: GetLastError:%d\n", __func__,
+            fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__,
                     GetLastError());
             exit(1);
         }
index f5f100ecb0d5361ef11c6a9aea5cd666aa8dcdff..b608f31c9a9d1d9c4f15f0a72b66db295817f934 100644 (file)
@@ -24,3 +24,4 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_PCI=y
 CONFIG_IPACK=y
 CONFIG_WDT_IB6300ESB=y
+CONFIG_PCI_TESTDEV=y
diff --git a/docs/specs/pci-testdev.txt b/docs/specs/pci-testdev.txt
new file mode 100644 (file)
index 0000000..128ae22
--- /dev/null
@@ -0,0 +1,26 @@
+pci-test is a device used for testing low level IO
+
+device implements up to two BARs: BAR0 and BAR1.
+Each BAR can be memory or IO. Guests must detect
+BAR type and act accordingly.
+
+Each BAR size is up to 4K bytes.
+Each BAR starts with the following header:
+
+typedef struct PCITestDevHdr {
+    uint8_t test;  <- write-only, starts a given test number
+    uint8_t width_type; <- read-only, type and width of access for a given test.
+                           1,2,4 for byte,word or long write.
+                           any other value if test not supported on this BAR
+    uint8_t pad0[2];
+    uint32_t offset; <- read-only, offset in this BAR for a given test
+    uint32_t data;    <- read-only, data to use for a given test
+    uint32_t count;  <- for debugging. number of writes detected.
+    uint8_t name[]; <- for debugging. 0-terminated ASCII string.
+} PCITestDevHdr;
+
+All registers are little endian.
+
+device is expected to always implement tests 0 to N on each BAR, and to add new
+tests with higher numbers.  In this way a guest can scan test numbers until it
+detects an access type that it does not support on this BAR, then stop.
index 2ae357676007851b2d0ec7a218c346c2d96dc876..93422bc7beedac74531f990bf33374fda618e679 100644 (file)
@@ -56,7 +56,7 @@ static uint32_t bitband_readw(void *opaque, hwaddr offset)
     addr = bitband_addr(opaque, offset) & ~1;
     mask = (1 << ((offset >> 2) & 15));
     mask = tswap16(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
+    cpu_physical_memory_read(addr, &v, 2);
     return (v & mask) != 0;
 }
 
@@ -69,12 +69,12 @@ static void bitband_writew(void *opaque, hwaddr offset,
     addr = bitband_addr(opaque, offset) & ~1;
     mask = (1 << ((offset >> 2) & 15));
     mask = tswap16(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
+    cpu_physical_memory_read(addr, &v, 2);
     if (value & 1)
         v |= mask;
     else
         v &= ~mask;
-    cpu_physical_memory_write(addr, (uint8_t *)&v, 2);
+    cpu_physical_memory_write(addr, &v, 2);
 }
 
 static uint32_t bitband_readl(void *opaque, hwaddr offset)
@@ -85,7 +85,7 @@ static uint32_t bitband_readl(void *opaque, hwaddr offset)
     addr = bitband_addr(opaque, offset) & ~3;
     mask = (1 << ((offset >> 2) & 31));
     mask = tswap32(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
+    cpu_physical_memory_read(addr, &v, 4);
     return (v & mask) != 0;
 }
 
@@ -98,12 +98,12 @@ static void bitband_writel(void *opaque, hwaddr offset,
     addr = bitband_addr(opaque, offset) & ~3;
     mask = (1 << ((offset >> 2) & 31));
     mask = tswap32(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
+    cpu_physical_memory_read(addr, &v, 4);
     if (value & 1)
         v |= mask;
     else
         v &= ~mask;
-    cpu_physical_memory_write(addr, (uint8_t *)&v, 4);
+    cpu_physical_memory_write(addr, &v, 4);
 }
 
 static const MemoryRegionOps bitband_ops = {
index e9c09454ac55fffa92e72d5457bfe9a3dfb67f18..f451529fced1e84d9faca15035978a53d2cc4861 100644 (file)
@@ -128,7 +128,7 @@ static void set_kernel_args(const struct arm_boot_info *info)
         int cmdline_size;
 
         cmdline_size = strlen(info->kernel_cmdline);
-        cpu_physical_memory_write(p + 8, (void *)info->kernel_cmdline,
+        cpu_physical_memory_write(p + 8, info->kernel_cmdline,
                                   cmdline_size + 1);
         cmdline_size = (cmdline_size >> 2) + 1;
         WRITE_WORD(p, cmdline_size + 2);
@@ -219,7 +219,7 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
     }
     s = info->kernel_cmdline;
     if (s) {
-        cpu_physical_memory_write(p, (void *)s, strlen(s) + 1);
+        cpu_physical_memory_write(p, s, strlen(s) + 1);
     } else {
         WRITE_WORD(p, 0);
     }
index 31586c652ef4852d4420e61b7c8b522adfd3f60f..f33ba9a03951f903477ef29599f1390efd7702f2 100644 (file)
@@ -170,12 +170,12 @@ static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc)
     cpu_to_le16s(&desc->buffer_size);
     cpu_to_le32s(&desc->buffer);
     cpu_to_le32s(&desc->next);
-    cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_write(addr, desc, sizeof(*desc));
 }
 
 static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
 {
-    cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_read(addr, desc, sizeof(*desc));
     le32_to_cpus(&desc->cmdstat);
     le16_to_cpus(&desc->bytes);
     le16_to_cpus(&desc->buffer_size);
@@ -229,12 +229,12 @@ static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
     cpu_to_le16s(&desc->bytes);
     cpu_to_le32s(&desc->buffer);
     cpu_to_le32s(&desc->next);
-    cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_write(addr, desc, sizeof(*desc));
 }
 
 static void eth_tx_desc_get(uint32_t addr, mv88w8618_tx_desc *desc)
 {
-    cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_read(addr, desc, sizeof(*desc));
     le32_to_cpus(&desc->cmdstat);
     le16_to_cpus(&desc->res);
     le16_to_cpus(&desc->bytes);
index 4976438ae6187ee86aae02ef7818cdea49791490..f6c9dc09ef6a5217730d32cd075bdbf117b76a12 100644 (file)
@@ -970,7 +970,7 @@ static void n800_gpmc_init(struct n800_s *s)
             (4 << 0);          /* BASEADDRESS */
 
     cpu_physical_memory_write(0x6800a078,              /* GPMC_CONFIG7_0 */
-                    (void *) &config7, sizeof(config7));
+                              &config7, sizeof(config7));
 }
 
 /* Setup sequence done by the bootloader */
@@ -982,7 +982,7 @@ static void n8x0_boot_init(void *opaque)
     /* PRCM setup */
 #define omap_writel(addr, val) \
     buf = (val);                       \
-    cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf))
+    cpu_physical_memory_write(addr, &buf, sizeof(buf))
 
     omap_writel(0x48008060, 0x41);             /* PRCM_CLKSRC_CTRL */
     omap_writel(0x48008070, 1);                        /* PRCM_CLKOUT_CTRL */
index f59f0f291a2d7d856d7c8c8116864225cda4d467..c06c642acc982fa9e7538098896ebce717a67fb1 100644 (file)
@@ -31,7 +31,7 @@ uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
     uint8_t ret;
 
     OMAP_8B_REG(addr);
-    cpu_physical_memory_read(addr, (void *) &ret, 1);
+    cpu_physical_memory_read(addr, &ret, 1);
     return ret;
 }
 
@@ -41,7 +41,7 @@ void omap_badwidth_write8(void *opaque, hwaddr addr,
     uint8_t val8 = value;
 
     OMAP_8B_REG(addr);
-    cpu_physical_memory_write(addr, (void *) &val8, 1);
+    cpu_physical_memory_write(addr, &val8, 1);
 }
 
 uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
@@ -49,7 +49,7 @@ uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
     uint16_t ret;
 
     OMAP_16B_REG(addr);
-    cpu_physical_memory_read(addr, (void *) &ret, 2);
+    cpu_physical_memory_read(addr, &ret, 2);
     return ret;
 }
 
@@ -59,7 +59,7 @@ void omap_badwidth_write16(void *opaque, hwaddr addr,
     uint16_t val16 = value;
 
     OMAP_16B_REG(addr);
-    cpu_physical_memory_write(addr, (void *) &val16, 2);
+    cpu_physical_memory_write(addr, &val16, 2);
 }
 
 uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
@@ -67,7 +67,7 @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
     uint32_t ret;
 
     OMAP_32B_REG(addr);
-    cpu_physical_memory_read(addr, (void *) &ret, 4);
+    cpu_physical_memory_read(addr, &ret, 4);
     return ret;
 }
 
@@ -75,7 +75,7 @@ void omap_badwidth_write32(void *opaque, hwaddr addr,
                 uint32_t value)
 {
     OMAP_32B_REG(addr);
-    cpu_physical_memory_write(addr, (void *) &value, 4);
+    cpu_physical_memory_write(addr, &value, 4);
 }
 
 /* MPU OS timers */
index feabfc58d4afe7c8e74d099315beabfa150359bc..d6f47bf4d4e1eacce124785ecc51ae4ad58a94e0 100644 (file)
@@ -217,9 +217,13 @@ static void realview_init(QEMUMachineInitArgs *args,
         dev = qdev_create(NULL, "realview_pci");
         busdev = SYS_BUS_DEVICE(dev);
         qdev_init_nofail(dev);
-        sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */
-        sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */
-        sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */
+        sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */
+        sysbus_mmio_map(busdev, 1, 0x60000000); /* PCI self-config */
+        sysbus_mmio_map(busdev, 2, 0x61000000); /* PCI config */
+        sysbus_mmio_map(busdev, 3, 0x62000000); /* PCI I/O */
+        sysbus_mmio_map(busdev, 4, 0x63000000); /* PCI memory window 1 */
+        sysbus_mmio_map(busdev, 5, 0x64000000); /* PCI memory window 2 */
+        sysbus_mmio_map(busdev, 6, 0x68000000); /* PCI memory window 3 */
         sysbus_connect_irq(busdev, 0, pic[48]);
         sysbus_connect_irq(busdev, 1, pic[49]);
         sysbus_connect_irq(busdev, 2, pic[50]);
@@ -303,12 +307,12 @@ static void realview_init(QEMUMachineInitArgs *args,
     /*  0x58000000 PISMO.  */
     /*  0x5c000000 PISMO.  */
     /* 0x60000000 PCI.  */
-    /* 0x61000000 PCI Self Config.  */
-    /* 0x62000000 PCI Config.  */
-    /* 0x63000000 PCI IO.  */
-    /* 0x64000000 PCI mem 0.  */
-    /* 0x68000000 PCI mem 1.  */
-    /* 0x6c000000 PCI mem 2.  */
+    /* 0x60000000 PCI Self Config.  */
+    /* 0x61000000 PCI Config.  */
+    /* 0x62000000 PCI IO.  */
+    /* 0x63000000 PCI mem 0.  */
+    /* 0x64000000 PCI mem 1.  */
+    /* 0x68000000 PCI mem 2.  */
 
     /* ??? Hack to map an additional page of ram for the secondary CPU
        startup code.  I guess this works on real hardware because the
index 25c665ab273cb27bd204ed04f1d48e4d002fe66a..753757ea19236a763aee7a9b3bb7e3a77f7fca29 100644 (file)
@@ -224,16 +224,19 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
     dev = qdev_create(NULL, "versatile_pci");
     busdev = SYS_BUS_DEVICE(dev);
     qdev_init_nofail(dev);
-    sysbus_mmio_map(busdev, 0, 0x41000000); /* PCI self-config */
-    sysbus_mmio_map(busdev, 1, 0x42000000); /* PCI config */
+    sysbus_mmio_map(busdev, 0, 0x10001000); /* PCI controller regs */
+    sysbus_mmio_map(busdev, 1, 0x41000000); /* PCI self-config */
+    sysbus_mmio_map(busdev, 2, 0x42000000); /* PCI config */
+    sysbus_mmio_map(busdev, 3, 0x43000000); /* PCI I/O */
+    sysbus_mmio_map(busdev, 4, 0x44000000); /* PCI memory window 1 */
+    sysbus_mmio_map(busdev, 5, 0x50000000); /* PCI memory window 2 */
+    sysbus_mmio_map(busdev, 6, 0x60000000); /* PCI memory window 3 */
     sysbus_connect_irq(busdev, 0, sic[27]);
     sysbus_connect_irq(busdev, 1, sic[28]);
     sysbus_connect_irq(busdev, 2, sic[29]);
     sysbus_connect_irq(busdev, 3, sic[30]);
     pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
 
-    /* The Versatile PCI bridge does not provide access to PCI IO space,
-       so many of the qemu PCI devices are not useable.  */
     for(n = 0; n < nb_nics; n++) {
         nd = &nd_table[n];
 
index f9b68fd3112259ddcbda47a6211277778ac0d8a3..de06dfd7d2e397bc46840ed897121433767f4426 100644 (file)
@@ -77,8 +77,7 @@ static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in)
     if (block_size > 4096) {
         return;
     }
-    cpu_physical_memory_read(s->target_buffer + s->play_pos, (void *)buf,
-                             block_size);
+    cpu_physical_memory_read(s->target_buffer + s->play_pos, buf, block_size);
     mem_buffer = buf;
     if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
         if (s->playback_mode & MP_AUDIO_MONO) {
index 1ed874f074120bda3431a859d767fafe4460bf8c..f1f1fd7f3b4972815beee287859038e462f56e08 100644 (file)
@@ -33,7 +33,6 @@
 #include "qemu/timer.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
-#include "hw/qdev-addr.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
 #include "qemu/log.h"
index efcc7f4c839b8b45bc73a578fc43369220a925cc..b3ca19ae520268ef22b572b9566f64c46bd4d3fa 100644 (file)
@@ -24,7 +24,6 @@
 #include "hw/hw.h"
 #include "sysemu/blockdev.h"
 #include "hw/ssi.h"
-#include "hw/devices.h"
 
 #ifndef M25P80_ERR_DEBUG
 #define M25P80_ERR_DEBUG 0
index 94109f32e220199daa6340941e3504c24f7d0a67..950146c6ffc55383fa92715d487df97990bbdb03 100644 (file)
@@ -9,6 +9,5 @@ common-obj-$(CONFIG_PTIMER) += ptimer.o
 common-obj-$(CONFIG_SOFTMMU) += sysbus.o
 common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
-common-obj-$(CONFIG_SOFTMMU) += qdev-addr.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 
diff --git a/hw/core/qdev-addr.c b/hw/core/qdev-addr.c
deleted file mode 100644 (file)
index 80a38bb..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "hw/qdev.h"
-#include "hw/qdev-addr.h"
-#include "exec/hwaddr.h"
-#include "qapi/qmp/qerror.h"
-#include "qapi/visitor.h"
-
-/* --- target physical address --- */
-
-static int parse_taddr(DeviceState *dev, Property *prop, const char *str)
-{
-    hwaddr *ptr = qdev_get_prop_ptr(dev, prop);
-
-    *ptr = strtoull(str, NULL, 16);
-    return 0;
-}
-
-static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    hwaddr *ptr = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr);
-}
-
-static void get_taddr(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    hwaddr *ptr = qdev_get_prop_ptr(dev, prop);
-    int64_t value;
-
-    value = *ptr;
-    visit_type_int64(v, &value, name, errp);
-}
-
-static void set_taddr(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    hwaddr *ptr = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    int64_t value;
-
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
-    visit_type_int64(v, &value, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if ((uint64_t)value <= (uint64_t) ~(hwaddr)0) {
-        *ptr = value;
-    } else {
-        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
-                  dev->id?:"", name, value, (uint64_t) 0,
-                  (uint64_t) ~(hwaddr)0);
-    }
-}
-
-
-PropertyInfo qdev_prop_taddr = {
-    .name  = "taddr",
-    .parse = parse_taddr,
-    .print = print_taddr,
-    .get   = get_taddr,
-    .set   = set_taddr,
-};
-
-void qdev_prop_set_taddr(DeviceState *dev, const char *name, hwaddr value)
-{
-    Error *errp = NULL;
-    object_property_set_int(OBJECT(dev), value, name, &errp);
-    assert(!errp);
-
-}
index 12d9cd28087fed403d33fd70e27efbbfb5579e4d..76276cf7f118c3a21da64553328c6fce8fecd338 100644 (file)
@@ -315,7 +315,7 @@ static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
             continue;
         }
 
-        cpu_physical_memory_read(descptr, (void *)&desc, sizeof(desc));
+        cpu_physical_memory_read(descptr, &desc, sizeof(desc));
         s->dma_ch[i].descriptor = tswap32(desc.fdaddr);
         s->dma_ch[i].source = tswap32(desc.fsaddr);
         s->dma_ch[i].id = tswap32(desc.fidr);
index f0e6d7022fd6ead8bb0c14f193b3221279d3818d..916816fc24520a1d20d9da1026b7738bca189cc8 100644 (file)
@@ -28,7 +28,6 @@
 #include "ui/console.h"
 #include "hw/devices.h"
 #include "hw/sysbus.h"
-#include "hw/qdev-addr.h"
 #include "qemu/range.h"
 #include "ui/pixel_ops.h"
 
@@ -1434,7 +1433,7 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
     /* bridge to usb host emulation module */
     dev = qdev_create(NULL, "sysbus-ohci");
     qdev_prop_set_uint32(dev, "num-ports", 2);
-    qdev_prop_set_taddr(dev, "dma-offset", base);
+    qdev_prop_set_uint64(dev, "dma-offset", base);
     qdev_init_nofail(dev);
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0,
                     base + MMIO_BASE_OFFSET + SM501_USB_HOST);
index 77c7191c764afdcce0205d247b01569098a96102..d7465c63f17bd5ce0de17734e090455881050f24 100644 (file)
@@ -26,7 +26,6 @@
 #include "ui/console.h"
 #include "ui/pixel_ops.h"
 #include "hw/sysbus.h"
-#include "hw/qdev-addr.h"
 
 #define MAXX 1024
 #define MAXY 768
index 6e4c1f6d62303f8371a4085c234bccdab1d7589c..b60569fd88c720492f82b9ffa734a3316a2cca53 100644 (file)
@@ -151,7 +151,7 @@ static inline void pxa2xx_dma_descriptor_fetch(
     if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST))
         daddr += 32;
 
-    cpu_physical_memory_read(daddr, (uint8_t *) desc, 16);
+    cpu_physical_memory_read(daddr, desc, 16);
     s->chan[ch].descr = desc[DDADR];
     s->chan[ch].src = desc[DSADR];
     s->chan[ch].dest = desc[DTADR];
index 1c237622107daf2cdd1d35aef8d32efb77aa502c..3a3ef8aff351595698f3ea2fe9dca0a5b07b587d 100644 (file)
@@ -26,7 +26,6 @@
 #include "qemu/timer.h"
 #include "hw/ptimer.h"
 #include "qemu/log.h"
-#include "hw/qdev-addr.h"
 #include "qapi/qmp/qerror.h"
 
 #include "hw/stream.h"
@@ -197,7 +196,7 @@ static void stream_desc_load(struct Stream *s, hwaddr addr)
 {
     struct SDesc *d = &s->desc;
 
-    cpu_physical_memory_read(addr, (void *) d, sizeof *d);
+    cpu_physical_memory_read(addr, d, sizeof *d);
 
     /* Convert from LE into host endianness.  */
     d->buffer_address = le64_to_cpu(d->buffer_address);
@@ -215,7 +214,7 @@ static void stream_desc_store(struct Stream *s, hwaddr addr)
     d->nxtdesc = cpu_to_le64(d->nxtdesc);
     d->control = cpu_to_le32(d->control);
     d->status = cpu_to_le32(d->status);
-    cpu_physical_memory_write(addr, (void *) d, sizeof *d);
+    cpu_physical_memory_write(addr, d, sizeof *d);
 }
 
 static void stream_update_irq(struct Stream *s)
index d853ea1310a0a13c36fb1b762a3971604a0405e1..c6cdef32122c4e457ec3d4820be64fb46f2c37c8 100644 (file)
@@ -287,6 +287,6 @@ static struct QEMU_PACKED sl_param_info {
 
 void sl_bootparam_write(hwaddr ptr)
 {
-    cpu_physical_memory_write(ptr, (void *)&zaurus_bootparam,
+    cpu_physical_memory_write(ptr, &zaurus_bootparam,
                               sizeof(struct sl_param_info));
 }
index 4e86c4e83231c5fd0e5e562dd58e8f6d6721973e..5317ce6e2d4c6fed187b947fca425613a0607b2c 100644 (file)
@@ -2,7 +2,6 @@
 #define QEMU_HW_MILKYMIST_H
 
 #include "hw/qdev.h"
-#include "hw/qdev-addr.h"
 #include "net/net.h"
 
 static inline DeviceState *milkymist_uart_create(hwaddr base,
index 23cb11d70e69c5a8000997aac7824a1b1c080c42..e543d886b83048ef1767d99dd6140246ee482b93 100644 (file)
@@ -80,7 +80,7 @@ static int microblaze_load_dtb(hwaddr addr,
         }
     }
 
-    cpu_physical_memory_write(addr, (void *)fdt, fdt_size);
+    cpu_physical_memory_write(addr, fdt, fdt_size);
 #else
     /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
        to the kernel.  */
index 03699c3365af0d430d8cc08a552607c169d1e362..11b18a41963d3b5ccbc421698f2ec5ca419e548c 100644 (file)
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_TMP105) += tmp105.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
 common-obj-$(CONFIG_SGA) += sga.o
 common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
+common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
 
 obj-$(CONFIG_VMPORT) += vmport.o
 
index a2363bbdf291a0524c76623f8bc0d3db82565424..2fc7f87bb6fb51cf0404b8031a5429cf57535ce7 100644 (file)
@@ -192,7 +192,7 @@ static void dbdma_cmdptr_load(DBDMA_channel *ch)
     DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
                   ch->regs[DBDMA_CMDPTR_LO]);
     cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO],
-                             (uint8_t*)&ch->current, sizeof(dbdma_cmd));
+                             &ch->current, sizeof(dbdma_cmd));
 }
 
 static void dbdma_cmdptr_save(DBDMA_channel *ch)
@@ -203,7 +203,7 @@ static void dbdma_cmdptr_save(DBDMA_channel *ch)
                   le16_to_cpu(ch->current.xfer_status),
                   le16_to_cpu(ch->current.res_count));
     cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO],
-                              (uint8_t*)&ch->current, sizeof(dbdma_cmd));
+                              &ch->current, sizeof(dbdma_cmd));
 }
 
 static void kill_channel(DBDMA_channel *ch)
@@ -454,7 +454,7 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
         return;
     }
 
-    cpu_physical_memory_read(addr, (uint8_t*)&val, len);
+    cpu_physical_memory_read(addr, &val, len);
 
     if (len == 2)
         val = (val << 16) | (current->cmd_dep & 0x0000ffff);
@@ -499,7 +499,7 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
     else if (len == 1)
         val >>= 24;
 
-    cpu_physical_memory_write(addr, (uint8_t*)&val, len);
+    cpu_physical_memory_write(addr, &val, len);
 
     if (conditional_wait(ch))
         goto wait;
index ad44b4db22f6b964745dd5058c63e0d35fc4a960..fe1b0395504f1a913b1fbeef67d6a8a144860ab8 100644 (file)
@@ -228,8 +228,8 @@ static int pfpu_decode_insn(MilkymistPFPUState *s)
         hwaddr dma_ptr =
             get_dma_address(s->regs[R_MESHBASE],
                     s->gp_regs[GPR_X], s->gp_regs[GPR_Y]);
-        cpu_physical_memory_write(dma_ptr, (uint8_t *)&a, 4);
-        cpu_physical_memory_write(dma_ptr + 4, (uint8_t *)&b, 4);
+        cpu_physical_memory_write(dma_ptr, &a, 4);
+        cpu_physical_memory_write(dma_ptr + 4, &b, 4);
         s->regs[R_LASTDMA] = dma_ptr + 4;
         D_EXEC(qemu_log("VECTOUT a=%08x b=%08x dma=%08x\n", a, b, dma_ptr));
         trace_milkymist_pfpu_vectout(a, b, dma_ptr);
diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c
new file mode 100644 (file)
index 0000000..71ce5a3
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * QEMU PCI test device
+ *
+ * Copyright (c) 2012 Red Hat Inc.
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include "hw/hw.h"
+#include "hw/pci/pci.h"
+#include "qemu/event_notifier.h"
+#include "qemu/osdep.h"
+
+typedef struct PCITestDevHdr {
+    uint8_t test;
+    uint8_t width;
+    uint8_t pad0[2];
+    uint32_t offset;
+    uint8_t data;
+    uint8_t pad1[3];
+    uint32_t count;
+    uint8_t name[];
+} PCITestDevHdr;
+
+typedef struct IOTest {
+    MemoryRegion *mr;
+    EventNotifier notifier;
+    bool hasnotifier;
+    unsigned size;
+    bool match_data;
+    PCITestDevHdr *hdr;
+    unsigned bufsize;
+} IOTest;
+
+#define IOTEST_DATAMATCH 0xFA
+#define IOTEST_NOMATCH   0xCE
+
+#define IOTEST_IOSIZE 128
+#define IOTEST_MEMSIZE 2048
+
+static const char *iotest_test[] = {
+    "no-eventfd",
+    "wildcard-eventfd",
+    "datamatch-eventfd"
+};
+
+static const char *iotest_type[] = {
+    "mmio",
+    "portio"
+};
+
+#define IOTEST_TEST(i) (iotest_test[((i) % ARRAY_SIZE(iotest_test))])
+#define IOTEST_TYPE(i) (iotest_type[((i) / ARRAY_SIZE(iotest_test))])
+#define IOTEST_MAX_TEST (ARRAY_SIZE(iotest_test))
+#define IOTEST_MAX_TYPE (ARRAY_SIZE(iotest_type))
+#define IOTEST_MAX (IOTEST_MAX_TEST * IOTEST_MAX_TYPE)
+
+enum {
+    IOTEST_ACCESS_NAME,
+    IOTEST_ACCESS_DATA,
+    IOTEST_ACCESS_MAX,
+};
+
+#define IOTEST_ACCESS_TYPE uint8_t
+#define IOTEST_ACCESS_WIDTH (sizeof(uint8_t))
+
+typedef struct PCITestDevState {
+    PCIDevice dev;
+    MemoryRegion mmio;
+    MemoryRegion portio;
+    IOTest *tests;
+    int current;
+} PCITestDevState;
+
+#define IOTEST_IS_MEM(i) (strcmp(IOTEST_TYPE(i), "portio"))
+#define IOTEST_REGION(d, i) (IOTEST_IS_MEM(i) ?  &(d)->mmio : &(d)->portio)
+#define IOTEST_SIZE(i) (IOTEST_IS_MEM(i) ? IOTEST_MEMSIZE : IOTEST_IOSIZE)
+#define IOTEST_PCI_BAR(i) (IOTEST_IS_MEM(i) ? PCI_BASE_ADDRESS_SPACE_MEMORY : \
+                           PCI_BASE_ADDRESS_SPACE_IO)
+
+static int pci_testdev_start(IOTest *test)
+{
+    test->hdr->count = 0;
+    if (!test->hasnotifier) {
+        return 0;
+    }
+    event_notifier_test_and_clear(&test->notifier);
+    memory_region_add_eventfd(test->mr,
+                              le32_to_cpu(test->hdr->offset),
+                              test->size,
+                              test->match_data,
+                              test->hdr->data,
+                              &test->notifier);
+    return 0;
+}
+
+static void pci_testdev_stop(IOTest *test)
+{
+    if (!test->hasnotifier) {
+        return;
+    }
+    memory_region_del_eventfd(test->mr,
+                              le32_to_cpu(test->hdr->offset),
+                              test->size,
+                              test->match_data,
+                              test->hdr->data,
+                              &test->notifier);
+}
+
+static void
+pci_testdev_reset(PCITestDevState *d)
+{
+    if (d->current == -1) {
+        return;
+    }
+    pci_testdev_stop(&d->tests[d->current]);
+    d->current = -1;
+}
+
+static void pci_testdev_inc(IOTest *test, unsigned inc)
+{
+    uint32_t c = le32_to_cpu(test->hdr->count);
+    test->hdr->count = cpu_to_le32(c + inc);
+}
+
+static void
+pci_testdev_write(void *opaque, hwaddr addr, uint64_t val,
+                  unsigned size, int type)
+{
+    PCITestDevState *d = opaque;
+    IOTest *test;
+    int t, r;
+
+    if (addr == offsetof(PCITestDevHdr, test)) {
+        pci_testdev_reset(d);
+        if (val >= IOTEST_MAX_TEST) {
+            return;
+        }
+        t = type * IOTEST_MAX_TEST + val;
+        r = pci_testdev_start(&d->tests[t]);
+        if (r < 0) {
+            return;
+        }
+        d->current = t;
+        return;
+    }
+    if (d->current < 0) {
+        return;
+    }
+    test = &d->tests[d->current];
+    if (addr != le32_to_cpu(test->hdr->offset)) {
+        return;
+    }
+    if (test->match_data && test->size != size) {
+        return;
+    }
+    if (test->match_data && val != test->hdr->data) {
+        return;
+    }
+    pci_testdev_inc(test, 1);
+}
+
+static uint64_t
+pci_testdev_read(void *opaque, hwaddr addr, unsigned size)
+{
+    PCITestDevState *d = opaque;
+    const char *buf;
+    IOTest *test;
+    if (d->current < 0) {
+        return 0;
+    }
+    test = &d->tests[d->current];
+    buf = (const char *)test->hdr;
+    if (addr + size >= test->bufsize) {
+        return 0;
+    }
+    if (test->hasnotifier) {
+        event_notifier_test_and_clear(&test->notifier);
+    }
+    return buf[addr];
+}
+
+static void
+pci_testdev_mmio_write(void *opaque, hwaddr addr, uint64_t val,
+                       unsigned size)
+{
+    pci_testdev_write(opaque, addr, val, size, 0);
+}
+
+static void
+pci_testdev_pio_write(void *opaque, hwaddr addr, uint64_t val,
+                       unsigned size)
+{
+    pci_testdev_write(opaque, addr, val, size, 1);
+}
+
+static const MemoryRegionOps pci_testdev_mmio_ops = {
+    .read = pci_testdev_read,
+    .write = pci_testdev_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+static const MemoryRegionOps pci_testdev_pio_ops = {
+    .read = pci_testdev_read,
+    .write = pci_testdev_pio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+static int pci_testdev_init(PCIDevice *pci_dev)
+{
+    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, pci_dev);
+    uint8_t *pci_conf;
+    char *name;
+    int r, i;
+
+    pci_conf = d->dev.config;
+
+    pci_conf[PCI_INTERRUPT_PIN] = 0; /* no interrupt pin */
+
+    memory_region_init_io(&d->mmio, &pci_testdev_mmio_ops, d,
+                          "pci-testdev-mmio", IOTEST_MEMSIZE * 2);
+    memory_region_init_io(&d->portio, &pci_testdev_pio_ops, d,
+                          "pci-testdev-portio", IOTEST_IOSIZE * 2);
+    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
+    pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio);
+
+    d->current = -1;
+    d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests);
+    for (i = 0; i < IOTEST_MAX; ++i) {
+        IOTest *test = &d->tests[i];
+        name = g_strdup_printf("%s-%s", IOTEST_TYPE(i), IOTEST_TEST(i));
+        test->bufsize = sizeof(PCITestDevHdr) + strlen(name) + 1;
+        test->hdr = g_malloc0(test->bufsize);
+        memcpy(test->hdr->name, name, strlen(name) + 1);
+        g_free(name);
+        test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH);
+        test->size = IOTEST_ACCESS_WIDTH;
+        test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd");
+        test->hdr->test = i;
+        test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH;
+        test->hdr->width = IOTEST_ACCESS_WIDTH;
+        test->mr = IOTEST_REGION(d, i);
+        if (!strcmp(IOTEST_TEST(i), "no-eventfd")) {
+            test->hasnotifier = false;
+            continue;
+        }
+        r = event_notifier_init(&test->notifier, 0);
+        assert(r >= 0);
+        test->hasnotifier = true;
+    }
+
+    return 0;
+}
+
+static void
+pci_testdev_uninit(PCIDevice *dev)
+{
+    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, dev);
+    int i;
+
+    pci_testdev_reset(d);
+    for (i = 0; i < IOTEST_MAX; ++i) {
+        if (d->tests[i].hasnotifier) {
+            event_notifier_cleanup(&d->tests[i].notifier);
+        }
+        g_free(d->tests[i].hdr);
+    }
+    g_free(d->tests);
+    memory_region_destroy(&d->mmio);
+    memory_region_destroy(&d->portio);
+}
+
+static void qdev_pci_testdev_reset(DeviceState *dev)
+{
+    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev.qdev, dev);
+    pci_testdev_reset(d);
+}
+
+static void pci_testdev_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_testdev_init;
+    k->exit = pci_testdev_uninit;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT;
+    k->device_id = PCI_DEVICE_ID_REDHAT_TEST;
+    k->revision = 0x00;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->desc = "PCI Test Device";
+    dc->reset = qdev_pci_testdev_reset;
+}
+
+static const TypeInfo pci_testdev_info = {
+    .name          = "pci-testdev",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCITestDevState),
+    .class_init    = pci_testdev_class_init,
+};
+
+static void pci_testdev_register_types(void)
+{
+    type_register_static(&pci_testdev_info);
+}
+
+type_init(pci_testdev_register_types)
index 9b6805267d3dd0e0eca08387a9cb13309ce02a57..2ef5a0d73dcdfeebad703d8df0e26018c069b382 100644 (file)
@@ -108,7 +108,7 @@ typedef struct {
 
 static void mcf_fec_read_bd(mcf_fec_bd *bd, uint32_t addr)
 {
-    cpu_physical_memory_read(addr, (uint8_t *)bd, sizeof(*bd));
+    cpu_physical_memory_read(addr, bd, sizeof(*bd));
     be16_to_cpus(&bd->flags);
     be16_to_cpus(&bd->length);
     be32_to_cpus(&bd->data);
@@ -120,7 +120,7 @@ static void mcf_fec_write_bd(mcf_fec_bd *bd, uint32_t addr)
     tmp.flags = cpu_to_be16(bd->flags);
     tmp.length = cpu_to_be16(bd->length);
     tmp.data = cpu_to_be32(bd->data);
-    cpu_physical_memory_write(addr, (uint8_t *)&tmp, sizeof(tmp));
+    cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
 }
 
 static void mcf_fec_update(mcf_fec_state *s)
index 29618e8efa83653ff3a79503dc1d7026f6ffe08a..4ef631841816342f08ad015d0e5e20ee833860c2 100644 (file)
@@ -27,7 +27,6 @@
 #include "trace.h"
 #include "net/net.h"
 #include "qemu/error-report.h"
-#include "hw/qdev-addr.h"
 
 #include <zlib.h>
 
index d67ca796fbde8241c8d1ccde948e4da297175ec7..540daf75ccffa5cae8da428d65f5757f51791043 100644 (file)
 
 #include "hw/sysbus.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "exec/address-spaces.h"
 
+/* Old and buggy versions of QEMU used the wrong mapping from
+ * PCI IRQs to system interrupt lines. Unfortunately the Linux
+ * kernel also had the corresponding bug in setting up interrupts
+ * (so older kernels work on QEMU and not on real hardware).
+ * We automatically detect these broken kernels and flip back
+ * to the broken irq mapping by spotting guest writes to the
+ * PCI_INTERRUPT_LINE register to see where the guest thinks
+ * interrupts are going to be routed. So we start in state
+ * ASSUME_OK on reset, and transition to either BROKEN or
+ * FORCE_OK at the first write to an INTERRUPT_LINE register for
+ * a slot where broken and correct interrupt mapping would differ.
+ * Once in either BROKEN or FORCE_OK we never transition again;
+ * this allows a newer kernel to use the INTERRUPT_LINE
+ * registers arbitrarily once it has indicated that it isn't
+ * broken in its init code somewhere.
+ */
+enum {
+    PCI_VPB_IRQMAP_ASSUME_OK,
+    PCI_VPB_IRQMAP_BROKEN,
+    PCI_VPB_IRQMAP_FORCE_OK,
+};
+
 typedef struct {
-    SysBusDevice busdev;
+    PCIHostState parent_obj;
+
     qemu_irq irq[4];
-    int realview;
+    MemoryRegion controlregs;
     MemoryRegion mem_config;
     MemoryRegion mem_config2;
-    MemoryRegion isa;
+    /* Containers representing the PCI address spaces */
+    MemoryRegion pci_io_space;
+    MemoryRegion pci_mem_space;
+    /* Alias regions into PCI address spaces which we expose as sysbus regions.
+     * The offsets into pci_mem_space are controlled by the imap registers.
+     */
+    MemoryRegion pci_io_window;
+    MemoryRegion pci_mem_window[3];
+    PCIBus pci_bus;
+    PCIDevice pci_dev;
+
+    /* Constant for life of device: */
+    int realview;
+    uint32_t mem_win_size[3];
+
+    /* Variable state: */
+    uint32_t imap[3];
+    uint32_t smap[3];
+    uint32_t selfid;
+    uint32_t flags;
+    uint8_t irq_mapping;
 } PCIVPBState;
 
-static inline uint32_t vpb_pci_config_addr(hwaddr addr)
+static void pci_vpb_update_window(PCIVPBState *s, int i)
+{
+    /* Adjust the offset of the alias region we use for
+     * the memory window i to account for a change in the
+     * value of the corresponding IMAP register.
+     * Note that the semantics of the IMAP register differ
+     * for realview and versatile variants of the controller.
+     */
+    hwaddr offset;
+    if (s->realview) {
+        /* Top bits of register (masked according to window size) provide
+         * top bits of PCI address.
+         */
+        offset = s->imap[i] & ~(s->mem_win_size[i] - 1);
+    } else {
+        /* Bottom 4 bits of register provide top 4 bits of PCI address */
+        offset = s->imap[i] << 28;
+    }
+    memory_region_set_alias_offset(&s->pci_mem_window[i], offset);
+}
+
+static void pci_vpb_update_all_windows(PCIVPBState *s)
+{
+    /* Update all alias windows based on the current register state */
+    int i;
+
+    for (i = 0; i < 3; i++) {
+        pci_vpb_update_window(s, i);
+    }
+}
+
+static int pci_vpb_post_load(void *opaque, int version_id)
 {
-    return addr & 0xffffff;
+    PCIVPBState *s = opaque;
+    pci_vpb_update_all_windows(s);
+    return 0;
+}
+
+static const VMStateDescription pci_vpb_vmstate = {
+    .name = "versatile-pci",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .post_load = pci_vpb_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(imap, PCIVPBState, 3),
+        VMSTATE_UINT32_ARRAY(smap, PCIVPBState, 3),
+        VMSTATE_UINT32(selfid, PCIVPBState),
+        VMSTATE_UINT32(flags, PCIVPBState),
+        VMSTATE_UINT8(irq_mapping, PCIVPBState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+#define TYPE_VERSATILE_PCI "versatile_pci"
+#define PCI_VPB(obj) \
+    OBJECT_CHECK(PCIVPBState, (obj), TYPE_VERSATILE_PCI)
+
+#define TYPE_VERSATILE_PCI_HOST "versatile_pci_host"
+#define PCI_VPB_HOST(obj) \
+    OBJECT_CHECK(PCIDevice, (obj), TYPE_VERSATILE_PCIHOST)
+
+typedef enum {
+    PCI_IMAP0 = 0x0,
+    PCI_IMAP1 = 0x4,
+    PCI_IMAP2 = 0x8,
+    PCI_SELFID = 0xc,
+    PCI_FLAGS = 0x10,
+    PCI_SMAP0 = 0x14,
+    PCI_SMAP1 = 0x18,
+    PCI_SMAP2 = 0x1c,
+} PCIVPBControlRegs;
+
+static void pci_vpb_reg_write(void *opaque, hwaddr addr,
+                              uint64_t val, unsigned size)
+{
+    PCIVPBState *s = opaque;
+
+    switch (addr) {
+    case PCI_IMAP0:
+    case PCI_IMAP1:
+    case PCI_IMAP2:
+    {
+        int win = (addr - PCI_IMAP0) >> 2;
+        s->imap[win] = val;
+        pci_vpb_update_window(s, win);
+        break;
+    }
+    case PCI_SELFID:
+        s->selfid = val;
+        break;
+    case PCI_FLAGS:
+        s->flags = val;
+        break;
+    case PCI_SMAP0:
+    case PCI_SMAP1:
+    case PCI_SMAP2:
+    {
+        int win = (addr - PCI_SMAP0) >> 2;
+        s->smap[win] = val;
+        break;
+    }
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "pci_vpb_reg_write: Bad offset %x\n", (int)addr);
+        break;
+    }
+}
+
+static uint64_t pci_vpb_reg_read(void *opaque, hwaddr addr,
+                                 unsigned size)
+{
+    PCIVPBState *s = opaque;
+
+    switch (addr) {
+    case PCI_IMAP0:
+    case PCI_IMAP1:
+    case PCI_IMAP2:
+    {
+        int win = (addr - PCI_IMAP0) >> 2;
+        return s->imap[win];
+    }
+    case PCI_SELFID:
+        return s->selfid;
+    case PCI_FLAGS:
+        return s->flags;
+    case PCI_SMAP0:
+    case PCI_SMAP1:
+    case PCI_SMAP2:
+    {
+        int win = (addr - PCI_SMAP0) >> 2;
+        return s->smap[win];
+    }
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "pci_vpb_reg_read: Bad offset %x\n", (int)addr);
+        return 0;
+    }
 }
 
+static const MemoryRegionOps pci_vpb_reg_ops = {
+    .read = pci_vpb_reg_read,
+    .write = pci_vpb_reg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
 static void pci_vpb_config_write(void *opaque, hwaddr addr,
                                  uint64_t val, unsigned size)
 {
-    pci_data_write(opaque, vpb_pci_config_addr(addr), val, size);
+    PCIVPBState *s = opaque;
+    if (!s->realview && (addr & 0xff) == PCI_INTERRUPT_LINE
+        && s->irq_mapping == PCI_VPB_IRQMAP_ASSUME_OK) {
+        uint8_t devfn = addr >> 8;
+        if ((PCI_SLOT(devfn) % PCI_NUM_PINS) != 2) {
+            if (val == 27) {
+                s->irq_mapping = PCI_VPB_IRQMAP_BROKEN;
+            } else {
+                s->irq_mapping = PCI_VPB_IRQMAP_FORCE_OK;
+            }
+        }
+    }
+    pci_data_write(&s->pci_bus, addr, val, size);
 }
 
 static uint64_t pci_vpb_config_read(void *opaque, hwaddr addr,
                                     unsigned size)
 {
+    PCIVPBState *s = opaque;
     uint32_t val;
-    val = pci_data_read(opaque, vpb_pci_config_addr(addr), size);
+    val = pci_data_read(&s->pci_bus, addr, size);
     return val;
 }
 
@@ -48,7 +249,47 @@ static const MemoryRegionOps pci_vpb_config_ops = {
 
 static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
 {
-    return irq_num;
+    PCIVPBState *s = container_of(d->bus, PCIVPBState, pci_bus);
+
+    if (s->irq_mapping == PCI_VPB_IRQMAP_BROKEN) {
+        /* Legacy broken IRQ mapping for compatibility with old and
+         * buggy Linux guests
+         */
+        return irq_num;
+    }
+
+    /* Slot to IRQ mapping for RealView Platform Baseboard 926 backplane
+     *      name    slot    IntA    IntB    IntC    IntD
+     *      A       31      IRQ28   IRQ29   IRQ30   IRQ27
+     *      B       30      IRQ27   IRQ28   IRQ29   IRQ30
+     *      C       29      IRQ30   IRQ27   IRQ28   IRQ29
+     * Slot C is for the host bridge; A and B the peripherals.
+     * Our output irqs 0..3 correspond to the baseboard's 27..30.
+     *
+     * This mapping function takes account of an oddity in the PB926
+     * board wiring, where the FPGA's P_nINTA input is connected to
+     * the INTB connection on the board PCI edge connector, P_nINTB
+     * is connected to INTC, and so on, so everything is one number
+     * further round from where you might expect.
+     */
+    return pci_swizzle_map_irq_fn(d, irq_num + 2);
+}
+
+static int pci_vpb_rv_map_irq(PCIDevice *d, int irq_num)
+{
+    /* Slot to IRQ mapping for RealView EB and PB1176 backplane
+     *      name    slot    IntA    IntB    IntC    IntD
+     *      A       31      IRQ50   IRQ51   IRQ48   IRQ49
+     *      B       30      IRQ49   IRQ50   IRQ51   IRQ48
+     *      C       29      IRQ48   IRQ49   IRQ50   IRQ51
+     * Slot C is for the host bridge; A and B the peripherals.
+     * Our output irqs 0..3 correspond to the baseboard's 48..51.
+     *
+     * The PB1176 and EB boards don't have the PB926 wiring oddity
+     * described above; P_nINTA connects to INTA, P_nINTB to INTB
+     * and so on, which is why this mapping function is different.
+     */
+    return pci_swizzle_map_irq_fn(d, irq_num + 3);
 }
 
 static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
@@ -58,53 +299,109 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[irq_num], level);
 }
 
-static int pci_vpb_init(SysBusDevice *dev)
+static void pci_vpb_reset(DeviceState *d)
+{
+    PCIVPBState *s = PCI_VPB(d);
+
+    s->imap[0] = 0;
+    s->imap[1] = 0;
+    s->imap[2] = 0;
+    s->smap[0] = 0;
+    s->smap[1] = 0;
+    s->smap[2] = 0;
+    s->selfid = 0;
+    s->flags = 0;
+    s->irq_mapping = PCI_VPB_IRQMAP_ASSUME_OK;
+
+    pci_vpb_update_all_windows(s);
+}
+
+static void pci_vpb_init(Object *obj)
 {
-    PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
-    PCIBus *bus;
+    PCIHostState *h = PCI_HOST_BRIDGE(obj);
+    PCIVPBState *s = PCI_VPB(obj);
+
+    memory_region_init(&s->pci_io_space, "pci_io", 1ULL << 32);
+    memory_region_init(&s->pci_mem_space, "pci_mem", 1ULL << 32);
+
+    pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), "pci",
+                        &s->pci_mem_space, &s->pci_io_space,
+                        PCI_DEVFN(11, 0), TYPE_PCI_BUS);
+    h->bus = &s->pci_bus;
+
+    object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST);
+    qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
+    object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(29, 0), "addr",
+                            NULL);
+
+    /* Window sizes for VersatilePB; realview_pci's init will override */
+    s->mem_win_size[0] = 0x0c000000;
+    s->mem_win_size[1] = 0x10000000;
+    s->mem_win_size[2] = 0x10000000;
+}
+
+static void pci_vpb_realize(DeviceState *dev, Error **errp)
+{
+    PCIVPBState *s = PCI_VPB(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    pci_map_irq_fn mapfn;
     int i;
 
     for (i = 0; i < 4; i++) {
-        sysbus_init_irq(dev, &s->irq[i]);
+        sysbus_init_irq(sbd, &s->irq[i]);
+    }
+
+    if (s->realview) {
+        mapfn = pci_vpb_rv_map_irq;
+    } else {
+        mapfn = pci_vpb_map_irq;
     }
-    bus = pci_register_bus(&dev->qdev, "pci",
-                           pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
-                           get_system_memory(), get_system_io(),
-                           PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
 
-    /* ??? Register memory space.  */
+    pci_bus_irqs(&s->pci_bus, pci_vpb_set_irq, mapfn, s->irq, 4);
 
     /* Our memory regions are:
-     * 0 : PCI self config window
-     * 1 : PCI config window
-     * 2 : PCI IO window (realview_pci only)
+     * 0 : our control registers
+     * 1 : PCI self config window
+     * 2 : PCI config window
+     * 3 : PCI IO window
+     * 4..6 : PCI memory windows
      */
-    memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
+    memory_region_init_io(&s->controlregs, &pci_vpb_reg_ops, s, "pci-vpb-regs",
+                          0x1000);
+    sysbus_init_mmio(sbd, &s->controlregs);
+    memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, s,
                           "pci-vpb-selfconfig", 0x1000000);
-    sysbus_init_mmio(dev, &s->mem_config);
-    memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
+    sysbus_init_mmio(sbd, &s->mem_config);
+    memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, s,
                           "pci-vpb-config", 0x1000000);
-    sysbus_init_mmio(dev, &s->mem_config2);
-    if (s->realview) {
-        isa_mmio_setup(&s->isa, 0x0100000);
-        sysbus_init_mmio(dev, &s->isa);
-    }
+    sysbus_init_mmio(sbd, &s->mem_config2);
 
-    pci_create_simple(bus, -1, "versatile_pci_host");
-    return 0;
-}
+    /* The window into I/O space is always into a fixed base address;
+     * its size is the same for both realview and versatile.
+     */
+    memory_region_init_alias(&s->pci_io_window, "pci-vbp-io-window",
+                             &s->pci_io_space, 0, 0x100000);
 
-static int pci_realview_init(SysBusDevice *dev)
-{
-    PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
-    s->realview = 1;
-    return pci_vpb_init(dev);
+    sysbus_init_mmio(sbd, &s->pci_io_space);
+
+    /* Create the alias regions corresponding to our three windows onto
+     * PCI memory space. The sizes vary from board to board; the base
+     * offsets are guest controllable via the IMAP registers.
+     */
+    for (i = 0; i < 3; i++) {
+        memory_region_init_alias(&s->pci_mem_window[i], "pci-vbp-window",
+                                 &s->pci_mem_space, 0, s->mem_win_size[i]);
+        sysbus_init_mmio(sbd, &s->pci_mem_window[i]);
+    }
+
+    /* TODO Remove once realize propagates to child devices. */
+    object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
 }
 
 static int versatile_pci_host_init(PCIDevice *d)
 {
     pci_set_word(d->config + PCI_STATUS,
-                PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
+                 PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
     pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10);
     return 0;
 }
@@ -120,7 +417,7 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo versatile_pci_host_info = {
-    .name          = "versatile_pci_host",
+    .name          = TYPE_VERSATILE_PCI_HOST,
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(PCIDevice),
     .class_init    = versatile_pci_host_class_init,
@@ -128,30 +425,36 @@ static const TypeInfo versatile_pci_host_info = {
 
 static void pci_vpb_class_init(ObjectClass *klass, void *data)
 {
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
-    sdc->init = pci_vpb_init;
+    dc->realize = pci_vpb_realize;
+    dc->reset = pci_vpb_reset;
+    dc->vmsd = &pci_vpb_vmstate;
 }
 
 static const TypeInfo pci_vpb_info = {
-    .name          = "versatile_pci",
-    .parent        = TYPE_SYS_BUS_DEVICE,
+    .name          = TYPE_VERSATILE_PCI,
+    .parent        = TYPE_PCI_HOST_BRIDGE,
     .instance_size = sizeof(PCIVPBState),
+    .instance_init = pci_vpb_init,
     .class_init    = pci_vpb_class_init,
 };
 
-static void pci_realview_class_init(ObjectClass *klass, void *data)
+static void pci_realview_init(Object *obj)
 {
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+    PCIVPBState *s = PCI_VPB(obj);
 
-    sdc->init = pci_realview_init;
+    s->realview = 1;
+    /* The PCI window sizes are different on Realview boards */
+    s->mem_win_size[0] = 0x01000000;
+    s->mem_win_size[1] = 0x04000000;
+    s->mem_win_size[2] = 0x08000000;
 }
 
 static const TypeInfo pci_realview_info = {
     .name          = "realview_pci",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(PCIVPBState),
-    .class_init    = pci_realview_class_init,
+    .parent        = TYPE_VERSATILE_PCI,
+    .instance_init = pci_realview_init,
 };
 
 static void versatile_pci_register_types(void)
index 8e56b16648f8085c5d643c14f041454cd072670c..f0c7ee9abd5891d40b6b47e8e48f0efd135e5e4f 100644 (file)
@@ -337,7 +337,7 @@ static void ref405ep_init(QEMUMachineInitArgs *args)
         if (kernel_cmdline != NULL) {
             len = strlen(kernel_cmdline);
             bdloc -= ((len + 255) & ~255);
-            cpu_physical_memory_write(bdloc, (void *)kernel_cmdline, len + 1);
+            cpu_physical_memory_write(bdloc, kernel_cmdline, len + 1);
             env->gpr[6] = bdloc;
             env->gpr[7] = bdloc + len;
         } else {
index 6728ba7ea08aab3741e6e66e940f82606c13ed89..1b4ce760e69d7acbcde3692d79e7e22ceb0687ff 100644 (file)
@@ -161,7 +161,7 @@ static int xilinx_load_device_tree(hwaddr addr,
     r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
     if (r < 0)
         fprintf(stderr, "couldn't set /chosen/bootargs\n");
-    cpu_physical_memory_write (addr, (void *)fdt, fdt_size);
+    cpu_physical_memory_write(addr, fdt, fdt_size);
 #else
     /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
        to the kernel.  */
index 31beb328858a4377af1ba485a741785746b6fd8f..635115f0977b3f2e22c44d1daab9d1b1577cbd93 100644 (file)
@@ -37,7 +37,6 @@
 #include "hw/nvram/fw_cfg.h"
 #include "hw/char/escc.h"
 #include "hw/empty_slot.h"
-#include "hw/qdev-addr.h"
 #include "hw/loader.h"
 #include "elf.h"
 #include "sysemu/blockdev.h"
index 05315c0475e892d5d3b949341726411e2fe71398..7053d5bb4b6e45fbe426a5978f82b2a4caae22a9 100644 (file)
@@ -85,6 +85,7 @@
 #define PCI_DEVICE_ID_REDHAT_SERIAL      0x0002
 #define PCI_DEVICE_ID_REDHAT_SERIAL2     0x0003
 #define PCI_DEVICE_ID_REDHAT_SERIAL4     0x0004
+#define PCI_DEVICE_ID_REDHAT_TEST        0x0005
 #define PCI_DEVICE_ID_REDHAT_QXL         0x0100
 
 #define FMT_PCIBUS                      PRIx64
diff --git a/include/hw/qdev-addr.h b/include/hw/qdev-addr.h
deleted file mode 100644 (file)
index 79708e6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef HW_QDEV_ADDR_H
-#define HW_QDEV_ADDR_H 1
-
-#define DEFINE_PROP_TADDR(_n, _s, _f, _d)                               \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_taddr, hwaddr)
-
-extern PropertyInfo qdev_prop_taddr;
-void qdev_prop_set_taddr(DeviceState *dev, const char *name, hwaddr value);
-
-#endif
index b21e5c2b9d030e3f15df14ff81e773316487856c..d3f14366dcdf2a9c4eb8c57b13cf249d4147ea39 100644 (file)
@@ -258,7 +258,6 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
                               uint32_t host_features);
 typedef struct virtio_serial_conf virtio_serial_conf;
 VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
-VirtIODevice *virtio_balloon_init(DeviceState *dev);
 typedef struct VirtIOSCSIConf VirtIOSCSIConf;
 VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *conf);
 typedef struct VirtIORNGConf VirtIORNGConf;
@@ -270,7 +269,6 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
 
 void virtio_net_exit(VirtIODevice *vdev);
 void virtio_serial_exit(VirtIODevice *vdev);
-void virtio_balloon_exit(VirtIODevice *vdev);
 void virtio_scsi_exit(VirtIODevice *vdev);
 void virtio_rng_exit(VirtIODevice *vdev);
 
index d3af35d1d9d2bc27752bf63fa28b382618046bc2..14a5f657ce5d6bcc088fc52d42c4c6149b171d89 100644 (file)
@@ -4,6 +4,7 @@
 #include "config-host.h"
 #include <inttypes.h>
 #include <limits.h>
+#include <string.h>
 #include "fpu/softfloat.h"
 
 #ifdef CONFIG_MACHINE_BSWAP_H
index 495e6f8dbd8570eb813363e48a1e2af2d17811e9..75bd7d99343284106f0e312e7f1b1b560e504cb4 100644 (file)
@@ -283,10 +283,6 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
 #endif
 
 #endif
-int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign,
-                           uint32_t size);
-
-int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
 
 int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
 int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
index fc4e17c8bb909635bb324d299cc588031f0cacf8..2d927217bd64aa756736d833fec08fa471aac314 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -500,6 +500,66 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
     return ret;
 }
 
+static int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val,
+                                  bool assign, uint32_t size, bool datamatch)
+{
+    int ret;
+    struct kvm_ioeventfd iofd;
+
+    iofd.datamatch = datamatch ? val : 0;
+    iofd.addr = addr;
+    iofd.len = size;
+    iofd.flags = 0;
+    iofd.fd = fd;
+
+    if (!kvm_enabled()) {
+        return -ENOSYS;
+    }
+
+    if (datamatch) {
+        iofd.flags |= KVM_IOEVENTFD_FLAG_DATAMATCH;
+    }
+    if (!assign) {
+        iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
+    }
+
+    ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd);
+
+    if (ret < 0) {
+        return -errno;
+    }
+
+    return 0;
+}
+
+static int kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint16_t val,
+                                 bool assign, uint32_t size, bool datamatch)
+{
+    struct kvm_ioeventfd kick = {
+        .datamatch = datamatch ? val : 0,
+        .addr = addr,
+        .flags = KVM_IOEVENTFD_FLAG_PIO,
+        .len = size,
+        .fd = fd,
+    };
+    int r;
+    if (!kvm_enabled()) {
+        return -ENOSYS;
+    }
+    if (datamatch) {
+        kick.flags |= KVM_IOEVENTFD_FLAG_DATAMATCH;
+    }
+    if (!assign) {
+        kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
+    }
+    r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
+    if (r < 0) {
+        return r;
+    }
+    return 0;
+}
+
+
 static int kvm_check_many_ioeventfds(void)
 {
     /* Userspace can use ioeventfd for io notification.  This requires a host
@@ -517,7 +577,7 @@ static int kvm_check_many_ioeventfds(void)
         if (ioeventfds[i] < 0) {
             break;
         }
-        ret = kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, true);
+        ret = kvm_set_ioeventfd_pio(ioeventfds[i], 0, i, true, 2, true);
         if (ret < 0) {
             close(ioeventfds[i]);
             break;
@@ -528,7 +588,7 @@ static int kvm_check_many_ioeventfds(void)
     ret = i == ARRAY_SIZE(ioeventfds);
 
     while (i-- > 0) {
-        kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, false);
+        kvm_set_ioeventfd_pio(ioeventfds[i], 0, i, false, 2, true);
         close(ioeventfds[i]);
     }
     return ret;
@@ -748,10 +808,8 @@ static void kvm_mem_ioeventfd_add(MemoryListener *listener,
     int fd = event_notifier_get_fd(e);
     int r;
 
-    assert(match_data && section->size <= 8);
-
     r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
-                               data, true, section->size);
+                               data, true, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -766,7 +824,7 @@ static void kvm_mem_ioeventfd_del(MemoryListener *listener,
     int r;
 
     r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
-                               data, false, section->size);
+                               data, false, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -780,10 +838,8 @@ static void kvm_io_ioeventfd_add(MemoryListener *listener,
     int fd = event_notifier_get_fd(e);
     int r;
 
-    assert(match_data && section->size == 2);
-
-    r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
-                                   data, true);
+    r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space,
+                              data, true, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -798,8 +854,8 @@ static void kvm_io_ioeventfd_del(MemoryListener *listener,
     int fd = event_notifier_get_fd(e);
     int r;
 
-    r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
-                                   data, false);
+    r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space,
+                              data, false, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -1967,59 +2023,6 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
 
     return r;
 }
-
-int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, bool assign,
-                           uint32_t size)
-{
-    int ret;
-    struct kvm_ioeventfd iofd;
-
-    iofd.datamatch = val;
-    iofd.addr = addr;
-    iofd.len = size;
-    iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH;
-    iofd.fd = fd;
-
-    if (!kvm_enabled()) {
-        return -ENOSYS;
-    }
-
-    if (!assign) {
-        iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
-    }
-
-    ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd);
-
-    if (ret < 0) {
-        return -errno;
-    }
-
-    return 0;
-}
-
-int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
-{
-    struct kvm_ioeventfd kick = {
-        .datamatch = val,
-        .addr = addr,
-        .len = 2,
-        .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO,
-        .fd = fd,
-    };
-    int r;
-    if (!kvm_enabled()) {
-        return -ENOSYS;
-    }
-    if (!assign) {
-        kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
-    }
-    r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
-    if (r < 0) {
-        return r;
-    }
-    return 0;
-}
-
 int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
 {
     return kvm_arch_on_sigbus_vcpu(cpu, code, addr);
index 723a813735cfadac8a4fe22114856f0901d81e36..5f52186ae713c777d3ac5051ca7e21786eb5d0cc 100644 (file)
@@ -101,16 +101,6 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
 }
 #endif
 
-int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
-{
-    return -ENOSYS;
-}
-
-int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign, uint32_t len)
-{
-    return -ENOSYS;
-}
-
 int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
 {
     return 1;
index 1f07621ffe2d00febfa016f3f9ab475a1f6c663a..c705960d7e3e5b1cfae1fb5a91537c241f2ba123 100644 (file)
@@ -914,7 +914,7 @@ static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
     for (i = 0; i < nw; i++) {
         v = 0;
         for (j = 0; j < TARGET_ABI_BITS; j++) {
-            v |= ((FD_ISSET(k, fds) != 0) << j);
+            v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
             k++;
         }
         __put_user(v, &target_fds[i]);
@@ -2764,7 +2764,7 @@ static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
     if (target_to_host_sembuf(sops, ptr, nsops))
         return -TARGET_EFAULT;
 
-    return semop(semid, sops, nsops);
+    return get_errno(semop(semid, sops, nsops));
 }
 
 struct target_msqid_ds
@@ -6957,7 +6957,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_semop
     case TARGET_NR_semop:
-        ret = get_errno(do_semop(arg1, arg2, arg3));
+        ret = do_semop(arg1, arg2, arg3);
         break;
 #endif
 #ifdef TARGET_NR_semctl
@@ -7743,12 +7743,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (gidsetsize == 0)
                 break;
             if (!is_error(ret)) {
-                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
+                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
                 if (!target_grouplist)
                     goto efault;
                 for(i = 0;i < ret; i++)
                     target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
-                unlock_user(target_grouplist, arg2, gidsetsize * 2);
+                unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
             }
         }
         break;
@@ -7760,7 +7760,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             int i;
             if (gidsetsize) {
                 grouplist = alloca(gidsetsize * sizeof(gid_t));
-                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
+                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
                 if (!target_grouplist) {
                     ret = -TARGET_EFAULT;
                     goto fail;
index 0b23f7795a32ccf36c64e130d2319fa28d6a6117..c90eda497afd4f0355e48d530dde1ae0f2ce9431 100755 (executable)
@@ -27,9 +27,9 @@ MSR_IA32_VMX_VMFUNC = 0x491
 class msr(object):
     def __init__(self):
         try:
-            self.f = file('/dev/cpu/0/msr')
+            self.f = open('/dev/cpu/0/msr', 'r', 0)
         except:
-            self.f = file('/dev/msr0')
+            self.f = open('/dev/msr0', 'r', 0)
     def read(self, index, default = None):
         import struct
         self.f.seek(index)
@@ -96,6 +96,19 @@ class Misc(object):
             print '  %-40s %s' % (self.bits[bits], fmt(v))
 
 controls = [
+    Misc(
+        name = 'Basic VMX Information',
+        bits = {
+            (0, 31): 'Revision',
+            (32,44): 'VMCS size',
+            48: 'VMCS restricted to 32 bit addresses',
+            49: 'Dual-monitor support',
+            (50, 53): 'VMCS memory type',
+            54: 'INS/OUTS instruction information',
+            55: 'IA32_VMX_TRUE_*_CTLS support',
+            },
+        msr = MSR_IA32_VMX_BASIC,
+        ),
     Control(
         name = 'pin-based controls',
         bits = {
@@ -103,6 +116,7 @@ controls = [
             3: 'NMI exiting',
             5: 'Virtual NMIs',
             6: 'Activate VMX-preemption timer',
+            7: 'Process posted interrupts',
             },
         cap_msr = MSR_IA32_VMX_PINBASED_CTLS,
         true_cap_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
@@ -143,15 +157,19 @@ controls = [
             0: 'Virtualize APIC accesses',
             1: 'Enable EPT',
             2: 'Descriptor-table exiting',
+            3: 'Enable RDTSCP',
             4: 'Virtualize x2APIC mode',
             5: 'Enable VPID',
             6: 'WBINVD exiting',
             7: 'Unrestricted guest',
+            8: 'APIC register emulation',
             9: 'Virtual interrupt delivery',
             10: 'PAUSE-loop exiting',
             11: 'RDRAND exiting',
             12: 'Enable INVPCID',
             13: 'Enable VM functions',
+            14: 'VMCS shadowing',
+            18: 'EPT-violation #VE'
             },
         cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2,
         ),
@@ -196,10 +214,12 @@ controls = [
             6: 'HLT activity state',
             7: 'Shutdown activity state',
             8: 'Wait-for-SIPI activity state',
+            15: 'IA32_SMBASE support',
             (16,24): 'Number of CR3-target values',
             (25,27): 'MSR-load/store count recommenation',
             28: 'IA32_SMM_MONITOR_CTL[2] can be set to 1',
-            (32,62): 'MSEG revision identifier',
+            29: 'VMWRITE to VM-exit information fields',
+            (32,63): 'MSEG revision identifier',
             },
         msr = MSR_IA32_VMX_MISC_CTLS,
         ),
index 25895509befb5f9cd4c0a62c5ccbad7c9071d56f..12fcefe0c693fc36a53c0b49f4308cae56dccf47 100644 (file)
@@ -111,6 +111,10 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
 
 #define ENV_OFFSET offsetof(ARMCPU, env)
 
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_arm_cpu;
+#endif
+
 void register_cp_regs_for_features(ARMCPU *cpu);
 
 void arm_cpu_do_interrupt(CPUState *cpu);
index a1e90939d671983b300593855fe08dc663152029..496a59f5c0936d14c2875e6430c06ef5a3c4103a 100644 (file)
@@ -814,6 +814,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->do_interrupt = arm_cpu_do_interrupt;
+    cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
 }
 
 static void cpu_register(const ARMCPUInfo *info)
index 2b972212095d0819c5e2a12e322bf8fa82c97d74..54384446b4d1735236c568b97532e7726b97e2e6 100644 (file)
@@ -640,8 +640,6 @@ static inline CPUARMState *cpu_init(const char *cpu_model)
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
-#define CPU_SAVE_VERSION 9
-
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
index 68dca7ffb2b6c5bf2a77a4c3561d844b97dad600..4dd057c4889d85cc1156484e7c455a0c4f53cdc2 100644 (file)
 #include "hw/hw.h"
 #include "hw/boards.h"
 
-void cpu_save(QEMUFile *f, void *opaque)
+static bool vfp_needed(void *opaque)
 {
-    int i;
-    CPUARMState *env = (CPUARMState *)opaque;
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    for (i = 0; i < 16; i++) {
-        qemu_put_be32(f, env->regs[i]);
-    }
-    qemu_put_be32(f, cpsr_read(env));
-    qemu_put_be32(f, env->spsr);
-    for (i = 0; i < 6; i++) {
-        qemu_put_be32(f, env->banked_spsr[i]);
-        qemu_put_be32(f, env->banked_r13[i]);
-        qemu_put_be32(f, env->banked_r14[i]);
-    }
-    for (i = 0; i < 5; i++) {
-        qemu_put_be32(f, env->usr_regs[i]);
-        qemu_put_be32(f, env->fiq_regs[i]);
-    }
-    qemu_put_be32(f, env->cp15.c0_cpuid);
-    qemu_put_be32(f, env->cp15.c0_cssel);
-    qemu_put_be32(f, env->cp15.c1_sys);
-    qemu_put_be32(f, env->cp15.c1_coproc);
-    qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
-    qemu_put_be32(f, env->cp15.c1_scr);
-    qemu_put_be32(f, env->cp15.c2_base0);
-    qemu_put_be32(f, env->cp15.c2_base0_hi);
-    qemu_put_be32(f, env->cp15.c2_base1);
-    qemu_put_be32(f, env->cp15.c2_base1_hi);
-    qemu_put_be32(f, env->cp15.c2_control);
-    qemu_put_be32(f, env->cp15.c2_mask);
-    qemu_put_be32(f, env->cp15.c2_base_mask);
-    qemu_put_be32(f, env->cp15.c2_data);
-    qemu_put_be32(f, env->cp15.c2_insn);
-    qemu_put_be32(f, env->cp15.c3);
-    qemu_put_be32(f, env->cp15.c5_insn);
-    qemu_put_be32(f, env->cp15.c5_data);
-    for (i = 0; i < 8; i++) {
-        qemu_put_be32(f, env->cp15.c6_region[i]);
-    }
-    qemu_put_be32(f, env->cp15.c6_insn);
-    qemu_put_be32(f, env->cp15.c6_data);
-    qemu_put_be32(f, env->cp15.c7_par);
-    qemu_put_be32(f, env->cp15.c7_par_hi);
-    qemu_put_be32(f, env->cp15.c9_insn);
-    qemu_put_be32(f, env->cp15.c9_data);
-    qemu_put_be32(f, env->cp15.c9_pmcr);
-    qemu_put_be32(f, env->cp15.c9_pmcnten);
-    qemu_put_be32(f, env->cp15.c9_pmovsr);
-    qemu_put_be32(f, env->cp15.c9_pmxevtyper);
-    qemu_put_be32(f, env->cp15.c9_pmuserenr);
-    qemu_put_be32(f, env->cp15.c9_pminten);
-    qemu_put_be32(f, env->cp15.c13_fcse);
-    qemu_put_be32(f, env->cp15.c13_context);
-    qemu_put_be32(f, env->cp15.c13_tls1);
-    qemu_put_be32(f, env->cp15.c13_tls2);
-    qemu_put_be32(f, env->cp15.c13_tls3);
-    qemu_put_be32(f, env->cp15.c15_cpar);
-    qemu_put_be32(f, env->cp15.c15_power_control);
-    qemu_put_be32(f, env->cp15.c15_diagnostic);
-    qemu_put_be32(f, env->cp15.c15_power_diagnostic);
-
-    qemu_put_be64(f, env->features);
-
-    if (arm_feature(env, ARM_FEATURE_VFP)) {
-        for (i = 0;  i < 16; i++) {
-            CPU_DoubleU u;
-            u.d = env->vfp.regs[i];
-            qemu_put_be32(f, u.l.upper);
-            qemu_put_be32(f, u.l.lower);
-        }
-        for (i = 0; i < 16; i++) {
-            qemu_put_be32(f, env->vfp.xregs[i]);
-        }
+    return arm_feature(env, ARM_FEATURE_VFP);
+}
 
-        /* TODO: Should use proper FPSCR access functions.  */
-        qemu_put_be32(f, env->vfp.vec_len);
-        qemu_put_be32(f, env->vfp.vec_stride);
-
-        if (arm_feature(env, ARM_FEATURE_VFP3)) {
-            for (i = 16;  i < 32; i++) {
-                CPU_DoubleU u;
-                u.d = env->vfp.regs[i];
-                qemu_put_be32(f, u.l.upper);
-                qemu_put_be32(f, u.l.lower);
-            }
-        }
-    }
+static int get_fpscr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+    uint32_t val = qemu_get_be32(f);
 
-    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
-        for (i = 0; i < 16; i++) {
-            qemu_put_be64(f, env->iwmmxt.regs[i]);
-        }
-        for (i = 0; i < 16; i++) {
-            qemu_put_be32(f, env->iwmmxt.cregs[i]);
-        }
-    }
+    vfp_set_fpscr(env, val);
+    return 0;
+}
 
-    if (arm_feature(env, ARM_FEATURE_M)) {
-        qemu_put_be32(f, env->v7m.other_sp);
-        qemu_put_be32(f, env->v7m.vecbase);
-        qemu_put_be32(f, env->v7m.basepri);
-        qemu_put_be32(f, env->v7m.control);
-        qemu_put_be32(f, env->v7m.current_sp);
-        qemu_put_be32(f, env->v7m.exception);
-    }
+static void put_fpscr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
-        qemu_put_be32(f, env->teecr);
-        qemu_put_be32(f, env->teehbr);
-    }
+    qemu_put_be32(f, vfp_get_fpscr(env));
 }
 
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
+static const VMStateInfo vmstate_fpscr = {
+    .name = "fpscr",
+    .get = get_fpscr,
+    .put = put_fpscr,
+};
+
+static const VMStateDescription vmstate_vfp = {
+    .name = "cpu/vfp",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .fields = (VMStateField[]) {
+        VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 32),
+        /* The xregs array is a little awkward because element 1 (FPSCR)
+         * requires a specific accessor, so we have to split it up in
+         * the vmstate:
+         */
+        VMSTATE_UINT32(env.vfp.xregs[0], ARMCPU),
+        VMSTATE_UINT32_SUB_ARRAY(env.vfp.xregs, ARMCPU, 2, 14),
+        {
+            .name = "fpscr",
+            .version_id = 0,
+            .size = sizeof(uint32_t),
+            .info = &vmstate_fpscr,
+            .flags = VMS_SINGLE,
+            .offset = 0,
+        },
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static bool iwmmxt_needed(void *opaque)
 {
-    CPUARMState *env = (CPUARMState *)opaque;
-    int i;
-    uint32_t val;
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    if (version_id != CPU_SAVE_VERSION)
-        return -EINVAL;
+    return arm_feature(env, ARM_FEATURE_IWMMXT);
+}
 
-    for (i = 0; i < 16; i++) {
-        env->regs[i] = qemu_get_be32(f);
-    }
-    val = qemu_get_be32(f);
-    /* Avoid mode switch when restoring CPSR.  */
-    env->uncached_cpsr = val & CPSR_M;
-    cpsr_write(env, val, 0xffffffff);
-    env->spsr = qemu_get_be32(f);
-    for (i = 0; i < 6; i++) {
-        env->banked_spsr[i] = qemu_get_be32(f);
-        env->banked_r13[i] = qemu_get_be32(f);
-        env->banked_r14[i] = qemu_get_be32(f);
-    }
-    for (i = 0; i < 5; i++) {
-        env->usr_regs[i] = qemu_get_be32(f);
-        env->fiq_regs[i] = qemu_get_be32(f);
-    }
-    env->cp15.c0_cpuid = qemu_get_be32(f);
-    env->cp15.c0_cssel = qemu_get_be32(f);
-    env->cp15.c1_sys = qemu_get_be32(f);
-    env->cp15.c1_coproc = qemu_get_be32(f);
-    env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
-    env->cp15.c1_scr = qemu_get_be32(f);
-    env->cp15.c2_base0 = qemu_get_be32(f);
-    env->cp15.c2_base0_hi = qemu_get_be32(f);
-    env->cp15.c2_base1 = qemu_get_be32(f);
-    env->cp15.c2_base1_hi = qemu_get_be32(f);
-    env->cp15.c2_control = qemu_get_be32(f);
-    env->cp15.c2_mask = qemu_get_be32(f);
-    env->cp15.c2_base_mask = qemu_get_be32(f);
-    env->cp15.c2_data = qemu_get_be32(f);
-    env->cp15.c2_insn = qemu_get_be32(f);
-    env->cp15.c3 = qemu_get_be32(f);
-    env->cp15.c5_insn = qemu_get_be32(f);
-    env->cp15.c5_data = qemu_get_be32(f);
-    for (i = 0; i < 8; i++) {
-        env->cp15.c6_region[i] = qemu_get_be32(f);
+static const VMStateDescription vmstate_iwmmxt = {
+    .name = "cpu/iwmmxt",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16),
+        VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16),
+        VMSTATE_END_OF_LIST()
     }
-    env->cp15.c6_insn = qemu_get_be32(f);
-    env->cp15.c6_data = qemu_get_be32(f);
-    env->cp15.c7_par = qemu_get_be32(f);
-    env->cp15.c7_par_hi = qemu_get_be32(f);
-    env->cp15.c9_insn = qemu_get_be32(f);
-    env->cp15.c9_data = qemu_get_be32(f);
-    env->cp15.c9_pmcr = qemu_get_be32(f);
-    env->cp15.c9_pmcnten = qemu_get_be32(f);
-    env->cp15.c9_pmovsr = qemu_get_be32(f);
-    env->cp15.c9_pmxevtyper = qemu_get_be32(f);
-    env->cp15.c9_pmuserenr = qemu_get_be32(f);
-    env->cp15.c9_pminten = qemu_get_be32(f);
-    env->cp15.c13_fcse = qemu_get_be32(f);
-    env->cp15.c13_context = qemu_get_be32(f);
-    env->cp15.c13_tls1 = qemu_get_be32(f);
-    env->cp15.c13_tls2 = qemu_get_be32(f);
-    env->cp15.c13_tls3 = qemu_get_be32(f);
-    env->cp15.c15_cpar = qemu_get_be32(f);
-    env->cp15.c15_power_control = qemu_get_be32(f);
-    env->cp15.c15_diagnostic = qemu_get_be32(f);
-    env->cp15.c15_power_diagnostic = qemu_get_be32(f);
-
-    env->features = qemu_get_be64(f);
-
-    if (arm_feature(env, ARM_FEATURE_VFP)) {
-        for (i = 0;  i < 16; i++) {
-            CPU_DoubleU u;
-            u.l.upper = qemu_get_be32(f);
-            u.l.lower = qemu_get_be32(f);
-            env->vfp.regs[i] = u.d;
-        }
-        for (i = 0; i < 16; i++) {
-            env->vfp.xregs[i] = qemu_get_be32(f);
-        }
+};
 
-        /* TODO: Should use proper FPSCR access functions.  */
-        env->vfp.vec_len = qemu_get_be32(f);
-        env->vfp.vec_stride = qemu_get_be32(f);
-
-        if (arm_feature(env, ARM_FEATURE_VFP3)) {
-            for (i = 16;  i < 32; i++) {
-                CPU_DoubleU u;
-                u.l.upper = qemu_get_be32(f);
-                u.l.lower = qemu_get_be32(f);
-                env->vfp.regs[i] = u.d;
-            }
-        }
-    }
+static bool m_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
-        for (i = 0; i < 16; i++) {
-            env->iwmmxt.regs[i] = qemu_get_be64(f);
-        }
-        for (i = 0; i < 16; i++) {
-            env->iwmmxt.cregs[i] = qemu_get_be32(f);
-        }
-    }
+    return arm_feature(env, ARM_FEATURE_M);
+}
 
-    if (arm_feature(env, ARM_FEATURE_M)) {
-        env->v7m.other_sp = qemu_get_be32(f);
-        env->v7m.vecbase = qemu_get_be32(f);
-        env->v7m.basepri = qemu_get_be32(f);
-        env->v7m.control = qemu_get_be32(f);
-        env->v7m.current_sp = qemu_get_be32(f);
-        env->v7m.exception = qemu_get_be32(f);
-    }
+const VMStateDescription vmstate_m = {
+    .name = "cpu/m",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(env.v7m.other_sp, ARMCPU),
+        VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
+        VMSTATE_UINT32(env.v7m.basepri, ARMCPU),
+        VMSTATE_UINT32(env.v7m.control, ARMCPU),
+        VMSTATE_INT32(env.v7m.current_sp, ARMCPU),
+        VMSTATE_INT32(env.v7m.exception, ARMCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static bool thumb2ee_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    return arm_feature(env, ARM_FEATURE_THUMB2EE);
+}
 
-    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
-        env->teecr = qemu_get_be32(f);
-        env->teehbr = qemu_get_be32(f);
+static const VMStateDescription vmstate_thumb2ee = {
+    .name = "cpu/thumb2ee",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(env.teecr, ARMCPU),
+        VMSTATE_UINT32(env.teehbr, ARMCPU),
+        VMSTATE_END_OF_LIST()
     }
+};
 
+static int get_cpsr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+    uint32_t val = qemu_get_be32(f);
+
+    /* Avoid mode switch when restoring CPSR */
+    env->uncached_cpsr = val & CPSR_M;
+    cpsr_write(env, val, 0xffffffff);
     return 0;
 }
+
+static void put_cpsr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    qemu_put_be32(f, cpsr_read(env));
+}
+
+static const VMStateInfo vmstate_cpsr = {
+    .name = "cpsr",
+    .get = get_cpsr,
+    .put = put_cpsr,
+};
+
+const VMStateDescription vmstate_arm_cpu = {
+    .name = "cpu",
+    .version_id = 11,
+    .minimum_version_id = 11,
+    .minimum_version_id_old = 11,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
+        {
+            .name = "cpsr",
+            .version_id = 0,
+            .size = sizeof(uint32_t),
+            .info = &vmstate_cpsr,
+            .flags = VMS_SINGLE,
+            .offset = 0,
+        },
+        VMSTATE_UINT32(env.spsr, ARMCPU),
+        VMSTATE_UINT32_ARRAY(env.banked_spsr, ARMCPU, 6),
+        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
+        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
+        VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
+        VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
+        VMSTATE_UINT32(env.cp15.c0_cpuid, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c0_cssel, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_sys, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_coproc, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_xscaleauxcr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_scr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base0, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base0_hi, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base1, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base1_hi, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_control, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_mask, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base_mask, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_data, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c3, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c5_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c5_data, ARMCPU),
+        VMSTATE_UINT32_ARRAY(env.cp15.c6_region, ARMCPU, 8),
+        VMSTATE_UINT32(env.cp15.c6_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c6_data, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c7_par, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c7_par_hi, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_data, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmcr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmcnten, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmovsr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmxevtyper, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmuserenr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pminten, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_fcse, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_context, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_tls1, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_tls2, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_tls3, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_cpar, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_ticonfig, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_i_max, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_i_min, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_threadid, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_power_control, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_diagnostic, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_power_diagnostic, ARMCPU),
+        VMSTATE_UINT32(env.exclusive_addr, ARMCPU),
+        VMSTATE_UINT32(env.exclusive_val, ARMCPU),
+        VMSTATE_UINT32(env.exclusive_high, ARMCPU),
+        VMSTATE_UINT64(env.features, ARMCPU),
+        VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection[]) {
+        {
+            .vmsd = &vmstate_vfp,
+            .needed = vfp_needed,
+        } , {
+            .vmsd = &vmstate_iwmmxt,
+            .needed = iwmmxt_needed,
+        } , {
+            .vmsd = &vmstate_m,
+            .needed = m_needed,
+        } , {
+            .vmsd = &vmstate_thumb2ee,
+            .needed = thumb2ee_needed,
+        } , {
+            /* empty */
+        }
+    }
+};
index 35a21be931c85e4df04813ca87a2fa55cf8b6ffa..a1b7b8c1a8fc07d68b4413d9076839c6d8fc7765 100644 (file)
@@ -6762,6 +6762,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
             }
             ARCH(6);
             gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
+            return;
         } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
             /* rfe */
             int32_t offset;
index cf1b05c28c5dbdba30daf3202ac5af95b69c3e71..a1614e8e50bad6bec98c7418ebd0cf2ee43d6aa6 100644 (file)
@@ -803,6 +803,7 @@ typedef struct CPUX86State {
 #endif
     uint64_t system_time_msr;
     uint64_t wall_clock_msr;
+    uint64_t steal_time_msr;
     uint64_t async_pf_en_msr;
     uint64_t pv_eoi_en_msr;
 
index 397afebecbb3dd9ac3b44c7a4702b83ba3df4c91..0e7cc8113f6e2b13aff32c336caba6c685f1b0b3 100644 (file)
@@ -68,6 +68,7 @@ static bool has_msr_tsc_deadline;
 static bool has_msr_async_pf_en;
 static bool has_msr_pv_eoi_en;
 static bool has_msr_misc_enable;
+static bool has_msr_kvm_steal_time;
 static int lm_capable_kernel;
 
 bool kvm_allows_irq0_override(void)
@@ -507,6 +508,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
     has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI);
 
+    has_msr_kvm_steal_time = c->eax & (1 << KVM_FEATURE_STEAL_TIME);
+
     cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
 
     for (i = 0; i <= limit; i++) {
@@ -1107,6 +1110,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
             kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN,
                               env->pv_eoi_en_msr);
         }
+        if (has_msr_kvm_steal_time) {
+            kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
+                              env->steal_time_msr);
+        }
         if (hyperv_hypercall_available()) {
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
@@ -1360,6 +1367,9 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (has_msr_pv_eoi_en) {
         msrs[n++].index = MSR_KVM_PV_EOI_EN;
     }
+    if (has_msr_kvm_steal_time) {
+        msrs[n++].index = MSR_KVM_STEAL_TIME;
+    }
 
     if (env->mcg_cap) {
         msrs[n++].index = MSR_MCG_STATUS;
@@ -1445,6 +1455,9 @@ static int kvm_get_msrs(X86CPU *cpu)
         case MSR_KVM_PV_EOI_EN:
             env->pv_eoi_en_msr = msrs[i].data;
             break;
+        case MSR_KVM_STEAL_TIME:
+            env->steal_time_msr = msrs[i].data;
+            break;
         }
     }
 
index ee85e574354b712d9ab295167e536af63076b5a2..3659db9e94431ae5c7aa428a121fb245eb3886ab 100644 (file)
@@ -292,6 +292,24 @@ static bool pv_eoi_msr_needed(void *opaque)
     return cpu->env.pv_eoi_en_msr != 0;
 }
 
+static bool steal_time_msr_needed(void *opaque)
+{
+    CPUX86State *cpu = opaque;
+
+    return cpu->steal_time_msr != 0;
+}
+
+static const VMStateDescription vmstate_steal_time_msr = {
+    .name = "cpu/steal_time_msr",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT64(steal_time_msr, CPUX86State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_async_pf_msr = {
     .name = "cpu/async_pf_msr",
     .version_id = 1,
@@ -502,6 +520,9 @@ const VMStateDescription vmstate_x86_cpu = {
         } , {
             .vmsd = &vmstate_pv_eoi_msr,
             .needed = pv_eoi_msr_needed,
+        } , {
+            .vmsd = &vmstate_steal_time_msr,
+            .needed = steal_time_msr_needed,
         } , {
             .vmsd = &vmstate_fpop_ip_dp,
             .needed = fpop_ip_dp_needed,
index 233f24ff41055ca83744543c7286441a8b56e21a..40f891da143d49330b6591d95a51553a54345662 100644 (file)
@@ -1775,6 +1775,7 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, int is_right)
     if (is_right) {
         tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask - 1);
         tcg_gen_shri_tl(cpu_cc_dst, cpu_T[0], mask);
+        tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
     } else {
         tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask);
         tcg_gen_andi_tl(cpu_cc_dst, cpu_T[0], 1);
index 048cc97347fad6f13cbe8b865806042be267350e..d51462a0159445b7c5a110951cf8d5852cb65062 100644 (file)
@@ -495,7 +495,7 @@ QemuCocoaView *cocoaView;
                 if (keycode == 58 || keycode == 69) { // emulate caps lock and num lock keydown and keyup
                     kbd_put_keycode(keycode);
                     kbd_put_keycode(keycode | 0x80);
-                } else if (is_graphic_console()) {
+                } else if (qemu_console_is_graphic(NULL)) {
                     if (keycode & 0x80)
                         kbd_put_keycode(0xe0);
                     if (modifiers_state[keycode] == 0) { // keydown
@@ -535,7 +535,7 @@ QemuCocoaView *cocoaView;
                 }
 
             // handle keys for graphic console
-            } else if (is_graphic_console()) {
+            } else if (qemu_console_is_graphic(NULL)) {
                 if (keycode & 0x80) //check bit for e0 in front
                     kbd_put_keycode(0xe0);
                 kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front
@@ -578,7 +578,7 @@ QemuCocoaView *cocoaView;
             break;
         case NSKeyUp:
             keycode = cocoa_keycode_to_qemu([event keyCode]);
-            if (is_graphic_console()) {
+            if (qemu_console_is_graphic(NULL)) {
                 if (keycode & 0x80)
                     kbd_put_keycode(0xe0);
                 kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key
@@ -1006,7 +1006,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
             [cocoaView handleEvent:event];
         }
     } while(event != nil);
-    vga_hw_update();
+    graphic_hw_update(NULL);
 }
 
 static void cocoa_cleanup(void)