Merge remote-tracking branch 'aneesh/for-upstream-3' into staging
authorAnthony Liguori <aliguori@us.ibm.com>
Thu, 8 Sep 2011 13:52:59 +0000 (08:52 -0500)
committerAnthony Liguori <aliguori@us.ibm.com>
Thu, 8 Sep 2011 13:52:59 +0000 (08:52 -0500)
191 files changed:
Makefile
Makefile.hw
Makefile.objs
Makefile.target
a.out.h
arm.ld
block.c
block.h
block/curl.c
block/parallels.c
block/qcow.c
block/qcow2-cluster.c
block/qcow2-refcount.c
block/qcow2-snapshot.c
block/qcow2.c
block/qcow2.h
block/sheepdog.c
block/vmdk.c
block/vvfat.c
block_int.h
blockdev.c
compiler.h
configure
cpus.c
docs/qapi-code-gen.txt
docs/tracing.txt
dyngen-exec.h
fpu/softfloat.c
fpu/softfloat.h
hmp-commands.hx
hppa.ld
hw/9pfs/virtio-9p.h
hw/acpi.c
hw/an5206.c
hw/apb_pci.c
hw/arm-misc.h
hw/armv7m.c
hw/axis_dev88.c
hw/bt.h
hw/cirrus_vga.c
hw/collie.c
hw/dec_pci.c
hw/dummy_m68k.c
hw/flash.h
hw/fw_cfg.c
hw/g364fb.c
hw/grackle_pci.c
hw/gumstix.c
hw/hpet_emul.h
hw/ide/ahci.c
hw/ide/ahci.h
hw/ide/atapi.c
hw/ide/core.c
hw/ide/internal.h
hw/ide/macio.c
hw/integratorcp.c
hw/leon3.c
hw/lm32_boards.c
hw/mainstone.c
hw/mcf5208.c
hw/milkymist-minimac2.c
hw/milkymist-softusb.c
hw/milkymist-tmu2.c
hw/milkymist.c
hw/mips.h
hw/mips_jazz.c
hw/mips_malta.c
hw/mips_r4k.c
hw/musicpal.c
hw/nseries.c
hw/omap.h
hw/omap2.c
hw/omap_gpmc.c
hw/omap_sx1.c
hw/onenand.c
hw/pc.c
hw/pci-stub.c
hw/pci.c
hw/pci_host.c
hw/pci_host.h
hw/pcie.c
hw/pcie_aer.c
hw/petalogix_ml605_mmu.c
hw/petalogix_s3adsp1800_mmu.c
hw/pflash_cfi01.c
hw/pflash_cfi02.c
hw/piix_pci.c
hw/ppc405_boards.c
hw/ppc4xx_pci.c
hw/ppce500_pci.c
hw/prep_pci.c
hw/pxa2xx_lcd.c
hw/qxl.c
hw/r2d.c
hw/rc4030.c
hw/scsi-disk.c
hw/sh_pci.c
hw/smbios.c
hw/smbios.h
hw/srp.h
hw/stellaris.c
hw/stellaris_enet.c
hw/sun4u.c
hw/sysbus.c
hw/sysbus.h
hw/tusb6010.c
hw/tusb6010.h [deleted file]
hw/unin_pci.c
hw/usb-ccid.c
hw/vga.c
hw/vhost.c
hw/vhost.h
hw/vhost_net.c
hw/virtex_ml507.c
hw/virtio-balloon.h
hw/virtio-blk.c
hw/virtio-blk.h
hw/virtio-net.h
hw/virtio-serial.h
hw/vmware_vga.c
hw/xen_disk.c
hw/xilinx_ethlite.c
hw/xilinx_intc.c
hw/xilinx_timer.c
hw/xilinx_uartlite.c
hw/z2.c
hw/zaurus.c
i386.ld
iohandler.c
kvm-all.c
libcacard/Makefile
libcacard/vscclient.c
linux-user/signal.c
linux-user/syscall_defs.h
m68k-semi.c
memory.c
memory.h
mips.ld
monitor.c
nbd.h
net.h
net/slirp.c
posix-aio-compat.c
ppc.ld
ppc64.ld
qemu-config.c
qemu-coroutine-lock.c
qemu-coroutine.h
qemu-ga.c
qemu-img-cmds.hx
qemu-img.c
qemu-img.texi
qemu-options.hx
qemu-timer.c
qmp-commands.hx
rules.mak
rwhandler.c [new file with mode: 0644]
rwhandler.h [new file with mode: 0644]
scripts/checkpatch.pl
scripts/simpletrace.py
scripts/tracetool
simpletrace.c [deleted file]
simpletrace.h [deleted file]
slirp/ip.h
slirp/slirp.h
sparc.ld
target-i386/kvm.c
target-i386/svm.h
target-microblaze/cpu.h
target-microblaze/translate.c
target-mips/cpu.h
target-mips/helper.c
target-mips/helper.h
target-mips/op_helper.c
target-mips/translate.c
target-mips/translate_init.c
target-s390x/cpu.h
tcg/optimize.c
tcg/ppc/tcg-target.c
tests/test-i386.c
tests/test_path.c
trace-events
trace/control.c [new file with mode: 0644]
trace/control.h [new file with mode: 0644]
trace/default.c [new file with mode: 0644]
trace/simple.c [new file with mode: 0644]
trace/simple.h [new file with mode: 0644]
trace/stderr.c [new file with mode: 0644]
trace/stderr.h [new file with mode: 0644]
vl.c
x86_64.ld

index 86068498e95844c45800a7e010bb341248050fed..e0cf51a8bfe3a4813fbbb7c2811627ac0b010461 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -209,6 +209,7 @@ clean:
        rm -Rf .libs
        rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d
        rm -f qemu-img-cmds.h
+       rm -f trace/*.o trace/*.d
        rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
        rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
        rm -f trace-dtrace.h trace-dtrace.h-timestamp
@@ -365,9 +366,8 @@ tar:
        rm -rf /tmp/$(FILE)
 
 SYSTEM_TARGETS=$(filter %-softmmu,$(TARGET_DIRS))
-SYSTEM_PROGS=$(patsubst qemu-system-i386,qemu, \
-             $(patsubst %-softmmu,qemu-system-%, \
-             $(SYSTEM_TARGETS)))
+SYSTEM_PROGS=$(patsubst %-softmmu,qemu-system-%, \
+             $(SYSTEM_TARGETS))
 
 USER_TARGETS=$(filter %-user,$(TARGET_DIRS))
 USER_PROGS=$(patsubst %-bsd-user,qemu-%, \
index 63eb7e40be7264268cbed33567b54f80f96bb2aa..659e441992e1ca84c32a3d03975e5204b0939a7c 100644 (file)
@@ -10,7 +10,6 @@ include $(SRC_PATH)/rules.mak
 $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
 
 QEMU_CFLAGS+=-I..
-QEMU_CFLAGS += $(GLIB_CFLAGS)
 
 include $(SRC_PATH)/Makefile.objs
 
index d1f3e5dae597755e60dd272a45b62fce3483f937..26b885bfeb23b8123afdfa37ddfe0ab84f9e8613 100644 (file)
@@ -372,18 +372,24 @@ trace-dtrace.lo: trace-dtrace.dtrace
        $(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC dtrace -o $@ -G -s $<, "  lt GEN trace-dtrace.o")
 endif
 
-simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
+trace/simple.o: trace/simple.c $(GENERATED_HEADERS)
 
-ifeq ($(TRACE_BACKEND),dtrace)
-trace-obj-y = trace-dtrace.o
-else
+trace-obj-$(CONFIG_TRACE_DTRACE) += trace-dtrace.o
+ifneq ($(TRACE_BACKEND),dtrace)
 trace-obj-y = trace.o
-ifeq ($(TRACE_BACKEND),simple)
-trace-obj-y += simpletrace.o
-user-obj-y += qemu-timer-common.o
-endif
 endif
 
+trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o
+
+trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o
+trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
+
+trace-nested-$(CONFIG_TRACE_STDERR) += stderr.o
+
+trace-nested-y += control.o
+
+trace-obj-y += $(addprefix trace/, $(trace-nested-y))
+
 ######################################################################
 # smartcard
 
index c9957ae63a4aa4dffdee37bf6716aaa77ab10b27..0787758ad63e0a21a0d5fb8358dd1e3901742399 100644 (file)
@@ -27,12 +27,8 @@ ifdef CONFIG_USER_ONLY
 QEMU_PROG=qemu-$(TARGET_ARCH2)
 else
 # system emulator name
-ifeq ($(TARGET_ARCH), i386)
-QEMU_PROG=qemu$(EXESUF)
-else
 QEMU_PROG=qemu-system-$(TARGET_ARCH2)$(EXESUF)
 endif
-endif
 
 PROGS=$(QEMU_PROG)
 STPFILES=
@@ -44,7 +40,7 @@ endif
 config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
-ifdef CONFIG_SYSTEMTAP_TRACE
+ifdef CONFIG_TRACE_SYSTEMTAP
 stap: $(QEMU_PROG).stp
 
 ifdef CONFIG_USER_ONLY
@@ -195,6 +191,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virt
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
 obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
+obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += memory.o
@@ -386,16 +383,18 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
 endif # CONFIG_SOFTMMU
 
 ifndef CONFIG_LINUX_USER
+ifndef CONFIG_BSD_USER
 # libcacard needs qemu-thread support, and besides is only needed by devices
-# so not requires with linux-user targets
+# so not requires with linux-user / bsd-user targets
 obj-$(CONFIG_SMARTCARD_NSS) += $(addprefix ../libcacard/, $(libcacard-y))
+endif # CONFIG_BSD_USER
 endif # CONFIG_LINUX_USER
 
 obj-y += $(addprefix ../, $(trace-obj-y))
 obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
 
 $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
-       $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y))
+       $(call LINK,$^)
 
 
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
@@ -411,7 +410,7 @@ clean:
        rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
        rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o
        rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
-ifdef CONFIG_SYSTEMTAP_TRACE
+ifdef CONFIG_TRACE_SYSTEMTAP
        rm -f *.stp
 endif
 
@@ -422,7 +421,7 @@ ifneq ($(STRIP),)
        $(STRIP) $(patsubst %,"$(DESTDIR)$(bindir)/%",$(PROGS))
 endif
 endif
-ifdef CONFIG_SYSTEMTAP_TRACE
+ifdef CONFIG_TRACE_SYSTEMTAP
        $(INSTALL_DIR) "$(DESTDIR)$(datadir)/../systemtap/tapset"
        $(INSTALL_DATA) $(QEMU_PROG).stp "$(DESTDIR)$(datadir)/../systemtap/tapset"
 endif
diff --git a/a.out.h b/a.out.h
index dfc104e606d9730c8f978f6b3d3da91dd85addad..33ca7f77eae0afc2f778b9f98d352743554ba294 100644 (file)
--- a/a.out.h
+++ b/a.out.h
@@ -151,7 +151,7 @@ struct external_lineno {
 #define E_FILNMLEN     14      /* # characters in a file name          */
 #define E_DIMNUM       4       /* # array dimensions in auxiliary entry */
 
-struct __attribute__((packed)) external_syment
+struct QEMU_PACKED external_syment
 {
   union {
     char e_name[E_SYMNMLEN];
diff --git a/arm.ld b/arm.ld
index 12b3edb5bbe66ea94f96678eb92807cf2253de93..7f13da9ebbc6bd8ec2de1c4319fb7ad4f10829a9 100644 (file)
--- a/arm.ld
+++ b/arm.ld
@@ -71,23 +71,23 @@ SECTIONS
   .data1   : { *(.data1) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors         :
   {
diff --git a/block.c b/block.c
index a8a013a6d2ad11c982d76c7fec9e10f535452dcc..43742b73c0bb2ad164d6683a947af564be1ed584 100644 (file)
--- a/block.c
+++ b/block.c
@@ -437,6 +437,33 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
     return 0;
 }
 
+/**
+ * Set open flags for a given cache mode
+ *
+ * Return 0 on success, -1 if the cache mode was invalid.
+ */
+int bdrv_parse_cache_flags(const char *mode, int *flags)
+{
+    *flags &= ~BDRV_O_CACHE_MASK;
+
+    if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
+        *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
+    } else if (!strcmp(mode, "directsync")) {
+        *flags |= BDRV_O_NOCACHE;
+    } else if (!strcmp(mode, "writeback")) {
+        *flags |= BDRV_O_CACHE_WB;
+    } else if (!strcmp(mode, "unsafe")) {
+        *flags |= BDRV_O_CACHE_WB;
+        *flags |= BDRV_O_NO_FLUSH;
+    } else if (!strcmp(mode, "writethrough")) {
+        /* this is the default */
+    } else {
+        return -1;
+    }
+
+    return 0;
+}
+
 /*
  * Common part for opening disk images and files
  */
@@ -1163,8 +1190,8 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
         return ret;
     }
 
-    /* No flush needed for cache=writethrough, it uses O_DSYNC */
-    if ((bs->open_flags & BDRV_O_CACHE_MASK) != 0) {
+    /* No flush needed for cache modes that use O_DSYNC */
+    if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
         bdrv_flush(bs);
     }
 
@@ -1300,7 +1327,7 @@ struct partition {
         uint8_t end_cyl;            /* end cylinder */
         uint32_t start_sect;        /* starting sector counting from 0 */
         uint32_t nr_sects;          /* nr of sectors in partition */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
 static int guess_disk_lchs(BlockDriverState *bs,
@@ -1888,11 +1915,19 @@ static void bdrv_stats_iter(QObject *data, void *opaque)
                         " wr_bytes=%" PRId64
                         " rd_operations=%" PRId64
                         " wr_operations=%" PRId64
+                        " flush_operations=%" PRId64
+                        " wr_total_time_ns=%" PRId64
+                        " rd_total_time_ns=%" PRId64
+                        " flush_total_time_ns=%" PRId64
                         "\n",
                         qdict_get_int(qdict, "rd_bytes"),
                         qdict_get_int(qdict, "wr_bytes"),
                         qdict_get_int(qdict, "rd_operations"),
-                        qdict_get_int(qdict, "wr_operations"));
+                        qdict_get_int(qdict, "wr_operations"),
+                        qdict_get_int(qdict, "flush_operations"),
+                        qdict_get_int(qdict, "wr_total_time_ns"),
+                        qdict_get_int(qdict, "rd_total_time_ns"),
+                        qdict_get_int(qdict, "flush_total_time_ns"));
 }
 
 void bdrv_stats_print(Monitor *mon, const QObject *data)
@@ -1910,12 +1945,22 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
                              "'wr_bytes': %" PRId64 ","
                              "'rd_operations': %" PRId64 ","
                              "'wr_operations': %" PRId64 ","
-                             "'wr_highest_offset': %" PRId64
+                             "'wr_highest_offset': %" PRId64 ","
+                             "'flush_operations': %" PRId64 ","
+                             "'wr_total_time_ns': %" PRId64 ","
+                             "'rd_total_time_ns': %" PRId64 ","
+                             "'flush_total_time_ns': %" PRId64
                              "} }",
-                             bs->rd_bytes, bs->wr_bytes,
-                             bs->rd_ops, bs->wr_ops,
+                             bs->nr_bytes[BDRV_ACCT_READ],
+                             bs->nr_bytes[BDRV_ACCT_WRITE],
+                             bs->nr_ops[BDRV_ACCT_READ],
+                             bs->nr_ops[BDRV_ACCT_WRITE],
                              bs->wr_highest_sector *
-                             (uint64_t)BDRV_SECTOR_SIZE);
+                             (uint64_t)BDRV_SECTOR_SIZE,
+                             bs->nr_ops[BDRV_ACCT_FLUSH],
+                             bs->total_time_ns[BDRV_ACCT_WRITE],
+                             bs->total_time_ns[BDRV_ACCT_READ],
+                             bs->total_time_ns[BDRV_ACCT_FLUSH]);
     dict  = qobject_to_qdict(res);
 
     if (*bs->device_name) {
@@ -2229,7 +2274,6 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
     return buf;
 }
 
-
 /**************************************************************/
 /* async I/Os */
 
@@ -2238,7 +2282,6 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                                  BlockDriverCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
-    BlockDriverAIOCB *ret;
 
     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
@@ -2247,16 +2290,8 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
     if (bdrv_check_request(bs, sector_num, nb_sectors))
         return NULL;
 
-    ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
-                              cb, opaque);
-
-    if (ret) {
-        /* Update stats even though technically transfer has not happened. */
-        bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
-        bs->rd_ops++;
-    }
-
-    return ret;
+    return drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
+                               cb, opaque);
 }
 
 typedef struct BlockCompleteData {
@@ -2323,9 +2358,6 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                                cb, opaque);
 
     if (ret) {
-        /* Update stats even though technically transfer has not happened. */
-        bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
-        bs->wr_ops ++;
         if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
             bs->wr_highest_sector = sector_num + nb_sectors - 1;
         }
@@ -3133,6 +3165,27 @@ int bdrv_in_use(BlockDriverState *bs)
     return bs->in_use;
 }
 
+void
+bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
+        enum BlockAcctType type)
+{
+    assert(type < BDRV_MAX_IOTYPE);
+
+    cookie->bytes = bytes;
+    cookie->start_time_ns = get_clock();
+    cookie->type = type;
+}
+
+void
+bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
+{
+    assert(cookie->type < BDRV_MAX_IOTYPE);
+
+    bs->nr_bytes[cookie->type] += cookie->bytes;
+    bs->nr_ops[cookie->type]++;
+    bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
+}
+
 int bdrv_img_create(const char *filename, const char *fmt,
                     const char *base_filename, const char *base_fmt,
                     char *options, uint64_t img_size, int flags)
diff --git a/block.h b/block.h
index a3bfaafef05ac5e98e4edbc6d9de1208cd34a33b..3ac0b944eb87236013c0f7d9480973cf70b5736a 100644 (file)
--- a/block.h
+++ b/block.h
@@ -69,6 +69,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
 BlockDriverState *bdrv_new(const char *device_name);
 void bdrv_make_anon(BlockDriverState *bs);
 void bdrv_delete(BlockDriverState *bs);
+int bdrv_parse_cache_flags(const char *mode, int *flags);
 int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
 int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
               BlockDriver *drv);
@@ -254,6 +255,23 @@ int64_t bdrv_get_dirty_count(BlockDriverState *bs);
 void bdrv_set_in_use(BlockDriverState *bs, int in_use);
 int bdrv_in_use(BlockDriverState *bs);
 
+enum BlockAcctType {
+    BDRV_ACCT_READ,
+    BDRV_ACCT_WRITE,
+    BDRV_ACCT_FLUSH,
+    BDRV_MAX_IOTYPE,
+};
+
+typedef struct BlockAcctCookie {
+    int64_t bytes;
+    int64_t start_time_ns;
+    enum BlockAcctType type;
+} BlockAcctCookie;
+
+void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
+        int64_t bytes, enum BlockAcctType type);
+void bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie);
+
 typedef enum {
     BLKDBG_L1_UPDATE,
 
@@ -306,3 +324,4 @@ typedef enum {
 void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event);
 
 #endif
+
index 5c157bc6094a23478fd7c807f836a191bb52b6c5..f3f61cc8a190a9d8ff2fbae100f47560b5420898 100644 (file)
@@ -229,6 +229,23 @@ static void curl_multi_do(void *arg)
             {
                 CURLState *state = NULL;
                 curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char**)&state);
+
+                /* ACBs for successful messages get completed in curl_read_cb */
+                if (msg->data.result != CURLE_OK) {
+                    int i;
+                    for (i = 0; i < CURL_NUM_ACB; i++) {
+                        CURLAIOCB *acb = state->acb[i];
+
+                        if (acb == NULL) {
+                            continue;
+                        }
+
+                        acb->common.cb(acb->common.opaque, -EIO);
+                        qemu_aio_release(acb);
+                        state->acb[i] = NULL;
+                    }
+                }
+
                 curl_clean_state(state);
                 break;
             }
@@ -277,7 +294,8 @@ static CURLState *curl_init_state(BDRVCURLState *s)
     curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1);
     curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1);
     curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg);
-    
+    curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1);
+
 #ifdef DEBUG_VERBOSE
     curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1);
 #endif
index 37d151dcb5f74e3bf28c457bfe65657cd7e001a8..c64103ddbb1f9d78096d054ffe3dba27ca4f928a 100644 (file)
@@ -43,7 +43,7 @@ struct parallels_header {
     uint32_t catalog_entries;
     uint32_t nb_sectors;
     char padding[24];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 typedef struct BDRVParallelsState {
 
index e155d3c002f32832f60a0ff6750c01293d187834..c8bfecc1cb3c4356c2473c15159fd9a425b23a2e 100644 (file)
@@ -159,6 +159,8 @@ static int qcow_open(BlockDriverState *bs, int flags)
             goto fail;
         bs->backing_file[len] = '\0';
     }
+
+    qemu_co_mutex_init(&s->lock);
     return 0;
 
  fail:
@@ -190,24 +192,6 @@ static int qcow_set_key(BlockDriverState *bs, const char *key)
         return -1;
     if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
         return -1;
-#if 0
-    /* test */
-    {
-        uint8_t in[16];
-        uint8_t out[16];
-        uint8_t tmp[16];
-        for(i=0;i<16;i++)
-            in[i] = i;
-        AES_encrypt(in, tmp, &s->aes_encrypt_key);
-        AES_decrypt(tmp, out, &s->aes_decrypt_key);
-        for(i = 0; i < 16; i++)
-            printf(" %02x", tmp[i]);
-        printf("\n");
-        for(i = 0; i < 16; i++)
-            printf(" %02x", out[i]);
-        printf("\n");
-    }
-#endif
     return 0;
 }
 
@@ -441,296 +425,178 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
     return 0;
 }
 
-#if 0
-
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
-                     uint8_t *buf, int nb_sectors)
+static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
+                         int nb_sectors, QEMUIOVector *qiov)
 {
     BDRVQcowState *s = bs->opaque;
-    int ret, index_in_cluster, n;
+    int index_in_cluster;
+    int ret = 0, n;
     uint64_t cluster_offset;
+    struct iovec hd_iov;
+    QEMUIOVector hd_qiov;
+    uint8_t *buf;
+    void *orig_buf;
+
+    if (qiov->niov > 1) {
+        buf = orig_buf = qemu_blockalign(bs, qiov->size);
+    } else {
+        orig_buf = NULL;
+        buf = (uint8_t *)qiov->iov->iov_base;
+    }
+
+    qemu_co_mutex_lock(&s->lock);
 
-    while (nb_sectors > 0) {
-        cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
+    while (nb_sectors != 0) {
+        /* prepare next request */
+        cluster_offset = get_cluster_offset(bs, sector_num << 9,
+                                                 0, 0, 0, 0);
         index_in_cluster = sector_num & (s->cluster_sectors - 1);
         n = s->cluster_sectors - index_in_cluster;
-        if (n > nb_sectors)
+        if (n > nb_sectors) {
             n = nb_sectors;
+        }
+
         if (!cluster_offset) {
             if (bs->backing_hd) {
                 /* read from the base image */
-                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
-                if (ret < 0)
-                    return -1;
+                hd_iov.iov_base = (void *)buf;
+                hd_iov.iov_len = n * 512;
+                qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+                qemu_co_mutex_unlock(&s->lock);
+                ret = bdrv_co_readv(bs->backing_hd, sector_num,
+                                    n, &hd_qiov);
+                qemu_co_mutex_lock(&s->lock);
+                if (ret < 0) {
+                    goto fail;
+                }
             } else {
+                /* Note: in this case, no need to wait */
                 memset(buf, 0, 512 * n);
             }
         } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
-            if (decompress_cluster(bs, cluster_offset) < 0)
-                return -1;
-            memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
+            /* add AIO support for compressed blocks ? */
+            if (decompress_cluster(bs, cluster_offset) < 0) {
+                goto fail;
+            }
+            memcpy(buf,
+                   s->cluster_cache + index_in_cluster * 512, 512 * n);
         } else {
-            ret = bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512);
-            if (ret != n * 512)
-                return -1;
+            if ((cluster_offset & 511) != 0) {
+                goto fail;
+            }
+            hd_iov.iov_base = (void *)buf;
+            hd_iov.iov_len = n * 512;
+            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+            qemu_co_mutex_unlock(&s->lock);
+            ret = bdrv_co_readv(bs->file,
+                                (cluster_offset >> 9) + index_in_cluster,
+                                n, &hd_qiov);
+            qemu_co_mutex_lock(&s->lock);
+            if (ret < 0) {
+                break;
+            }
             if (s->crypt_method) {
-                encrypt_sectors(s, sector_num, buf, buf, n, 0,
+                encrypt_sectors(s, sector_num, buf, buf,
+                                n, 0,
                                 &s->aes_decrypt_key);
             }
         }
+        ret = 0;
+
         nb_sectors -= n;
         sector_num += n;
         buf += n * 512;
     }
-    return 0;
-}
-#endif
 
-typedef struct QCowAIOCB {
-    BlockDriverAIOCB common;
-    int64_t sector_num;
-    QEMUIOVector *qiov;
-    uint8_t *buf;
-    void *orig_buf;
-    int nb_sectors;
-    int n;
-    uint64_t cluster_offset;
-    uint8_t *cluster_data;
-    struct iovec hd_iov;
-    bool is_write;
-    QEMUBH *bh;
-    QEMUIOVector hd_qiov;
-    BlockDriverAIOCB *hd_aiocb;
-} QCowAIOCB;
-
-static void qcow_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-    QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
-    if (acb->hd_aiocb)
-        bdrv_aio_cancel(acb->hd_aiocb);
-    qemu_aio_release(acb);
-}
-
-static AIOPool qcow_aio_pool = {
-    .aiocb_size         = sizeof(QCowAIOCB),
-    .cancel             = qcow_aio_cancel,
-};
-
-static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        int is_write)
-{
-    QCowAIOCB *acb;
-
-    acb = qemu_aio_get(&qcow_aio_pool, bs, NULL, NULL);
-    if (!acb)
-        return NULL;
-    acb->hd_aiocb = NULL;
-    acb->sector_num = sector_num;
-    acb->qiov = qiov;
-    acb->is_write = is_write;
+done:
+    qemu_co_mutex_unlock(&s->lock);
 
     if (qiov->niov > 1) {
-        acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
-        if (is_write)
-            qemu_iovec_to_buffer(qiov, acb->buf);
-    } else {
-        acb->buf = (uint8_t *)qiov->iov->iov_base;
+        qemu_iovec_from_buffer(qiov, orig_buf, qiov->size);
+        qemu_vfree(orig_buf);
     }
-    acb->nb_sectors = nb_sectors;
-    acb->n = 0;
-    acb->cluster_offset = 0;
-    return acb;
+
+    return ret;
+
+fail:
+    ret = -EIO;
+    goto done;
 }
 
-static int qcow_aio_read_cb(void *opaque)
+static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
+                          int nb_sectors, QEMUIOVector *qiov)
 {
-    QCowAIOCB *acb = opaque;
-    BlockDriverState *bs = acb->common.bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
-    int ret;
+    uint64_t cluster_offset;
+    const uint8_t *src_buf;
+    int ret = 0, n;
+    uint8_t *cluster_data = NULL;
+    struct iovec hd_iov;
+    QEMUIOVector hd_qiov;
+    uint8_t *buf;
+    void *orig_buf;
 
-    acb->hd_aiocb = NULL;
+    s->cluster_cache_offset = -1; /* disable compressed cache */
 
- redo:
-    /* post process the read buffer */
-    if (!acb->cluster_offset) {
-        /* nothing to do */
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* nothing to do */
+    if (qiov->niov > 1) {
+        buf = orig_buf = qemu_blockalign(bs, qiov->size);
+        qemu_iovec_to_buffer(qiov, buf);
     } else {
-        if (s->crypt_method) {
-            encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
-                            acb->n, 0,
-                            &s->aes_decrypt_key);
-        }
+        orig_buf = NULL;
+        buf = (uint8_t *)qiov->iov->iov_base;
     }
 
-    acb->nb_sectors -= acb->n;
-    acb->sector_num += acb->n;
-    acb->buf += acb->n * 512;
+    qemu_co_mutex_lock(&s->lock);
 
-    if (acb->nb_sectors == 0) {
-        /* request completed */
-        return 0;
-    }
+    while (nb_sectors != 0) {
 
-    /* prepare next AIO request */
-    acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
-                                             0, 0, 0, 0);
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    acb->n = s->cluster_sectors - index_in_cluster;
-    if (acb->n > acb->nb_sectors)
-        acb->n = acb->nb_sectors;
-
-    if (!acb->cluster_offset) {
-        if (bs->backing_hd) {
-            /* read from the base image */
-            acb->hd_iov.iov_base = (void *)acb->buf;
-            acb->hd_iov.iov_len = acb->n * 512;
-            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-            qemu_co_mutex_unlock(&s->lock);
-            ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
-                                acb->n, &acb->hd_qiov);
-            qemu_co_mutex_lock(&s->lock);
-            if (ret < 0) {
-                return -EIO;
-            }
-        } else {
-            /* Note: in this case, no need to wait */
-            memset(acb->buf, 0, 512 * acb->n);
-            goto redo;
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        n = s->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors) {
+            n = nb_sectors;
         }
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* add AIO support for compressed blocks ? */
-        if (decompress_cluster(bs, acb->cluster_offset) < 0) {
-            return -EIO;
+        cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
+                                            index_in_cluster,
+                                            index_in_cluster + n);
+        if (!cluster_offset || (cluster_offset & 511) != 0) {
+            ret = -EIO;
+            break;
         }
-        memcpy(acb->buf,
-               s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
-        goto redo;
-    } else {
-        if ((acb->cluster_offset & 511) != 0) {
-            return -EIO;
+        if (s->crypt_method) {
+            if (!cluster_data) {
+                cluster_data = g_malloc0(s->cluster_size);
+            }
+            encrypt_sectors(s, sector_num, cluster_data, buf,
+                            n, 1, &s->aes_encrypt_key);
+            src_buf = cluster_data;
+        } else {
+            src_buf = buf;
         }
-        acb->hd_iov.iov_base = (void *)acb->buf;
-        acb->hd_iov.iov_len = acb->n * 512;
-        qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+
+        hd_iov.iov_base = (void *)src_buf;
+        hd_iov.iov_len = n * 512;
+        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
         qemu_co_mutex_unlock(&s->lock);
-        ret = bdrv_co_readv(bs->file,
-                            (acb->cluster_offset >> 9) + index_in_cluster,
-                            acb->n, &acb->hd_qiov);
+        ret = bdrv_co_writev(bs->file,
+                             (cluster_offset >> 9) + index_in_cluster,
+                             n, &hd_qiov);
         qemu_co_mutex_lock(&s->lock);
         if (ret < 0) {
-            return ret;
+            break;
         }
-    }
-
-    return 1;
-}
-
-static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
-                         int nb_sectors, QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
-    int ret;
-
-    acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0);
-
-    qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow_aio_read_cb(acb);
-    } while (ret > 0);
-    qemu_co_mutex_unlock(&s->lock);
+        ret = 0;
 
-    if (acb->qiov->niov > 1) {
-        qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
-        qemu_vfree(acb->orig_buf);
-    }
-    qemu_aio_release(acb);
-
-    return ret;
-}
-
-static int qcow_aio_write_cb(void *opaque)
-{
-    QCowAIOCB *acb = opaque;
-    BlockDriverState *bs = acb->common.bs;
-    BDRVQcowState *s = bs->opaque;
-    int index_in_cluster;
-    uint64_t cluster_offset;
-    const uint8_t *src_buf;
-    int ret;
-
-    acb->hd_aiocb = NULL;
-
-    acb->nb_sectors -= acb->n;
-    acb->sector_num += acb->n;
-    acb->buf += acb->n * 512;
-
-    if (acb->nb_sectors == 0) {
-        /* request completed */
-        return 0;
-    }
-
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    acb->n = s->cluster_sectors - index_in_cluster;
-    if (acb->n > acb->nb_sectors)
-        acb->n = acb->nb_sectors;
-    cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
-                                        index_in_cluster,
-                                        index_in_cluster + acb->n);
-    if (!cluster_offset || (cluster_offset & 511) != 0) {
-        return -EIO;
-    }
-    if (s->crypt_method) {
-        if (!acb->cluster_data) {
-            acb->cluster_data = g_malloc0(s->cluster_size);
-        }
-        encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
-                        acb->n, 1, &s->aes_encrypt_key);
-        src_buf = acb->cluster_data;
-    } else {
-        src_buf = acb->buf;
-    }
-
-    acb->hd_iov.iov_base = (void *)src_buf;
-    acb->hd_iov.iov_len = acb->n * 512;
-    qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-    qemu_co_mutex_unlock(&s->lock);
-    ret = bdrv_co_writev(bs->file,
-                         (cluster_offset >> 9) + index_in_cluster,
-                         acb->n, &acb->hd_qiov);
-    qemu_co_mutex_lock(&s->lock);
-    if (ret < 0) {
-        return ret;
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
     }
-    return 1;
-}
-
-static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
-                          int nb_sectors, QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
-    int ret;
-
-    s->cluster_cache_offset = -1; /* disable compressed cache */
-
-    acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1);
-
-    qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow_aio_write_cb(acb);
-    } while (ret > 0);
     qemu_co_mutex_unlock(&s->lock);
 
-    if (acb->qiov->niov > 1) {
-        qemu_vfree(acb->orig_buf);
+    if (qiov->niov > 1) {
+        qemu_vfree(orig_buf);
     }
-    qemu_aio_release(acb);
+    free(cluster_data);
 
     return ret;
 }
index 9269ddaefd2dde4c5e6be38baa9cab12a7c083bb..e06be648766c31ceef5a717f3642a302106138ce 100644 (file)
@@ -53,7 +53,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
     }
 
 #ifdef DEBUG_ALLOC2
-    printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
+    fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
 #endif
 
     new_l1_size2 = sizeof(uint64_t) * new_l1_size;
@@ -381,10 +381,10 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
  * For a given offset of the disk image, find the cluster offset in
  * qcow2 file. The offset is stored in *cluster_offset.
  *
- * on entry, *num is the number of contiguous clusters we'd like to
+ * on entry, *num is the number of contiguous sectors we'd like to
  * access following offset.
  *
- * on exit, *num is the number of contiguous clusters we can read.
+ * on exit, *num is the number of contiguous sectors we can read.
  *
  * Return 0, if the offset is found
  * Return -errno, otherwise.
index 2a915be57a9907f6bb85a6de5833b0bd102c46d5..9605367777bd6e856bb139e8e9a1c205d68de3b1 100644 (file)
@@ -422,7 +422,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
     int ret;
 
 #ifdef DEBUG_ALLOC2
-    printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
+    fprintf(stderr, "update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
            offset, length, addend);
 #endif
     if (length < 0) {
@@ -556,7 +556,7 @@ retry:
         }
     }
 #ifdef DEBUG_ALLOC2
-    printf("alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
+    fprintf(stderr, "alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
             size,
             (s->free_cluster_index - nb_clusters) << s->cluster_bits);
 #endif
@@ -680,24 +680,6 @@ void qcow2_free_any_clusters(BlockDriverState *bs,
 
 
 
-void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
-    int64_t size)
-{
-    int refcount;
-    int64_t start, last, cluster_offset;
-    uint16_t *p;
-
-    start = offset & ~(s->cluster_size - 1);
-    last = (offset + size - 1)  & ~(s->cluster_size - 1);
-    for(cluster_offset = start; cluster_offset <= last;
-        cluster_offset += s->cluster_size) {
-        p = &s->refcount_block[cluster_offset >> s->cluster_bits];
-        refcount = be16_to_cpu(*p);
-        refcount++;
-        *p = cpu_to_be16(refcount);
-    }
-}
-
 /* update the refcounts of snapshots and the copied flag */
 int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     int64_t l1_table_offset, int l1_size, int addend)
index 3bd2a30d35ca50c41713ebf7d24ac47dfdec1cb7..bdc33ba94c3f31535f698b85cf33b81aa8c32f8e 100644 (file)
@@ -26,7 +26,7 @@
 #include "block_int.h"
 #include "block/qcow2.h"
 
-typedef struct __attribute__((packed)) QCowSnapshotHeader {
+typedef struct QEMU_PACKED QCowSnapshotHeader {
     /* header is 8 byte aligned */
     uint64_t l1_table_offset;
 
@@ -303,7 +303,10 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     if (qcow2_write_snapshots(bs) < 0)
         goto fail;
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+      BdrvCheckResult result = {0};
+      qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return 0;
  fail:
@@ -353,7 +356,10 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto fail;
 
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+        BdrvCheckResult result = {0};
+        qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return 0;
  fail:
@@ -390,7 +396,10 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
         return ret;
     }
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+        BdrvCheckResult result = {0};
+        qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return 0;
 }
index bfff6cd9630f54d1def691b3c3a6fbc06a6b9720..b725d68b1dc867764249e4b1384b58573e435e73 100644 (file)
@@ -87,6 +87,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
     while (offset < end_offset) {
 
 #ifdef DEBUG_EXT
+        BDRVQcowState *s = bs->opaque;
         /* Sanity check */
         if (offset > s->cluster_size)
             printf("qcow2_read_extension: suspicious offset %lu\n", offset);
@@ -280,7 +281,10 @@ static int qcow2_open(BlockDriverState *bs, int flags)
     qemu_co_mutex_init(&s->lock);
 
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+        BdrvCheckResult result = {0};
+        qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return ret;
 
@@ -372,201 +376,127 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
     return n1;
 }
 
-typedef struct QCowAIOCB {
-    BlockDriverAIOCB common;
-    int64_t sector_num;
-    QEMUIOVector *qiov;
-    int remaining_sectors;
-    int cur_nr_sectors;        /* number of sectors in current iteration */
-    uint64_t bytes_done;
-    uint64_t cluster_offset;
-    uint8_t *cluster_data;
-    bool is_write;
-    QEMUIOVector hd_qiov;
-    QEMUBH *bh;
-    QCowL2Meta l2meta;
-    QLIST_ENTRY(QCowAIOCB) next_depend;
-} QCowAIOCB;
-
-static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-    QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
-    qemu_aio_release(acb);
-}
-
-static AIOPool qcow2_aio_pool = {
-    .aiocb_size         = sizeof(QCowAIOCB),
-    .cancel             = qcow2_aio_cancel,
-};
-
-/*
- * Returns 0 when the request is completed successfully, 1 when there is still
- * a part left to do and -errno in error cases.
- */
-static int qcow2_aio_read_cb(QCowAIOCB *acb)
+static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
+                          int remaining_sectors, QEMUIOVector *qiov)
 {
-    BlockDriverState *bs = acb->common.bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster, n1;
     int ret;
+    int cur_nr_sectors; /* number of sectors in current iteration */
+    uint64_t cluster_offset = 0;
+    uint64_t bytes_done = 0;
+    QEMUIOVector hd_qiov;
+    uint8_t *cluster_data = NULL;
 
-    /* post process the read buffer */
-    if (!acb->cluster_offset) {
-        /* nothing to do */
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* nothing to do */
-    } else {
-        if (s->crypt_method) {
-            qcow2_encrypt_sectors(s, acb->sector_num,  acb->cluster_data,
-                acb->cluster_data, acb->cur_nr_sectors, 0, &s->aes_decrypt_key);
-            qemu_iovec_reset(&acb->hd_qiov);
-            qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-                acb->cur_nr_sectors * 512);
-            qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data,
-                512 * acb->cur_nr_sectors);
-        }
-    }
+    qemu_iovec_init(&hd_qiov, qiov->niov);
 
-    acb->remaining_sectors -= acb->cur_nr_sectors;
-    acb->sector_num += acb->cur_nr_sectors;
-    acb->bytes_done += acb->cur_nr_sectors * 512;
+    qemu_co_mutex_lock(&s->lock);
 
-    if (acb->remaining_sectors == 0) {
-        /* request completed */
-        return 0;
-    }
+    while (remaining_sectors != 0) {
 
-    /* prepare next AIO request */
-    acb->cur_nr_sectors = acb->remaining_sectors;
-    if (s->crypt_method) {
-        acb->cur_nr_sectors = MIN(acb->cur_nr_sectors,
-            QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
-    }
+        /* prepare next request */
+        cur_nr_sectors = remaining_sectors;
+        if (s->crypt_method) {
+            cur_nr_sectors = MIN(cur_nr_sectors,
+                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
+        }
 
-    ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
-        &acb->cur_nr_sectors, &acb->cluster_offset);
-    if (ret < 0) {
-        return ret;
-    }
+        ret = qcow2_get_cluster_offset(bs, sector_num << 9,
+            &cur_nr_sectors, &cluster_offset);
+        if (ret < 0) {
+            goto fail;
+        }
 
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-
-    qemu_iovec_reset(&acb->hd_qiov);
-    qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-        acb->cur_nr_sectors * 512);
-
-    if (!acb->cluster_offset) {
-
-        if (bs->backing_hd) {
-            /* read from the base image */
-            n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov,
-                acb->sector_num, acb->cur_nr_sectors);
-            if (n1 > 0) {
-                BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
-                qemu_co_mutex_unlock(&s->lock);
-                ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
-                                    n1, &acb->hd_qiov);
-                qemu_co_mutex_lock(&s->lock);
-                if (ret < 0) {
-                    return ret;
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+
+        qemu_iovec_reset(&hd_qiov);
+        qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
+            cur_nr_sectors * 512);
+
+        if (!cluster_offset) {
+
+            if (bs->backing_hd) {
+                /* read from the base image */
+                n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,
+                    sector_num, cur_nr_sectors);
+                if (n1 > 0) {
+                    BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
+                    qemu_co_mutex_unlock(&s->lock);
+                    ret = bdrv_co_readv(bs->backing_hd, sector_num,
+                                        n1, &hd_qiov);
+                    qemu_co_mutex_lock(&s->lock);
+                    if (ret < 0) {
+                        goto fail;
+                    }
                 }
+            } else {
+                /* Note: in this case, no need to wait */
+                qemu_iovec_memset(&hd_qiov, 0, 512 * cur_nr_sectors);
+            }
+        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+            /* add AIO support for compressed blocks ? */
+            ret = qcow2_decompress_cluster(bs, cluster_offset);
+            if (ret < 0) {
+                goto fail;
             }
-            return 1;
-        } else {
-            /* Note: in this case, no need to wait */
-            qemu_iovec_memset(&acb->hd_qiov, 0, 512 * acb->cur_nr_sectors);
-            return 1;
-        }
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* add AIO support for compressed blocks ? */
-        ret = qcow2_decompress_cluster(bs, acb->cluster_offset);
-        if (ret < 0) {
-            return ret;
-        }
 
-        qemu_iovec_from_buffer(&acb->hd_qiov,
-            s->cluster_cache + index_in_cluster * 512,
-            512 * acb->cur_nr_sectors);
+            qemu_iovec_from_buffer(&hd_qiov,
+                s->cluster_cache + index_in_cluster * 512,
+                512 * cur_nr_sectors);
+        } else {
+            if ((cluster_offset & 511) != 0) {
+                ret = -EIO;
+                goto fail;
+            }
 
-        return 1;
-    } else {
-        if ((acb->cluster_offset & 511) != 0) {
-            return -EIO;
-        }
+            if (s->crypt_method) {
+                /*
+                 * For encrypted images, read everything into a temporary
+                 * contiguous buffer on which the AES functions can work.
+                 */
+                if (!cluster_data) {
+                    cluster_data =
+                        g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+                }
 
-        if (s->crypt_method) {
-            /*
-             * For encrypted images, read everything into a temporary
-             * contiguous buffer on which the AES functions can work.
-             */
-            if (!acb->cluster_data) {
-                acb->cluster_data =
-                    g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+                assert(cur_nr_sectors <=
+                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
+                qemu_iovec_reset(&hd_qiov);
+                qemu_iovec_add(&hd_qiov, cluster_data,
+                    512 * cur_nr_sectors);
             }
 
-            assert(acb->cur_nr_sectors <=
-                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
-            qemu_iovec_reset(&acb->hd_qiov);
-            qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
-                512 * acb->cur_nr_sectors);
+            BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
+            qemu_co_mutex_unlock(&s->lock);
+            ret = bdrv_co_readv(bs->file,
+                                (cluster_offset >> 9) + index_in_cluster,
+                                cur_nr_sectors, &hd_qiov);
+            qemu_co_mutex_lock(&s->lock);
+            if (ret < 0) {
+                goto fail;
+            }
+            if (s->crypt_method) {
+                qcow2_encrypt_sectors(s, sector_num,  cluster_data,
+                    cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
+                qemu_iovec_reset(&hd_qiov);
+                qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
+                    cur_nr_sectors * 512);
+                qemu_iovec_from_buffer(&hd_qiov, cluster_data,
+                    512 * cur_nr_sectors);
+            }
         }
 
-        BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
-        qemu_co_mutex_unlock(&s->lock);
-        ret = bdrv_co_readv(bs->file,
-                            (acb->cluster_offset >> 9) + index_in_cluster,
-                            acb->cur_nr_sectors, &acb->hd_qiov);
-        qemu_co_mutex_lock(&s->lock);
-        if (ret < 0) {
-            return ret;
-        }
+        remaining_sectors -= cur_nr_sectors;
+        sector_num += cur_nr_sectors;
+        bytes_done += cur_nr_sectors * 512;
     }
+    ret = 0;
 
-    return 1;
-}
-
-static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
-                                  QEMUIOVector *qiov, int nb_sectors,
-                                  BlockDriverCompletionFunc *cb,
-                                  void *opaque, int is_write)
-{
-    QCowAIOCB *acb;
-
-    acb = qemu_aio_get(&qcow2_aio_pool, bs, cb, opaque);
-    if (!acb)
-        return NULL;
-    acb->sector_num = sector_num;
-    acb->qiov = qiov;
-    acb->is_write = is_write;
-
-    qemu_iovec_init(&acb->hd_qiov, qiov->niov);
-
-    acb->bytes_done = 0;
-    acb->remaining_sectors = nb_sectors;
-    acb->cur_nr_sectors = 0;
-    acb->cluster_offset = 0;
-    acb->l2meta.nb_clusters = 0;
-    qemu_co_queue_init(&acb->l2meta.dependent_requests);
-    return acb;
-}
-
-static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
-                          int nb_sectors, QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
-    int ret;
-
-    acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0);
-
-    qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow2_aio_read_cb(acb);
-    } while (ret > 0);
+fail:
     qemu_co_mutex_unlock(&s->lock);
 
-    qemu_iovec_destroy(&acb->hd_qiov);
-    qemu_aio_release(acb);
+    qemu_iovec_destroy(&hd_qiov);
+    g_free(cluster_data);
 
     return ret;
 }
@@ -586,104 +516,100 @@ static void run_dependent_requests(BDRVQcowState *s, QCowL2Meta *m)
     }
 }
 
-/*
- * Returns 0 when the request is completed successfully, 1 when there is still
- * a part left to do and -errno in error cases.
- */
-static int qcow2_aio_write_cb(QCowAIOCB *acb)
+static int qcow2_co_writev(BlockDriverState *bs,
+                           int64_t sector_num,
+                           int remaining_sectors,
+                           QEMUIOVector *qiov)
 {
-    BlockDriverState *bs = acb->common.bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
     int n_end;
     int ret;
+    int cur_nr_sectors; /* number of sectors in current iteration */
+    QCowL2Meta l2meta;
+    uint64_t cluster_offset;
+    QEMUIOVector hd_qiov;
+    uint64_t bytes_done = 0;
+    uint8_t *cluster_data = NULL;
 
-    ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta);
+    l2meta.nb_clusters = 0;
+    qemu_co_queue_init(&l2meta.dependent_requests);
 
-    run_dependent_requests(s, &acb->l2meta);
+    qemu_iovec_init(&hd_qiov, qiov->niov);
 
-    if (ret < 0) {
-        return ret;
-    }
+    s->cluster_cache_offset = -1; /* disable compressed cache */
 
-    acb->remaining_sectors -= acb->cur_nr_sectors;
-    acb->sector_num += acb->cur_nr_sectors;
-    acb->bytes_done += acb->cur_nr_sectors * 512;
+    qemu_co_mutex_lock(&s->lock);
 
-    if (acb->remaining_sectors == 0) {
-        /* request completed */
-        return 0;
-    }
+    while (remaining_sectors != 0) {
 
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    n_end = index_in_cluster + acb->remaining_sectors;
-    if (s->crypt_method &&
-        n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
-        n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        n_end = index_in_cluster + remaining_sectors;
+        if (s->crypt_method &&
+            n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) {
+            n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
+        }
 
-    ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
-        index_in_cluster, n_end, &acb->cur_nr_sectors, &acb->l2meta);
-    if (ret < 0) {
-        return ret;
-    }
+        ret = qcow2_alloc_cluster_offset(bs, sector_num << 9,
+            index_in_cluster, n_end, &cur_nr_sectors, &l2meta);
+        if (ret < 0) {
+            goto fail;
+        }
 
-    acb->cluster_offset = acb->l2meta.cluster_offset;
-    assert((acb->cluster_offset & 511) == 0);
+        cluster_offset = l2meta.cluster_offset;
+        assert((cluster_offset & 511) == 0);
 
-    qemu_iovec_reset(&acb->hd_qiov);
-    qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-        acb->cur_nr_sectors * 512);
+        qemu_iovec_reset(&hd_qiov);
+        qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
+            cur_nr_sectors * 512);
 
-    if (s->crypt_method) {
-        if (!acb->cluster_data) {
-            acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS *
-                                             s->cluster_size);
-        }
+        if (s->crypt_method) {
+            if (!cluster_data) {
+                cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS *
+                                                 s->cluster_size);
+            }
 
-        assert(acb->hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
-        qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data);
+            assert(hd_qiov.size <=
+                   QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+            qemu_iovec_to_buffer(&hd_qiov, cluster_data);
 
-        qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
-            acb->cluster_data, acb->cur_nr_sectors, 1, &s->aes_encrypt_key);
+            qcow2_encrypt_sectors(s, sector_num, cluster_data,
+                cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
 
-        qemu_iovec_reset(&acb->hd_qiov);
-        qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
-            acb->cur_nr_sectors * 512);
-    }
+            qemu_iovec_reset(&hd_qiov);
+            qemu_iovec_add(&hd_qiov, cluster_data,
+                cur_nr_sectors * 512);
+        }
 
-    BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
-    qemu_co_mutex_unlock(&s->lock);
-    ret = bdrv_co_writev(bs->file,
-                         (acb->cluster_offset >> 9) + index_in_cluster,
-                         acb->cur_nr_sectors, &acb->hd_qiov);
-    qemu_co_mutex_lock(&s->lock);
-    if (ret < 0) {
-        return ret;
-    }
+        BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
+        qemu_co_mutex_unlock(&s->lock);
+        ret = bdrv_co_writev(bs->file,
+                             (cluster_offset >> 9) + index_in_cluster,
+                             cur_nr_sectors, &hd_qiov);
+        qemu_co_mutex_lock(&s->lock);
+        if (ret < 0) {
+            goto fail;
+        }
 
-    return 1;
-}
+        ret = qcow2_alloc_cluster_link_l2(bs, &l2meta);
 
-static int qcow2_co_writev(BlockDriverState *bs,
-                           int64_t sector_num,
-                           int nb_sectors,
-                           QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
-    int ret;
+        run_dependent_requests(s, &l2meta);
 
-    acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1);
-    s->cluster_cache_offset = -1; /* disable compressed cache */
+        if (ret < 0) {
+            goto fail;
+        }
 
-    qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow2_aio_write_cb(acb);
-    } while (ret > 0);
+        remaining_sectors -= cur_nr_sectors;
+        sector_num += cur_nr_sectors;
+        bytes_done += cur_nr_sectors * 512;
+    }
+    ret = 0;
+
+fail:
     qemu_co_mutex_unlock(&s->lock);
 
-    qemu_iovec_destroy(&acb->hd_qiov);
-    qemu_aio_release(acb);
+    qemu_iovec_destroy(&hd_qiov);
+    g_free(cluster_data);
 
     return ret;
 }
index de23abe1a4991ad406536d12fa2f37f11e137735..c8ca3bc574b44dff78b71e649769abad6addf9b3 100644 (file)
@@ -189,8 +189,6 @@ void qcow2_free_clusters(BlockDriverState *bs,
 void qcow2_free_any_clusters(BlockDriverState *bs,
     uint64_t cluster_offset, int nb_clusters);
 
-void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
-    int64_t size);
 int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     int64_t l1_table_offset, int l1_size, int addend);
 
index 57b6e1aad7d77a1ad0d97c4eb28c2630d8ed3dee..c1f6e07ec163fbfc9784f386c2774ef2c57658bb 100644 (file)
@@ -274,7 +274,7 @@ struct SheepdogAIOCB {
     int ret;
     enum AIOCBState aiocb_type;
 
-    QEMUBH *bh;
+    Coroutine *coroutine;
     void (*aio_done_func)(SheepdogAIOCB *);
 
     int canceled;
@@ -295,6 +295,10 @@ typedef struct BDRVSheepdogState {
     char *port;
     int fd;
 
+    CoMutex lock;
+    Coroutine *co_send;
+    Coroutine *co_recv;
+
     uint32_t aioreq_seq_num;
     QLIST_HEAD(outstanding_aio_head, AIOReq) outstanding_aio_head;
 } BDRVSheepdogState;
@@ -346,19 +350,16 @@ static const char * sd_strerror(int err)
 /*
  * Sheepdog I/O handling:
  *
- * 1. In the sd_aio_readv/writev, read/write requests are added to the
- *    QEMU Bottom Halves.
- *
- * 2. In sd_readv_writev_bh_cb, the callbacks of BHs, we send the I/O
- *    requests to the server and link the requests to the
- *    outstanding_list in the BDRVSheepdogState.  we exits the
- *    function without waiting for receiving the response.
+ * 1. In sd_co_rw_vector, we send the I/O requests to the server and
+ *    link the requests to the outstanding_list in the
+ *    BDRVSheepdogState.  The function exits without waiting for
+ *    receiving the response.
  *
- * 3. We receive the response in aio_read_response, the fd handler to
+ * 2. We receive the response in aio_read_response, the fd handler to
  *    the sheepdog connection.  If metadata update is needed, we send
  *    the write request to the vdi object in sd_write_done, the write
- *    completion function.  The AIOCB callback is not called until all
- *    the requests belonging to the AIOCB are finished.
+ *    completion function.  We switch back to sd_co_readv/writev after
+ *    all the requests belonging to the AIOCB are finished.
  */
 
 static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
@@ -398,7 +399,7 @@ static inline int free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
 static void sd_finish_aiocb(SheepdogAIOCB *acb)
 {
     if (!acb->canceled) {
-        acb->common.cb(acb->common.opaque, acb->ret);
+        qemu_coroutine_enter(acb->coroutine, NULL);
     }
     qemu_aio_release(acb);
 }
@@ -411,7 +412,8 @@ static void sd_aio_cancel(BlockDriverAIOCB *blockacb)
      * Sheepdog cannot cancel the requests which are already sent to
      * the servers, so we just complete the request with -EIO here.
      */
-    acb->common.cb(acb->common.opaque, -EIO);
+    acb->ret = -EIO;
+    qemu_coroutine_enter(acb->coroutine, NULL);
     acb->canceled = 1;
 }
 
@@ -435,24 +437,12 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
 
     acb->aio_done_func = NULL;
     acb->canceled = 0;
-    acb->bh = NULL;
+    acb->coroutine = qemu_coroutine_self();
     acb->ret = 0;
     QLIST_INIT(&acb->aioreq_head);
     return acb;
 }
 
-static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb)
-{
-    if (acb->bh) {
-        error_report("bug: %d %d", acb->aiocb_type, acb->aiocb_type);
-        return -EIO;
-    }
-
-    acb->bh = qemu_bh_new(cb, acb);
-    qemu_bh_schedule(acb->bh);
-    return 0;
-}
-
 #ifdef _WIN32
 
 struct msghdr {
@@ -635,7 +625,13 @@ static int do_readv_writev(int sockfd, struct iovec *iov, int len,
 again:
     ret = do_send_recv(sockfd, iov, len, iov_offset, write);
     if (ret < 0) {
-        if (errno == EINTR || errno == EAGAIN) {
+        if (errno == EINTR) {
+            goto again;
+        }
+        if (errno == EAGAIN) {
+            if (qemu_in_coroutine()) {
+                qemu_coroutine_yield();
+            }
             goto again;
         }
         error_report("failed to recv a rsp, %s", strerror(errno));
@@ -793,14 +789,14 @@ static void aio_read_response(void *opaque)
     unsigned long idx;
 
     if (QLIST_EMPTY(&s->outstanding_aio_head)) {
-        return;
+        goto out;
     }
 
     /* read a header */
     ret = do_read(fd, &rsp, sizeof(rsp));
     if (ret) {
         error_report("failed to get the header, %s", strerror(errno));
-        return;
+        goto out;
     }
 
     /* find the right aio_req from the outstanding_aio list */
@@ -811,7 +807,7 @@ static void aio_read_response(void *opaque)
     }
     if (!aio_req) {
         error_report("cannot find aio_req %x", rsp.id);
-        return;
+        goto out;
     }
 
     acb = aio_req->aiocb;
@@ -847,7 +843,7 @@ static void aio_read_response(void *opaque)
                        aio_req->iov_offset);
         if (ret) {
             error_report("failed to get the data, %s", strerror(errno));
-            return;
+            goto out;
         }
         break;
     }
@@ -861,10 +857,30 @@ static void aio_read_response(void *opaque)
     if (!rest) {
         /*
          * We've finished all requests which belong to the AIOCB, so
-         * we can call the callback now.
+         * we can switch back to sd_co_readv/writev now.
          */
         acb->aio_done_func(acb);
     }
+out:
+    s->co_recv = NULL;
+}
+
+static void co_read_response(void *opaque)
+{
+    BDRVSheepdogState *s = opaque;
+
+    if (!s->co_recv) {
+        s->co_recv = qemu_coroutine_create(aio_read_response);
+    }
+
+    qemu_coroutine_enter(s->co_recv, opaque);
+}
+
+static void co_write_request(void *opaque)
+{
+    BDRVSheepdogState *s = opaque;
+
+    qemu_coroutine_enter(s->co_send, NULL);
 }
 
 static int aio_flush_request(void *opaque)
@@ -924,7 +940,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
         return -1;
     }
 
-    qemu_aio_set_fd_handler(fd, aio_read_response, NULL, aio_flush_request,
+    qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request,
                             NULL, s);
     return fd;
 }
@@ -1091,6 +1107,10 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 
     hdr.id = aio_req->id;
 
+    qemu_co_mutex_lock(&s->lock);
+    s->co_send = qemu_coroutine_self();
+    qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,
+                            aio_flush_request, NULL, s);
     set_cork(s->fd, 1);
 
     /* send a header */
@@ -1109,6 +1129,9 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
     }
 
     set_cork(s->fd, 0);
+    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
+                            aio_flush_request, NULL, s);
+    qemu_co_mutex_unlock(&s->lock);
 
     return 0;
 }
@@ -1225,6 +1248,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 
     bs->total_sectors = s->inode.vdi_size / SECTOR_SIZE;
     strncpy(s->name, vdi, sizeof(s->name));
+    qemu_co_mutex_init(&s->lock);
     g_free(buf);
     return 0;
 out:
@@ -1491,7 +1515,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
 /*
  * This function is called after writing data objects.  If we need to
  * update metadata, this sends a write request to the vdi object.
- * Otherwise, this calls the AIOCB callback.
+ * Otherwise, this switches back to sd_co_readv/writev.
  */
 static void sd_write_done(SheepdogAIOCB *acb)
 {
@@ -1587,8 +1611,11 @@ out:
  * waiting the response.  The responses are received in the
  * `aio_read_response' function which is called from the main loop as
  * a fd handler.
+ *
+ * Returns 1 when we need to wait a response, 0 when there is no sent
+ * request and -errno in error cases.
  */
-static void sd_readv_writev_bh_cb(void *p)
+static int sd_co_rw_vector(void *p)
 {
     SheepdogAIOCB *acb = p;
     int ret = 0;
@@ -1600,9 +1627,6 @@ static void sd_readv_writev_bh_cb(void *p)
     SheepdogInode *inode = &s->inode;
     AIOReq *aio_req;
 
-    qemu_bh_delete(acb->bh);
-    acb->bh = NULL;
-
     if (acb->aiocb_type == AIOCB_WRITE_UDATA && s->is_snapshot) {
         /*
          * In the case we open the snapshot VDI, Sheepdog creates the
@@ -1684,42 +1708,47 @@ static void sd_readv_writev_bh_cb(void *p)
     }
 out:
     if (QLIST_EMPTY(&acb->aioreq_head)) {
-        sd_finish_aiocb(acb);
+        return acb->ret;
     }
+    return 1;
 }
 
-static BlockDriverAIOCB *sd_aio_writev(BlockDriverState *bs, int64_t sector_num,
-                                       QEMUIOVector *qiov, int nb_sectors,
-                                       BlockDriverCompletionFunc *cb,
-                                       void *opaque)
+static int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
+                        int nb_sectors, QEMUIOVector *qiov)
 {
     SheepdogAIOCB *acb;
+    int ret;
 
     if (bs->growable && sector_num + nb_sectors > bs->total_sectors) {
         /* TODO: shouldn't block here */
         if (sd_truncate(bs, (sector_num + nb_sectors) * SECTOR_SIZE) < 0) {
-            return NULL;
+            return -EIO;
         }
         bs->total_sectors = sector_num + nb_sectors;
     }
 
-    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, cb, opaque);
+    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
     acb->aio_done_func = sd_write_done;
     acb->aiocb_type = AIOCB_WRITE_UDATA;
 
-    sd_schedule_bh(sd_readv_writev_bh_cb, acb);
-    return &acb->common;
+    ret = sd_co_rw_vector(acb);
+    if (ret <= 0) {
+        qemu_aio_release(acb);
+        return ret;
+    }
+
+    qemu_coroutine_yield();
+
+    return acb->ret;
 }
 
-static BlockDriverAIOCB *sd_aio_readv(BlockDriverState *bs, int64_t sector_num,
-                                      QEMUIOVector *qiov, int nb_sectors,
-                                      BlockDriverCompletionFunc *cb,
-                                      void *opaque)
+static int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
+                       int nb_sectors, QEMUIOVector *qiov)
 {
     SheepdogAIOCB *acb;
-    int i;
+    int i, ret;
 
-    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, cb, opaque);
+    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
     acb->aiocb_type = AIOCB_READ_UDATA;
     acb->aio_done_func = sd_finish_aiocb;
 
@@ -1731,8 +1760,15 @@ static BlockDriverAIOCB *sd_aio_readv(BlockDriverState *bs, int64_t sector_num,
         memset(qiov->iov[i].iov_base, 0, qiov->iov[i].iov_len);
     }
 
-    sd_schedule_bh(sd_readv_writev_bh_cb, acb);
-    return &acb->common;
+    ret = sd_co_rw_vector(acb);
+    if (ret <= 0) {
+        qemu_aio_release(acb);
+        return ret;
+    }
+
+    qemu_coroutine_yield();
+
+    return acb->ret;
 }
 
 static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
@@ -2062,8 +2098,8 @@ BlockDriver bdrv_sheepdog = {
     .bdrv_getlength = sd_getlength,
     .bdrv_truncate  = sd_truncate,
 
-    .bdrv_aio_readv     = sd_aio_readv,
-    .bdrv_aio_writev    = sd_aio_writev,
+    .bdrv_co_readv  = sd_co_readv,
+    .bdrv_co_writev = sd_co_writev,
 
     .bdrv_snapshot_create   = sd_snapshot_create,
     .bdrv_snapshot_goto     = sd_snapshot_goto,
index 8da87acef05148e751e034f7d464c4799efa6f36..5f673e9e258bb45713c90418001f284cd79458a3 100644 (file)
@@ -56,7 +56,7 @@ typedef struct {
     int64_t grain_offset;
     char filler[1];
     char check_bytes[4];
-} __attribute__((packed)) VMDK4Header;
+} QEMU_PACKED VMDK4Header;
 
 #define L2_CACHE_SIZE 16
 
index d6a07efcc9ec2174576150f1c6ff6002400e2915..187ac96f25b1a63fe51102e227f2f8b74ab127a9 100644 (file)
@@ -200,7 +200,7 @@ static int array_index(array_t* array, void* pointer)
 }
 
 /* These structures are used to fake a disk and the VFAT filesystem.
- * For this reason we need to use __attribute__((packed)). */
+ * For this reason we need to use QEMU_PACKED. */
 
 typedef struct bootsector_t {
     uint8_t jump[3];
@@ -224,7 +224,7 @@ typedef struct bootsector_t {
            uint8_t signature;
            uint32_t id;
            uint8_t volume_label[11];
-       } __attribute__((packed)) fat16;
+       } QEMU_PACKED fat16;
        struct {
            uint32_t sectors_per_fat;
            uint16_t flags;
@@ -233,12 +233,12 @@ typedef struct bootsector_t {
            uint16_t info_sector;
            uint16_t backup_boot_sector;
            uint16_t ignored;
-       } __attribute__((packed)) fat32;
+       } QEMU_PACKED fat32;
     } u;
     uint8_t fat_type[8];
     uint8_t ignored[0x1c0];
     uint8_t magic[2];
-} __attribute__((packed)) bootsector_t;
+} QEMU_PACKED bootsector_t;
 
 typedef struct {
     uint8_t head;
@@ -253,7 +253,7 @@ typedef struct partition_t {
     mbr_chs_t end_CHS;
     uint32_t start_sector_long;
     uint32_t length_sector_long;
-} __attribute__((packed)) partition_t;
+} QEMU_PACKED partition_t;
 
 typedef struct mbr_t {
     uint8_t ignored[0x1b8];
@@ -261,7 +261,7 @@ typedef struct mbr_t {
     uint8_t ignored2[2];
     partition_t partition[4];
     uint8_t magic[2];
-} __attribute__((packed)) mbr_t;
+} QEMU_PACKED mbr_t;
 
 typedef struct direntry_t {
     uint8_t name[8];
@@ -276,7 +276,7 @@ typedef struct direntry_t {
     uint16_t mdate;
     uint16_t begin;
     uint32_t size;
-} __attribute__((packed)) direntry_t;
+} QEMU_PACKED direntry_t;
 
 /* this structure are used to transparently access the files */
 
index f6d02b38a767d24fa5300818ee2a43b78f7c4a6d..8a72b804b2d93d536c14699a6f1c0ef69f92430a 100644 (file)
@@ -28,6 +28,7 @@
 #include "qemu-option.h"
 #include "qemu-queue.h"
 #include "qemu-coroutine.h"
+#include "qemu-timer.h"
 
 #define BLOCK_FLAG_ENCRYPT     1
 #define BLOCK_FLAG_COMPAT6     4
@@ -184,10 +185,9 @@ struct BlockDriverState {
     void *sync_aiocb;
 
     /* I/O stats (display with "info blockstats"). */
-    uint64_t rd_bytes;
-    uint64_t wr_bytes;
-    uint64_t rd_ops;
-    uint64_t wr_ops;
+    uint64_t nr_bytes[BDRV_MAX_IOTYPE];
+    uint64_t nr_ops[BDRV_MAX_IOTYPE];
+    uint64_t total_time_ns[BDRV_MAX_IOTYPE];
     uint64_t wr_highest_sector;
 
     /* Whether the disk can expand beyond total_sectors */
index d272659ab26f0ba9901802876d368d7127b02f3c..2602591bf601da704204d6abdc02e31dd48573ab 100644 (file)
@@ -321,18 +321,9 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
     }
 
     if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
-        if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
-            bdrv_flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
-        } else if (!strcmp(buf, "writeback")) {
-            bdrv_flags |= BDRV_O_CACHE_WB;
-        } else if (!strcmp(buf, "unsafe")) {
-            bdrv_flags |= BDRV_O_CACHE_WB;
-            bdrv_flags |= BDRV_O_NO_FLUSH;
-        } else if (!strcmp(buf, "writethrough")) {
-            /* this is the default */
-        } else {
-           error_report("invalid cache option");
-           return NULL;
+        if (bdrv_parse_cache_flags(buf, &bdrv_flags) != 0) {
+            error_report("invalid cache option");
+            return NULL;
         }
     }
 
index 9af5dc6c91dc7315559449589d3209488c07e2f5..a2d5959e4b86e539313b37e82c7bb8d75b6dc00e 100644 (file)
 #define QEMU_WARN_UNUSED_RESULT
 #endif
 
+#if defined(_WIN32)
+# define QEMU_PACKED __attribute__((gcc_struct, packed))
+#else
+# define QEMU_PACKED __attribute__((packed))
+#endif
+
 #define QEMU_BUILD_BUG_ON(x) \
     typedef char qemu_build_bug_on__##__LINE__[(x)?-1:1];
 
index 1340c33ef827d05914c6b114fd3eb6ea62fcca96..c3044c7435202631821d8224a0fabcdc363c61be 100755 (executable)
--- a/configure
+++ b/configure
@@ -165,7 +165,6 @@ darwin_user="no"
 bsd_user="no"
 guest_base=""
 uname_release=""
-io_thread="no"
 mixemu="no"
 aix="no"
 blobs="yes"
@@ -413,6 +412,7 @@ SunOS)
   make="${MAKE-gmake}"
   install="${INSTALL-ginstall}"
   ld="gld"
+  smbd="${SMBD-/usr/sfw/sbin/smbd}"
   needs_libsunmath="no"
   solarisrev=`uname -r | cut -f2 -d.`
   # have to select again, because `uname -m` returns i86pc
@@ -481,6 +481,7 @@ fi
 : ${make=${MAKE-make}}
 : ${install=${INSTALL-install}}
 : ${python=${PYTHON-python}}
+: ${smbd=${SMBD-/usr/sbin/smbd}}
 
 if test "$mingw32" = "yes" ; then
   EXESUF=".exe"
@@ -525,6 +526,8 @@ for opt do
   ;;
   --python=*) python="$optarg"
   ;;
+  --smbd=*) smbd="$optarg"
+  ;;
   --extra-cflags=*)
   ;;
   --extra-ldflags=*)
@@ -723,8 +726,6 @@ for opt do
   ;;
   --enable-attr) attr="yes"
   ;;
-  --enable-io-thread) io_thread="yes"
-  ;;
   --disable-blobs) blobs="no"
   ;;
   --with-pkgversion=*) pkgversion=" ($optarg)"
@@ -941,6 +942,7 @@ echo "  --extra-ldflags=LDFLAGS  append extra linker flags LDFLAGS"
 echo "  --make=MAKE              use specified make [$make]"
 echo "  --install=INSTALL        use specified install [$install]"
 echo "  --python=PYTHON          use specified python [$python]"
+echo "  --smbd=SMBD              use specified smbd [$smbd]"
 echo "  --static                 enable static build [$static]"
 echo "  --mandir=PATH            install man pages in PATH"
 echo "  --datadir=PATH           install firmware in PATH"
@@ -2158,12 +2160,6 @@ EOF
 
 if compile_prog "" "" ; then
   signalfd=yes
-elif test "$kvm" = "yes" -a "$io_thread" != "yes"; then
-  echo
-  echo "ERROR: Host kernel lacks signalfd() support,"
-  echo "but KVM depends on it when the IO thread is disabled."
-  echo
-  exit 1
 fi
 
 # check if eventfd is supported
@@ -2666,6 +2662,9 @@ echo "LDFLAGS           $LDFLAGS"
 echo "make              $make"
 echo "install           $install"
 echo "python            $python"
+if test "$slirp" = "yes" ; then
+    echo "smbd              $smbd"
+fi
 echo "host CPU          $cpu"
 echo "host big endian   $bigendian"
 echo "target list       $target_list"
@@ -2710,7 +2709,6 @@ echo "NPTL support      $nptl"
 echo "GUEST_BASE        $guest_base"
 echo "PIE user targets  $user_pie"
 echo "vde support       $vde"
-echo "IO thread         $io_thread"
 echo "Linux AIO support $linux_aio"
 echo "ATTR/XATTR support $attr"
 echo "Install blobs     $blobs"
@@ -2825,6 +2823,7 @@ if test "$profiler" = "yes" ; then
 fi
 if test "$slirp" = "yes" ; then
   echo "CONFIG_SLIRP=y" >> $config_host_mak
+  echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
   QEMU_INCLUDES="-I\$(SRC_PATH)/slirp $QEMU_INCLUDES"
 fi
 if test "$vde" = "yes" ; then
@@ -2968,9 +2967,6 @@ if test "$xen" = "yes" ; then
   echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
   echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
 fi
-if test "$io_thread" = "yes" ; then
-  echo "CONFIG_IOTHREAD=y" >> $config_host_mak
-fi
 if test "$linux_aio" = "yes" ; then
   echo "CONFIG_LINUX_AIO=y" >> $config_host_mak
 fi
@@ -3064,26 +3060,43 @@ bsd)
 ;;
 esac
 
+# use default implementation for tracing backend-specific routines
+trace_default=yes
 echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
-if test "$trace_backend" = "simple"; then
-  echo "CONFIG_SIMPLE_TRACE=y" >> $config_host_mak
+if test "$trace_backend" = "nop"; then
+  echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
 fi
-# Set the appropriate trace file.
 if test "$trace_backend" = "simple"; then
+  echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
+  trace_default=no
+  # Set the appropriate trace file.
   trace_file="\"$trace_file-\" FMT_pid"
 fi
-if test "$trace_backend" = "dtrace" -a "$trace_backend_stap" = "yes" ; then
-  echo "CONFIG_SYSTEMTAP_TRACE=y" >> $config_host_mak
+if test "$trace_backend" = "stderr"; then
+  echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
+  trace_default=no
+fi
+if test "$trace_backend" = "ust"; then
+  echo "CONFIG_TRACE_UST=y" >> $config_host_mak
+fi
+if test "$trace_backend" = "dtrace"; then
+  echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak
+  if test "$trace_backend_stap" = "yes" ; then
+    echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
+  fi
 fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
+if test "$trace_default" = "yes"; then
+  echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak
+fi
 
 echo "TOOLS=$tools" >> $config_host_mak
 echo "ROMS=$roms" >> $config_host_mak
 echo "MAKE=$make" >> $config_host_mak
 echo "INSTALL=$install" >> $config_host_mak
-echo "INSTALL_DIR=$install -d -m0755 -p" >> $config_host_mak
-echo "INSTALL_DATA=$install -m0644 -p" >> $config_host_mak
-echo "INSTALL_PROG=$install -m0755 -p" >> $config_host_mak
+echo "INSTALL_DIR=$install -d -m 0755" >> $config_host_mak
+echo "INSTALL_DATA=$install -c -m 0644" >> $config_host_mak
+echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
 echo "PYTHON=$python" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 echo "CC_I386=$cc_i386" >> $config_host_mak
@@ -3600,7 +3613,7 @@ DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS fsdev ui"
 DIRS="$DIRS qapi"
-DIRS="$DIRS qga"
+DIRS="$DIRS qga trace"
 FILES="Makefile tests/Makefile"
 FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
diff --git a/cpus.c b/cpus.c
index b163efe4a88f6eb56fc9aeb4511a272449475e6b..54c188cf5c9a58b37262eae29b797de241658808 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -173,12 +173,9 @@ static void cpu_handle_guest_debug(CPUState *env)
 {
     gdb_set_stop_cpu(env);
     qemu_system_debug_request();
-#ifdef CONFIG_IOTHREAD
     env->stopped = 1;
-#endif
 }
 
-#ifdef CONFIG_IOTHREAD
 static void cpu_signal(int sig)
 {
     if (cpu_single_env) {
@@ -186,7 +183,6 @@ static void cpu_signal(int sig)
     }
     exit_request = 1;
 }
-#endif
 
 #ifdef CONFIG_LINUX
 static void sigbus_reraise(void)
@@ -262,12 +258,6 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
-
-#ifndef CONFIG_IOTHREAD
-    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
-        qemu_notify_event();
-    }
-#endif
 }
 
 #else /* !CONFIG_LINUX */
@@ -390,7 +380,6 @@ static int qemu_signal_init(void)
     int sigfd;
     sigset_t set;
 
-#ifdef CONFIG_IOTHREAD
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
     sigaddset(&set, SIGUSR2);
@@ -409,18 +398,6 @@ static int qemu_signal_init(void)
     sigaddset(&set, SIGIO);
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIGBUS);
-#else
-    sigemptyset(&set);
-    sigaddset(&set, SIGBUS);
-    if (kvm_enabled()) {
-        /*
-         * We need to process timer signals synchronously to avoid a race
-         * between exit_request check and KVM vcpu entry.
-         */
-        sigaddset(&set, SIGIO);
-        sigaddset(&set, SIGALRM);
-    }
-#endif
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     sigfd = qemu_signalfd(&set);
@@ -447,7 +424,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     sigact.sa_handler = dummy_signal;
     sigaction(SIG_IPI, &sigact, NULL);
 
-#ifdef CONFIG_IOTHREAD
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
@@ -456,17 +432,7 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
         exit(1);
     }
-#else
-    sigemptyset(&set);
-    sigaddset(&set, SIG_IPI);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
 
-    pthread_sigmask(SIG_BLOCK, NULL, &set);
-    sigdelset(&set, SIGIO);
-    sigdelset(&set, SIGALRM);
-#endif
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
     r = kvm_set_signal_mask(env, &set);
@@ -478,7 +444,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
 
 static void qemu_tcg_init_cpu_signals(void)
 {
-#ifdef CONFIG_IOTHREAD
     sigset_t set;
     struct sigaction sigact;
 
@@ -489,7 +454,6 @@ static void qemu_tcg_init_cpu_signals(void)
     sigemptyset(&set);
     sigaddset(&set, SIG_IPI);
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-#endif
 }
 
 #else /* _WIN32 */
@@ -535,106 +499,6 @@ static void qemu_tcg_init_cpu_signals(void)
 }
 #endif /* _WIN32 */
 
-#ifndef CONFIG_IOTHREAD
-int qemu_init_main_loop(void)
-{
-    int ret;
-
-    ret = qemu_signal_init();
-    if (ret) {
-        return ret;
-    }
-
-    qemu_init_sigbus();
-
-    return qemu_event_init();
-}
-
-void qemu_main_loop_start(void)
-{
-}
-
-void qemu_init_vcpu(void *_env)
-{
-    CPUState *env = _env;
-    int r;
-
-    env->nr_cores = smp_cores;
-    env->nr_threads = smp_threads;
-
-    if (kvm_enabled()) {
-        r = kvm_init_vcpu(env);
-        if (r < 0) {
-            fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
-            exit(1);
-        }
-        qemu_kvm_init_cpu_signals(env);
-    } else {
-        qemu_tcg_init_cpu_signals();
-    }
-}
-
-int qemu_cpu_is_self(void *env)
-{
-    return 1;
-}
-
-void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
-{
-    func(data);
-}
-
-void resume_all_vcpus(void)
-{
-}
-
-void pause_all_vcpus(void)
-{
-}
-
-void qemu_cpu_kick(void *env)
-{
-}
-
-void qemu_cpu_kick_self(void)
-{
-#ifndef _WIN32
-    assert(cpu_single_env);
-
-    raise(SIG_IPI);
-#else
-    abort();
-#endif
-}
-
-void qemu_notify_event(void)
-{
-    CPUState *env = cpu_single_env;
-
-    qemu_event_increment ();
-    if (env) {
-        cpu_exit(env);
-    }
-    if (next_cpu && env != next_cpu) {
-        cpu_exit(next_cpu);
-    }
-    exit_request = 1;
-}
-
-void qemu_mutex_lock_iothread(void) {}
-void qemu_mutex_unlock_iothread(void) {}
-
-void cpu_stop_current(void)
-{
-}
-
-void vm_stop(int reason)
-{
-    do_vm_stop(reason);
-}
-
-#else /* CONFIG_IOTHREAD */
-
 QemuMutex qemu_global_mutex;
 static QemuCond qemu_io_proceeded_cond;
 static bool iothread_requesting_mutex;
@@ -1028,8 +892,6 @@ void vm_stop(int reason)
     do_vm_stop(reason);
 }
 
-#endif
-
 static int tcg_cpu_exec(CPUState *env)
 {
     int ret;
@@ -1084,11 +946,6 @@ bool cpu_exec_all(void)
         qemu_clock_enable(vm_clock,
                           (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
-#ifndef CONFIG_IOTHREAD
-        if (qemu_alarm_pending()) {
-            break;
-        }
-#endif
         if (cpu_can_run(env)) {
             if (kvm_enabled()) {
                 r = kvm_cpu_exec(env);
index b7befb5e48221dff4ad7429302d13d50ea98c553..f345866f57c4dffc4ed3d1a215fb84e740f54bda 100644 (file)
@@ -229,7 +229,7 @@ in the schema. The following files are generated:
 $(prefix)qmp-marshal.c: command marshal/dispatch functions for each
                         QMP command defined in the schema. Functions
                         generated by qapi-visit.py are used to
-                        convert QObjects recieved from the wire into
+                        convert QObjects received from the wire into
                         function parameters, and uses the same
                         visitor functions to convert native C return
                         values to QObjects from transmission back
index c99a0f27cfa79a79d8de558da3dbaab6cf84e7f8..4b27ab0c2a71f0a5d094fe52069f26ff8d66238c 100644 (file)
@@ -12,13 +12,14 @@ for debugging, profiling, and observing execution.
     ./configure --trace-backend=simple
     make
 
-2. Enable trace events you are interested in:
+2. Create a file with the events you want to trace:
 
-    $EDITOR trace-events  # remove "disable" from events you want
+   echo bdrv_aio_readv   > /tmp/events
+   echo bdrv_aio_writev >> /tmp/events
 
 3. Run the virtual machine to produce a trace file:
 
-    qemu ... # your normal QEMU invocation
+    qemu -trace events=/tmp/events ... # your normal QEMU invocation
 
 4. Pretty-print the binary trace file:
 
@@ -38,7 +39,7 @@ generate code for the trace events.  Trace events are invoked directly from
 source code like this:
 
     #include "trace.h"  /* needed for trace event prototype */
-
+    
     void *qemu_malloc(size_t size)
     {
         void *ptr;
@@ -103,10 +104,45 @@ portability macros, ensure they are preceded and followed by double quotes:
 4. Name trace events after their function.  If there are multiple trace events
    in one function, append a unique distinguisher at the end of the name.
 
-5. Declare trace events with the "disable" keyword.  Some trace events can
-   produce a lot of output and users are typically only interested in a subset
-   of trace events.  Marking trace events disabled by default saves the user
-   from having to manually disable noisy trace events.
+5. If specific trace events are going to be called a huge number of times, this
+   might have a noticeable performance impact even when the trace events are
+   programmatically disabled. In this case you should declare the trace event
+   with the "disable" property, which will effectively disable it at compile
+   time (using the "nop" backend).
+
+== Generic interface and monitor commands ==
+
+You can programmatically query and control the dynamic state of trace events
+through a backend-agnostic interface:
+
+* trace_print_events
+
+* trace_event_set_state
+  Enables or disables trace events at runtime inside QEMU.
+  The function returns "true" if the state of the event has been successfully
+  changed, or "false" otherwise:
+
+    #include "trace/control.h"
+    
+    trace_event_set_state("virtio_irq", true); /* enable */
+    [...]
+    trace_event_set_state("virtio_irq", false); /* disable */
+
+Note that some of the backends do not provide an implementation for this
+interface, in which case QEMU will just print a warning.
+
+This functionality is also provided through monitor commands:
+
+* info trace-events
+  View available trace events and their state.  State 1 means enabled, state 0
+  means disabled.
+
+* trace-event NAME on|off
+  Enable/disable a given trace event.
+
+The "-trace events=<file>" command line argument can be used to enable the
+events listed in <file> from the very beginning of the program. This file must
+contain one event name per line.
 
 == Trace backends ==
 
@@ -131,6 +167,9 @@ The "nop" backend generates empty trace event functions so that the compiler
 can optimize out trace events completely.  This is the default and imposes no
 performance penalty.
 
+Note that regardless of the selected trace backend, events with the "disable"
+property will be generated with the "nop" backend.
+
 === Stderr ===
 
 The "stderr" backend sends trace events directly to standard error.  This
@@ -157,27 +196,9 @@ unless you have specific needs for more advanced backends.
   flushed and emptied.  This means the 'info trace' will display few or no
   entries if the buffer has just been flushed.
 
-* info trace-events
-  View available trace events and their state.  State 1 means enabled, state 0
-  means disabled.
-
-* trace-event NAME on|off
-  Enable/disable a given trace event.
-
 * trace-file on|off|flush|set <path>
   Enable/disable/flush the trace file or set the trace file name.
 
-==== Enabling/disabling trace events programmatically ====
-
-The st_change_trace_event_state() function can be used to enable or disable trace
-events at runtime inside QEMU:
-
-    #include "trace.h"
-    
-    st_change_trace_event_state("virtio_irq", true); /* enable */
-    [...]
-    st_change_trace_event_state("virtio_irq", false); /* disable */
-
 ==== Analyzing trace files ====
 
 The "simple" backend produces binary trace files that can be formatted with the
index cc1e4fb09d50082bf258b859c113cd4554ee00fb..8beb7f33447cea9fe71d54b2d753d26b4900a209 100644 (file)
 #if !defined(__DYNGEN_EXEC_H__)
 #define __DYNGEN_EXEC_H__
 
-#include "qemu-common.h"
-
-#ifdef __OpenBSD__
-#include <sys/types.h>
-#endif
-
-/* XXX: This may be wrong for 64-bit ILP32 hosts.  */
-typedef void * host_reg_t;
-
 #if defined(__i386__)
 #define AREG0 "ebp"
 #elif defined(__x86_64__)
@@ -66,11 +57,6 @@ typedef void * host_reg_t;
 
 register CPUState *env asm(AREG0);
 
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s)   tostring(s)
-#define tostring(s)    #s
-
 /* The return address may point to the start of the next instruction.
    Subtracting one gets us the call instruction itself.  */
 #if defined(__s390__) && !defined(__s390x__)
index 7951a0e8696fa697a61a5a2118ee2a655313375d..2b2008502c57f6e1c5d7cccbb73df684143ab76b 100644 (file)
@@ -5965,20 +5965,20 @@ int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
 }
 
 /* misc functions */
-float32 uint32_to_float32( unsigned int a STATUS_PARAM )
+float32 uint32_to_float32( uint32 a STATUS_PARAM )
 {
     return int64_to_float32(a STATUS_VAR);
 }
 
-float64 uint32_to_float64( unsigned int a STATUS_PARAM )
+float64 uint32_to_float64( uint32 a STATUS_PARAM )
 {
     return int64_to_float64(a STATUS_VAR);
 }
 
-unsigned int float32_to_uint32( float32 a STATUS_PARAM )
+uint32 float32_to_uint32( float32 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float32_to_int64(a STATUS_VAR);
     if (v < 0) {
@@ -5993,10 +5993,10 @@ unsigned int float32_to_uint32( float32 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
+uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float32_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
@@ -6011,10 +6011,10 @@ unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float32_to_uint16_round_to_zero( float32 a STATUS_PARAM )
+uint16 float32_to_uint16_round_to_zero( float32 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint16 res;
 
     v = float32_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
@@ -6029,10 +6029,10 @@ unsigned int float32_to_uint16_round_to_zero( float32 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float64_to_uint32( float64 a STATUS_PARAM )
+uint32 float64_to_uint32( float64 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float64_to_int64(a STATUS_VAR);
     if (v < 0) {
@@ -6047,10 +6047,10 @@ unsigned int float64_to_uint32( float64 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
+uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float64_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
@@ -6065,10 +6065,10 @@ unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float64_to_uint16_round_to_zero( float64 a STATUS_PARAM )
+uint16 float64_to_uint16_round_to_zero( float64 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint16 res;
 
     v = float64_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
index 3bb7d8fa6d9e8e0b7e22969fb36dbd37ff0e64d0..618ddee569976b002ae63c99d9d1194cc003e0c7 100644 (file)
@@ -216,8 +216,8 @@ void float_raise( int8 flags STATUS_PARAM);
 *----------------------------------------------------------------------------*/
 float32 int32_to_float32( int32 STATUS_PARAM );
 float64 int32_to_float64( int32 STATUS_PARAM );
-float32 uint32_to_float32( unsigned int STATUS_PARAM );
-float64 uint32_to_float64( unsigned int STATUS_PARAM );
+float32 uint32_to_float32( uint32 STATUS_PARAM );
+float64 uint32_to_float64( uint32 STATUS_PARAM );
 floatx80 int32_to_floatx80( int32 STATUS_PARAM );
 float128 int32_to_float128( int32 STATUS_PARAM );
 float32 int64_to_float32( int64 STATUS_PARAM );
@@ -249,7 +249,7 @@ extern const float16 float16_default_nan;
 | Software IEC/IEEE single-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int16 float32_to_int16_round_to_zero( float32 STATUS_PARAM );
-unsigned int float32_to_uint16_round_to_zero( float32 STATUS_PARAM );
+uint16 float32_to_uint16_round_to_zero( float32 STATUS_PARAM );
 int32 float32_to_int32( float32 STATUS_PARAM );
 int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM );
 uint32 float32_to_uint32( float32 STATUS_PARAM );
@@ -352,7 +352,7 @@ extern const float32 float32_default_nan;
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int16 float64_to_int16_round_to_zero( float64 STATUS_PARAM );
-unsigned int float64_to_uint16_round_to_zero( float64 STATUS_PARAM );
+uint16 float64_to_uint16_round_to_zero( float64 STATUS_PARAM );
 int32 float64_to_int32( float64 STATUS_PARAM );
 int32 float64_to_int32_round_to_zero( float64 STATUS_PARAM );
 uint32 float64_to_uint32( float64 STATUS_PARAM );
index 0ccfb2867f475f197e8df293dcd965a2a1935781..9e1cca8e3d26b9648d9bd077cf10c1be8d1565ed 100644 (file)
@@ -180,13 +180,12 @@ STEXI
 Output logs to @var{filename}.
 ETEXI
 
-#ifdef CONFIG_SIMPLE_TRACE
     {
         .name       = "trace-event",
         .args_type  = "name:s,option:b",
         .params     = "name on|off",
         .help       = "changes status of a specific trace event",
-        .mhandler.cmd = do_change_trace_event_state,
+        .mhandler.cmd = do_trace_event_set_state,
     },
 
 STEXI
@@ -195,6 +194,7 @@ STEXI
 changes status of a trace event
 ETEXI
 
+#if defined(CONFIG_SIMPLE_TRACE)
     {
         .name       = "trace-file",
         .args_type  = "op:s?,arg:F?",
@@ -1354,14 +1354,17 @@ show roms
 @end table
 ETEXI
 
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 STEXI
 @item info trace
 show contents of trace buffer
+ETEXI
+#endif
+
+STEXI
 @item info trace-events
 show available trace events and their state
 ETEXI
-#endif
 
 STEXI
 @end table
diff --git a/hppa.ld b/hppa.ld
index 9a4b22c022edbcc2548a478e0763b468f16e7698..3555b3e8e805330d40e9601f3f7a4a9fc84151cd 100644 (file)
--- a/hppa.ld
+++ b/hppa.ld
@@ -75,36 +75,34 @@ SECTIONS
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .PARISC.unwind   : { *(.PARISC.unwind) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN(0x10000) + (. & (0x10000 - 1));
   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table .gcc_except_table.*) }
   /* Thread Local Storage sections  */
   .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors          :
   {
index 28fe1ff3a3e74954c5be23515667e50860128a2b..9d1b508e1642896133b8d2fef6583470d6a5bf08 100644 (file)
@@ -327,7 +327,7 @@ struct virtio_9p_config
     uint16_t tag_len;
     /* Variable size tag name */
     uint8_t tag[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 typedef struct V9fsMkState {
     V9fsPDU *pdu;
index d04b965977571b941337d084d562f3b2ce99b6a5..1cf35e116abacccc0082ead37b307e8240618a0c 100644 (file)
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -32,7 +32,7 @@ struct acpi_table_header {
     uint32_t oem_revision;    /* OEM revision number */
     char asl_compiler_id[4];  /* ASL compiler vendor ID */
     uint32_t asl_compiler_revision; /* ASL compiler revision number */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
 #define ACPI_TABLE_PFX_SIZE sizeof(uint16_t)  /* size of the extra prefix */
index 481ae6044906e475c35061b4dc3d7aba257d49bf..04ca420a90f6518029b5b466904da360d74c115d 100644 (file)
@@ -12,7 +12,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 #define AN5206_MBAR_ADDR 0x10000000
@@ -38,9 +37,6 @@ static void an5206_init(ram_addr_t ram_size,
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5206";
@@ -56,12 +52,12 @@ static void an5206_init(ram_addr_t ram_size,
     env->rambar0 = AN5206_RAMBAR_ADDR | 1;
 
     /* DRAM at address zero */
-    memory_region_init_ram(ram, NULL, "an5206.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size,
+        qemu_ram_alloc(NULL, "an5206.ram", ram_size) | IO_MEM_RAM);
 
     /* Internal SRAM.  */
-    memory_region_init_ram(sram, NULL, "an5206.sram", 512);
-    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
+    cpu_register_physical_memory(AN5206_RAMBAR_ADDR, 512,
+        qemu_ram_alloc(NULL, "an5206.sram", 512) | IO_MEM_RAM);
 
     mcf5206_init(AN5206_MBAR_ADDR, env);
 
index 6ee2068128c082329af9f4cb71dbf20e11def95e..c232946280079c2fe27cd1c9f6fdabb200f312c3 100644 (file)
@@ -71,6 +71,7 @@ typedef struct APBState {
     PCIBus      *bus;
     MemoryRegion apb_config;
     MemoryRegion pci_config;
+    MemoryRegion pci_mmio;
     MemoryRegion pci_ioport;
     uint32_t iommu[4];
     uint32_t pci_control[16];
@@ -336,12 +337,14 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
     sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
     d = FROM_SYSBUS(APBState, s);
 
+    memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
+    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
+
     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
-                                         pci_apb_set_irq, pci_pbm_map_irq, d,
-                                         get_system_memory(),
-                                         get_system_io(),
-                                         0, 32);
-    pci_bus_set_mem_base(d->bus, mem_base);
+                              pci_apb_set_irq, pci_pbm_map_irq, d,
+                              &d->pci_mmio,
+                              get_system_io(),
+                              0, 32);
 
     for (i = 0; i < 32; i++) {
         sysbus_connect_irq(s, i, pic[i]);
index af403a159a3c5547d49c41d9ddc998dcf44a612f..f8a747289b9c9cd624890be4aa57462ef1699a22 100644 (file)
 #ifndef ARM_MISC_H
 #define ARM_MISC_H 1
 
-#include "memory.h"
-
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
 #define ARM_PIC_CPU_FIQ 1
 qemu_irq *arm_pic_init_cpu(CPUState *env);
 
 /* armv7m.c */
-qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
-                      int flash_size, int sram_size,
+qemu_irq *armv7m_init(int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model);
 
 /* arm_boot.c */
index 28d41b82a62b55b0bcc5642cabee9e8d8feb709e..a932f16a44ee4869b0a252c31766970f492e644e 100644 (file)
@@ -156,8 +156,7 @@ static void armv7m_reset(void *opaque)
    flash_size and sram_size are in kb.
    Returns the NVIC array.  */
 
-qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
-                      int flash_size, int sram_size,
+qemu_irq *armv7m_init(int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model)
 {
     CPUState *env;
@@ -170,9 +169,6 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     uint64_t lowaddr;
     int i;
     int big_endian;
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
-    MemoryRegion *hack = g_new(MemoryRegion, 1);
 
     flash_size *= 1024;
     sram_size *= 1024;
@@ -198,11 +194,12 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
 #endif
 
     /* Flash programming is done via the SCU, so pretend it is ROM.  */
-    memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
-    memory_region_set_readonly(flash, true);
-    memory_region_add_subregion(address_space_mem, 0, flash);
-    memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
-    memory_region_add_subregion(address_space_mem, 0x20000000, sram);
+    cpu_register_physical_memory(0, flash_size,
+                                 qemu_ram_alloc(NULL, "armv7m.flash",
+                                                flash_size) | IO_MEM_ROM);
+    cpu_register_physical_memory(0x20000000, sram_size,
+                                 qemu_ram_alloc(NULL, "armv7m.sram",
+                                                sram_size) | IO_MEM_RAM);
     armv7m_bitband_init();
 
     nvic = qdev_create(NULL, "armv7m_nvic");
@@ -235,8 +232,9 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     /* Hack to map an additional page of ram at the top of the address
        space.  This stops qemu complaining about executing code outside RAM
        when returning from an exception.  */
-    memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000);
-    memory_region_add_subregion(address_space_mem, 0xfffff000, hack);
+    cpu_register_physical_memory(0xfffff000, 0x1000,
+                                 qemu_ram_alloc(NULL, "armv7m.hack", 
+                                                0x1000) | IO_MEM_RAM);
 
     qemu_register_reset(armv7m_reset, env);
     return pic;
index 73eb39d43bc38b3445ad10e295a9db6d739500b8..06200e257a3eb335ee63231a3f5b0f3310321ecb 100644 (file)
@@ -31,7 +31,6 @@
 #include "elf.h"
 #include "cris-boot.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define D(x)
 #define DNAND(x)
@@ -260,9 +259,8 @@ void axisdev88_init (ram_addr_t ram_size,
     int i;
     int nand_regs;
     int gpio_regs;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_intmem = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_intmem;
 
     /* init CPUs */
     if (cpu_model == NULL) {
@@ -271,13 +269,15 @@ void axisdev88_init (ram_addr_t ram_size,
     env = cpu_init(cpu_model);
 
     /* allocate RAM */
-    memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "axisdev88.ram", ram_size);
+    cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM);
 
     /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the 
        internal memory.  */
-    memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
+    phys_intmem = qemu_ram_alloc(NULL, "axisdev88.chipram", INTMEM_SIZE);
+    cpu_register_physical_memory(0x38000000, INTMEM_SIZE,
+                                 phys_intmem | IO_MEM_RAM);
+
 
       /* Attach a NAND flash to CS1.  */
     nand = drive_get(IF_MTD, 0, 0);
diff --git a/hw/bt.h b/hw/bt.h
index 3797254691954ff72248195e1afeabb0cd3e5979..a48b8d4b133783cccdac9f5eb85edd11e59413e7 100644 (file)
--- a/hw/bt.h
+++ b/hw/bt.h
@@ -26,7 +26,7 @@
 /* BD Address */
 typedef struct {
     uint8_t b[6];
-} __attribute__((packed)) bdaddr_t;
+} QEMU_PACKED bdaddr_t;
 
 #define BDADDR_ANY     (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
 #define BDADDR_ALL     (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
@@ -446,13 +446,13 @@ typedef struct {
     uint8_t    lap[3];
     uint8_t    length;         /* 1.28s units */
     uint8_t    num_rsp;
-} __attribute__ ((packed)) inquiry_cp;
+} QEMU_PACKED inquiry_cp;
 #define INQUIRY_CP_SIZE 5
 
 typedef struct {
     uint8_t            status;
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) status_bdaddr_rp;
+} QEMU_PACKED status_bdaddr_rp;
 #define STATUS_BDADDR_RP_SIZE 7
 
 #define OCF_INQUIRY_CANCEL             0x0002
@@ -464,7 +464,7 @@ typedef struct {
     uint8_t    lap[3];
     uint8_t    length;         /* 1.28s units */
     uint8_t    num_rsp;
-} __attribute__ ((packed)) periodic_inquiry_cp;
+} QEMU_PACKED periodic_inquiry_cp;
 #define PERIODIC_INQUIRY_CP_SIZE 9
 
 #define OCF_EXIT_PERIODIC_INQUIRY      0x0004
@@ -477,55 +477,55 @@ typedef struct {
     uint8_t    pscan_mode;
     uint16_t   clock_offset;
     uint8_t    role_switch;
-} __attribute__ ((packed)) create_conn_cp;
+} QEMU_PACKED create_conn_cp;
 #define CREATE_CONN_CP_SIZE 13
 
 #define OCF_DISCONNECT                 0x0006
 typedef struct {
     uint16_t   handle;
     uint8_t    reason;
-} __attribute__ ((packed)) disconnect_cp;
+} QEMU_PACKED disconnect_cp;
 #define DISCONNECT_CP_SIZE 3
 
 #define OCF_ADD_SCO                    0x0007
 typedef struct {
     uint16_t   handle;
     uint16_t   pkt_type;
-} __attribute__ ((packed)) add_sco_cp;
+} QEMU_PACKED add_sco_cp;
 #define ADD_SCO_CP_SIZE 4
 
 #define OCF_CREATE_CONN_CANCEL         0x0008
 typedef struct {
     uint8_t    status;
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) create_conn_cancel_cp;
+} QEMU_PACKED create_conn_cancel_cp;
 #define CREATE_CONN_CANCEL_CP_SIZE 6
 
 typedef struct {
     uint8_t    status;
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) create_conn_cancel_rp;
+} QEMU_PACKED create_conn_cancel_rp;
 #define CREATE_CONN_CANCEL_RP_SIZE 7
 
 #define OCF_ACCEPT_CONN_REQ            0x0009
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    role;
-} __attribute__ ((packed)) accept_conn_req_cp;
+} QEMU_PACKED accept_conn_req_cp;
 #define ACCEPT_CONN_REQ_CP_SIZE        7
 
 #define OCF_REJECT_CONN_REQ            0x000A
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    reason;
-} __attribute__ ((packed)) reject_conn_req_cp;
+} QEMU_PACKED reject_conn_req_cp;
 #define REJECT_CONN_REQ_CP_SIZE        7
 
 #define OCF_LINK_KEY_REPLY             0x000B
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    link_key[16];
-} __attribute__ ((packed)) link_key_reply_cp;
+} QEMU_PACKED link_key_reply_cp;
 #define LINK_KEY_REPLY_CP_SIZE 22
 
 #define OCF_LINK_KEY_NEG_REPLY         0x000C
@@ -535,7 +535,7 @@ typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    pin_len;
     uint8_t    pin_code[16];
-} __attribute__ ((packed)) pin_code_reply_cp;
+} QEMU_PACKED pin_code_reply_cp;
 #define PIN_CODE_REPLY_CP_SIZE 23
 
 #define OCF_PIN_CODE_NEG_REPLY         0x000E
@@ -544,32 +544,32 @@ typedef struct {
 typedef struct {
     uint16_t    handle;
     uint16_t    pkt_type;
-} __attribute__ ((packed)) set_conn_ptype_cp;
+} QEMU_PACKED set_conn_ptype_cp;
 #define SET_CONN_PTYPE_CP_SIZE 4
 
 #define OCF_AUTH_REQUESTED             0x0011
 typedef struct {
     uint16_t    handle;
-} __attribute__ ((packed)) auth_requested_cp;
+} QEMU_PACKED auth_requested_cp;
 #define AUTH_REQUESTED_CP_SIZE 2
 
 #define OCF_SET_CONN_ENCRYPT           0x0013
 typedef struct {
     uint16_t   handle;
     uint8_t    encrypt;
-} __attribute__ ((packed)) set_conn_encrypt_cp;
+} QEMU_PACKED set_conn_encrypt_cp;
 #define SET_CONN_ENCRYPT_CP_SIZE 3
 
 #define OCF_CHANGE_CONN_LINK_KEY       0x0015
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) change_conn_link_key_cp;
+} QEMU_PACKED change_conn_link_key_cp;
 #define CHANGE_CONN_LINK_KEY_CP_SIZE 2
 
 #define OCF_MASTER_LINK_KEY            0x0017
 typedef struct {
     uint8_t    key_flag;
-} __attribute__ ((packed)) master_link_key_cp;
+} QEMU_PACKED master_link_key_cp;
 #define MASTER_LINK_KEY_CP_SIZE 1
 
 #define OCF_REMOTE_NAME_REQ            0x0019
@@ -578,50 +578,50 @@ typedef struct {
     uint8_t    pscan_rep_mode;
     uint8_t    pscan_mode;
     uint16_t   clock_offset;
-} __attribute__ ((packed)) remote_name_req_cp;
+} QEMU_PACKED remote_name_req_cp;
 #define REMOTE_NAME_REQ_CP_SIZE 10
 
 #define OCF_REMOTE_NAME_REQ_CANCEL     0x001A
 typedef struct {
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) remote_name_req_cancel_cp;
+} QEMU_PACKED remote_name_req_cancel_cp;
 #define REMOTE_NAME_REQ_CANCEL_CP_SIZE 6
 
 typedef struct {
     uint8_t            status;
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) remote_name_req_cancel_rp;
+} QEMU_PACKED remote_name_req_cancel_rp;
 #define REMOTE_NAME_REQ_CANCEL_RP_SIZE 7
 
 #define OCF_READ_REMOTE_FEATURES       0x001B
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) read_remote_features_cp;
+} QEMU_PACKED read_remote_features_cp;
 #define READ_REMOTE_FEATURES_CP_SIZE 2
 
 #define OCF_READ_REMOTE_EXT_FEATURES   0x001C
 typedef struct {
     uint16_t   handle;
     uint8_t    page_num;
-} __attribute__ ((packed)) read_remote_ext_features_cp;
+} QEMU_PACKED read_remote_ext_features_cp;
 #define READ_REMOTE_EXT_FEATURES_CP_SIZE 3
 
 #define OCF_READ_REMOTE_VERSION                0x001D
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) read_remote_version_cp;
+} QEMU_PACKED read_remote_version_cp;
 #define READ_REMOTE_VERSION_CP_SIZE 2
 
 #define OCF_READ_CLOCK_OFFSET          0x001F
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) read_clock_offset_cp;
+} QEMU_PACKED read_clock_offset_cp;
 #define READ_CLOCK_OFFSET_CP_SIZE 2
 
 #define OCF_READ_LMP_HANDLE            0x0020
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) read_lmp_handle_cp;
+} QEMU_PACKED read_lmp_handle_cp;
 #define READ_LMP_HANDLE_CP_SIZE 2
 
 typedef struct {
@@ -629,7 +629,7 @@ typedef struct {
     uint16_t   handle;
     uint8_t    lmp_handle;
     uint32_t   reserved;
-} __attribute__ ((packed)) read_lmp_handle_rp;
+} QEMU_PACKED read_lmp_handle_rp;
 #define READ_LMP_HANDLE_RP_SIZE 8
 
 #define OCF_SETUP_SYNC_CONN            0x0028
@@ -641,7 +641,7 @@ typedef struct {
     uint16_t   voice_setting;
     uint8_t    retrans_effort;
     uint16_t   pkt_type;
-} __attribute__ ((packed)) setup_sync_conn_cp;
+} QEMU_PACKED setup_sync_conn_cp;
 #define SETUP_SYNC_CONN_CP_SIZE 17
 
 #define OCF_ACCEPT_SYNC_CONN_REQ       0x0029
@@ -653,14 +653,14 @@ typedef struct {
     uint16_t   voice_setting;
     uint8_t    retrans_effort;
     uint16_t   pkt_type;
-} __attribute__ ((packed)) accept_sync_conn_req_cp;
+} QEMU_PACKED accept_sync_conn_req_cp;
 #define ACCEPT_SYNC_CONN_REQ_CP_SIZE 21
 
 #define OCF_REJECT_SYNC_CONN_REQ       0x002A
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    reason;
-} __attribute__ ((packed)) reject_sync_conn_req_cp;
+} QEMU_PACKED reject_sync_conn_req_cp;
 #define REJECT_SYNC_CONN_REQ_CP_SIZE 7
 
 /* Link Policy */
@@ -671,7 +671,7 @@ typedef struct {
     uint16_t   handle;
     uint16_t   max_interval;
     uint16_t   min_interval;
-} __attribute__ ((packed)) hold_mode_cp;
+} QEMU_PACKED hold_mode_cp;
 #define HOLD_MODE_CP_SIZE 6
 
 #define OCF_SNIFF_MODE                 0x0003
@@ -681,13 +681,13 @@ typedef struct {
     uint16_t   min_interval;
     uint16_t   attempt;
     uint16_t   timeout;
-} __attribute__ ((packed)) sniff_mode_cp;
+} QEMU_PACKED sniff_mode_cp;
 #define SNIFF_MODE_CP_SIZE 10
 
 #define OCF_EXIT_SNIFF_MODE            0x0004
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) exit_sniff_mode_cp;
+} QEMU_PACKED exit_sniff_mode_cp;
 #define EXIT_SNIFF_MODE_CP_SIZE 2
 
 #define OCF_PARK_MODE                  0x0005
@@ -695,13 +695,13 @@ typedef struct {
     uint16_t   handle;
     uint16_t   max_interval;
     uint16_t   min_interval;
-} __attribute__ ((packed)) park_mode_cp;
+} QEMU_PACKED park_mode_cp;
 #define PARK_MODE_CP_SIZE 6
 
 #define OCF_EXIT_PARK_MODE             0x0006
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) exit_park_mode_cp;
+} QEMU_PACKED exit_park_mode_cp;
 #define EXIT_PARK_MODE_CP_SIZE 2
 
 #define OCF_QOS_SETUP                  0x0007
@@ -711,56 +711,56 @@ typedef struct {
     uint32_t   peak_bandwidth;         /* Byte per seconds */
     uint32_t   latency;                /* Microseconds */
     uint32_t   delay_variation;        /* Microseconds */
-} __attribute__ ((packed)) hci_qos;
+} QEMU_PACKED hci_qos;
 #define HCI_QOS_CP_SIZE 17
 typedef struct {
     uint16_t   handle;
     uint8_t    flags;                  /* Reserved */
     hci_qos    qos;
-} __attribute__ ((packed)) qos_setup_cp;
+} QEMU_PACKED qos_setup_cp;
 #define QOS_SETUP_CP_SIZE (3 + HCI_QOS_CP_SIZE)
 
 #define OCF_ROLE_DISCOVERY             0x0009
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) role_discovery_cp;
+} QEMU_PACKED role_discovery_cp;
 #define ROLE_DISCOVERY_CP_SIZE 2
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint8_t    role;
-} __attribute__ ((packed)) role_discovery_rp;
+} QEMU_PACKED role_discovery_rp;
 #define ROLE_DISCOVERY_RP_SIZE 4
 
 #define OCF_SWITCH_ROLE                        0x000B
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    role;
-} __attribute__ ((packed)) switch_role_cp;
+} QEMU_PACKED switch_role_cp;
 #define SWITCH_ROLE_CP_SIZE 7
 
 #define OCF_READ_LINK_POLICY           0x000C
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) read_link_policy_cp;
+} QEMU_PACKED read_link_policy_cp;
 #define READ_LINK_POLICY_CP_SIZE 2
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint16_t   policy;
-} __attribute__ ((packed)) read_link_policy_rp;
+} QEMU_PACKED read_link_policy_rp;
 #define READ_LINK_POLICY_RP_SIZE 5
 
 #define OCF_WRITE_LINK_POLICY          0x000D
 typedef struct {
     uint16_t   handle;
     uint16_t   policy;
-} __attribute__ ((packed)) write_link_policy_cp;
+} QEMU_PACKED write_link_policy_cp;
 #define WRITE_LINK_POLICY_CP_SIZE 4
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
-} __attribute__ ((packed)) write_link_policy_rp;
+} QEMU_PACKED write_link_policy_rp;
 #define WRITE_LINK_POLICY_RP_SIZE 3
 
 #define OCF_READ_DEFAULT_LINK_POLICY   0x000E
@@ -776,7 +776,7 @@ typedef struct {
     uint16_t   max_local_latency;
     uint16_t   min_remote_timeout;
     uint16_t   min_local_timeout;
-} __attribute__ ((packed)) sniff_subrate_cp;
+} QEMU_PACKED sniff_subrate_cp;
 #define SNIFF_SUBRATE_CP_SIZE 10
 
 /* Host Controller and Baseband */
@@ -785,7 +785,7 @@ typedef struct {
 #define OCF_SET_EVENT_MASK             0x0001
 typedef struct {
     uint8_t    mask[8];
-} __attribute__ ((packed)) set_event_mask_cp;
+} QEMU_PACKED set_event_mask_cp;
 #define SET_EVENT_MASK_CP_SIZE 8
 
 #define OCF_RESET                      0x0003
@@ -795,7 +795,7 @@ typedef struct {
     uint8_t    flt_type;
     uint8_t    cond_type;
     uint8_t    condition[0];
-} __attribute__ ((packed)) set_event_flt_cp;
+} QEMU_PACKED set_event_flt_cp;
 #define SET_EVENT_FLT_CP_SIZE 2
 
 enum bt_filter_type {
@@ -821,26 +821,26 @@ enum conn_setup_cond {
 #define OCF_FLUSH                      0x0008
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) flush_cp;
+} QEMU_PACKED flush_cp;
 #define FLUSH_CP_SIZE 2
 
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
-} __attribute__ ((packed)) flush_rp;
+} QEMU_PACKED flush_rp;
 #define FLUSH_RP_SIZE 3
 
 #define OCF_READ_PIN_TYPE              0x0009
 typedef struct {
     uint8_t    status;
     uint8_t    pin_type;
-} __attribute__ ((packed)) read_pin_type_rp;
+} QEMU_PACKED read_pin_type_rp;
 #define READ_PIN_TYPE_RP_SIZE 2
 
 #define OCF_WRITE_PIN_TYPE             0x000A
 typedef struct {
     uint8_t    pin_type;
-} __attribute__ ((packed)) write_pin_type_cp;
+} QEMU_PACKED write_pin_type_cp;
 #define WRITE_PIN_TYPE_CP_SIZE 1
 
 #define OCF_CREATE_NEW_UNIT_KEY                0x000B
@@ -849,89 +849,89 @@ typedef struct {
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    read_all;
-} __attribute__ ((packed)) read_stored_link_key_cp;
+} QEMU_PACKED read_stored_link_key_cp;
 #define READ_STORED_LINK_KEY_CP_SIZE 7
 typedef struct {
     uint8_t    status;
     uint16_t   max_keys;
     uint16_t   num_keys;
-} __attribute__ ((packed)) read_stored_link_key_rp;
+} QEMU_PACKED read_stored_link_key_rp;
 #define READ_STORED_LINK_KEY_RP_SIZE 5
 
 #define OCF_WRITE_STORED_LINK_KEY      0x0011
 typedef struct {
     uint8_t    num_keys;
     /* variable length part */
-} __attribute__ ((packed)) write_stored_link_key_cp;
+} QEMU_PACKED write_stored_link_key_cp;
 #define WRITE_STORED_LINK_KEY_CP_SIZE 1
 typedef struct {
     uint8_t    status;
     uint8_t    num_keys;
-} __attribute__ ((packed)) write_stored_link_key_rp;
+} QEMU_PACKED write_stored_link_key_rp;
 #define READ_WRITE_LINK_KEY_RP_SIZE 2
 
 #define OCF_DELETE_STORED_LINK_KEY     0x0012
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    delete_all;
-} __attribute__ ((packed)) delete_stored_link_key_cp;
+} QEMU_PACKED delete_stored_link_key_cp;
 #define DELETE_STORED_LINK_KEY_CP_SIZE 7
 typedef struct {
     uint8_t    status;
     uint16_t   num_keys;
-} __attribute__ ((packed)) delete_stored_link_key_rp;
+} QEMU_PACKED delete_stored_link_key_rp;
 #define DELETE_STORED_LINK_KEY_RP_SIZE 3
 
 #define OCF_CHANGE_LOCAL_NAME          0x0013
 typedef struct {
     char       name[248];
-} __attribute__ ((packed)) change_local_name_cp;
+} QEMU_PACKED change_local_name_cp;
 #define CHANGE_LOCAL_NAME_CP_SIZE 248 
 
 #define OCF_READ_LOCAL_NAME            0x0014
 typedef struct {
     uint8_t    status;
     char       name[248];
-} __attribute__ ((packed)) read_local_name_rp;
+} QEMU_PACKED read_local_name_rp;
 #define READ_LOCAL_NAME_RP_SIZE 249 
 
 #define OCF_READ_CONN_ACCEPT_TIMEOUT   0x0015
 typedef struct {
     uint8_t    status;
     uint16_t   timeout;
-} __attribute__ ((packed)) read_conn_accept_timeout_rp;
+} QEMU_PACKED read_conn_accept_timeout_rp;
 #define READ_CONN_ACCEPT_TIMEOUT_RP_SIZE 3
 
 #define OCF_WRITE_CONN_ACCEPT_TIMEOUT  0x0016
 typedef struct {
     uint16_t   timeout;
-} __attribute__ ((packed)) write_conn_accept_timeout_cp;
+} QEMU_PACKED write_conn_accept_timeout_cp;
 #define WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE 2
 
 #define OCF_READ_PAGE_TIMEOUT          0x0017
 typedef struct {
     uint8_t    status;
     uint16_t   timeout;
-} __attribute__ ((packed)) read_page_timeout_rp;
+} QEMU_PACKED read_page_timeout_rp;
 #define READ_PAGE_TIMEOUT_RP_SIZE 3
 
 #define OCF_WRITE_PAGE_TIMEOUT         0x0018
 typedef struct {
     uint16_t   timeout;
-} __attribute__ ((packed)) write_page_timeout_cp;
+} QEMU_PACKED write_page_timeout_cp;
 #define WRITE_PAGE_TIMEOUT_CP_SIZE 2
 
 #define OCF_READ_SCAN_ENABLE           0x0019
 typedef struct {
     uint8_t    status;
     uint8_t    enable;
-} __attribute__ ((packed)) read_scan_enable_rp;
+} QEMU_PACKED read_scan_enable_rp;
 #define READ_SCAN_ENABLE_RP_SIZE 2
 
 #define OCF_WRITE_SCAN_ENABLE          0x001A
 typedef struct {
     uint8_t    scan_enable;
-} __attribute__ ((packed)) write_scan_enable_cp;
+} QEMU_PACKED write_scan_enable_cp;
 #define WRITE_SCAN_ENABLE_CP_SIZE 1
 
 enum scan_enable_bits {
@@ -945,14 +945,14 @@ typedef struct {
     uint8_t    status;
     uint16_t   interval;
     uint16_t   window;
-} __attribute__ ((packed)) read_page_activity_rp;
+} QEMU_PACKED read_page_activity_rp;
 #define READ_PAGE_ACTIVITY_RP_SIZE 5
 
 #define OCF_WRITE_PAGE_ACTIVITY                0x001C
 typedef struct {
     uint16_t   interval;
     uint16_t   window;
-} __attribute__ ((packed)) write_page_activity_cp;
+} QEMU_PACKED write_page_activity_cp;
 #define WRITE_PAGE_ACTIVITY_CP_SIZE 4
 
 #define OCF_READ_INQ_ACTIVITY          0x001D
@@ -960,14 +960,14 @@ typedef struct {
     uint8_t    status;
     uint16_t   interval;
     uint16_t   window;
-} __attribute__ ((packed)) read_inq_activity_rp;
+} QEMU_PACKED read_inq_activity_rp;
 #define READ_INQ_ACTIVITY_RP_SIZE 5
 
 #define OCF_WRITE_INQ_ACTIVITY         0x001E
 typedef struct {
     uint16_t   interval;
     uint16_t   window;
-} __attribute__ ((packed)) write_inq_activity_cp;
+} QEMU_PACKED write_inq_activity_cp;
 #define WRITE_INQ_ACTIVITY_CP_SIZE 4
 
 #define OCF_READ_AUTH_ENABLE           0x001F
@@ -989,26 +989,26 @@ typedef struct {
 typedef struct {
     uint8_t    status;
     uint8_t    dev_class[3];
-} __attribute__ ((packed)) read_class_of_dev_rp;
+} QEMU_PACKED read_class_of_dev_rp;
 #define READ_CLASS_OF_DEV_RP_SIZE 4 
 
 #define OCF_WRITE_CLASS_OF_DEV         0x0024
 typedef struct {
     uint8_t    dev_class[3];
-} __attribute__ ((packed)) write_class_of_dev_cp;
+} QEMU_PACKED write_class_of_dev_cp;
 #define WRITE_CLASS_OF_DEV_CP_SIZE 3
 
 #define OCF_READ_VOICE_SETTING         0x0025
 typedef struct {
     uint8_t    status;
     uint16_t   voice_setting;
-} __attribute__ ((packed)) read_voice_setting_rp;
+} QEMU_PACKED read_voice_setting_rp;
 #define READ_VOICE_SETTING_RP_SIZE 3
 
 #define OCF_WRITE_VOICE_SETTING                0x0026
 typedef struct {
     uint16_t   voice_setting;
-} __attribute__ ((packed)) write_voice_setting_cp;
+} QEMU_PACKED write_voice_setting_cp;
 #define WRITE_VOICE_SETTING_CP_SIZE 2
 
 #define OCF_READ_AUTOMATIC_FLUSH_TIMEOUT       0x0027
@@ -1027,13 +1027,13 @@ typedef struct {
 typedef struct {
     uint16_t   handle;
     uint8_t    type;
-} __attribute__ ((packed)) read_transmit_power_level_cp;
+} QEMU_PACKED read_transmit_power_level_cp;
 #define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
     int8_t     level;
-} __attribute__ ((packed)) read_transmit_power_level_rp;
+} QEMU_PACKED read_transmit_power_level_rp;
 #define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4
 
 #define OCF_HOST_BUFFER_SIZE           0x0033
@@ -1042,7 +1042,7 @@ typedef struct {
     uint8_t    sco_mtu;
     uint16_t   acl_max_pkt;
     uint16_t   sco_max_pkt;
-} __attribute__ ((packed)) host_buffer_size_cp;
+} QEMU_PACKED host_buffer_size_cp;
 #define HOST_BUFFER_SIZE_CP_SIZE 7
 
 #define OCF_HOST_NUMBER_OF_COMPLETED_PACKETS   0x0035
@@ -1052,19 +1052,19 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint16_t   link_sup_to;
-} __attribute__ ((packed)) read_link_supervision_timeout_rp;
+} QEMU_PACKED read_link_supervision_timeout_rp;
 #define READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE 5
 
 #define OCF_WRITE_LINK_SUPERVISION_TIMEOUT     0x0037
 typedef struct {
     uint16_t   handle;
     uint16_t   link_sup_to;
-} __attribute__ ((packed)) write_link_supervision_timeout_cp;
+} QEMU_PACKED write_link_supervision_timeout_cp;
 #define WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE 4
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
-} __attribute__ ((packed)) write_link_supervision_timeout_rp;
+} QEMU_PACKED write_link_supervision_timeout_rp;
 #define WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE 3
 
 #define OCF_READ_NUM_SUPPORTED_IAC     0x0038
@@ -1075,14 +1075,14 @@ typedef struct {
     uint8_t    status;
     uint8_t    num_current_iac;
     uint8_t    lap[MAX_IAC_LAP][3];
-} __attribute__ ((packed)) read_current_iac_lap_rp;
+} QEMU_PACKED read_current_iac_lap_rp;
 #define READ_CURRENT_IAC_LAP_RP_SIZE 2+3*MAX_IAC_LAP
 
 #define OCF_WRITE_CURRENT_IAC_LAP      0x003A
 typedef struct {
     uint8_t    num_current_iac;
     uint8_t    lap[MAX_IAC_LAP][3];
-} __attribute__ ((packed)) write_current_iac_lap_cp;
+} QEMU_PACKED write_current_iac_lap_cp;
 #define WRITE_CURRENT_IAC_LAP_CP_SIZE 1+3*MAX_IAC_LAP
 
 #define OCF_READ_PAGE_SCAN_PERIOD_MODE 0x003B
@@ -1096,45 +1096,45 @@ typedef struct {
 #define OCF_SET_AFH_CLASSIFICATION     0x003F
 typedef struct {
     uint8_t    map[10];
-} __attribute__ ((packed)) set_afh_classification_cp;
+} QEMU_PACKED set_afh_classification_cp;
 #define SET_AFH_CLASSIFICATION_CP_SIZE 10
 typedef struct {
     uint8_t    status;
-} __attribute__ ((packed)) set_afh_classification_rp;
+} QEMU_PACKED set_afh_classification_rp;
 #define SET_AFH_CLASSIFICATION_RP_SIZE 1
 
 #define OCF_READ_INQUIRY_SCAN_TYPE     0x0042
 typedef struct {
     uint8_t    status;
     uint8_t    type;
-} __attribute__ ((packed)) read_inquiry_scan_type_rp;
+} QEMU_PACKED read_inquiry_scan_type_rp;
 #define READ_INQUIRY_SCAN_TYPE_RP_SIZE 2
 
 #define OCF_WRITE_INQUIRY_SCAN_TYPE    0x0043
 typedef struct {
     uint8_t    type;
-} __attribute__ ((packed)) write_inquiry_scan_type_cp;
+} QEMU_PACKED write_inquiry_scan_type_cp;
 #define WRITE_INQUIRY_SCAN_TYPE_CP_SIZE 1
 typedef struct {
     uint8_t    status;
-} __attribute__ ((packed)) write_inquiry_scan_type_rp;
+} QEMU_PACKED write_inquiry_scan_type_rp;
 #define WRITE_INQUIRY_SCAN_TYPE_RP_SIZE 1
 
 #define OCF_READ_INQUIRY_MODE          0x0044
 typedef struct {
     uint8_t    status;
     uint8_t    mode;
-} __attribute__ ((packed)) read_inquiry_mode_rp;
+} QEMU_PACKED read_inquiry_mode_rp;
 #define READ_INQUIRY_MODE_RP_SIZE 2
 
 #define OCF_WRITE_INQUIRY_MODE         0x0045
 typedef struct {
     uint8_t    mode;
-} __attribute__ ((packed)) write_inquiry_mode_cp;
+} QEMU_PACKED write_inquiry_mode_cp;
 #define WRITE_INQUIRY_MODE_CP_SIZE 1
 typedef struct {
     uint8_t    status;
-} __attribute__ ((packed)) write_inquiry_mode_rp;
+} QEMU_PACKED write_inquiry_mode_rp;
 #define WRITE_INQUIRY_MODE_RP_SIZE 1
 
 #define OCF_READ_PAGE_SCAN_TYPE                0x0046
@@ -1145,17 +1145,17 @@ typedef struct {
 typedef struct {
     uint8_t    status;
     uint8_t    mode;
-} __attribute__ ((packed)) read_afh_mode_rp;
+} QEMU_PACKED read_afh_mode_rp;
 #define READ_AFH_MODE_RP_SIZE 2
 
 #define OCF_WRITE_AFH_MODE             0x0049
 typedef struct {
     uint8_t    mode;
-} __attribute__ ((packed)) write_afh_mode_cp;
+} QEMU_PACKED write_afh_mode_cp;
 #define WRITE_AFH_MODE_CP_SIZE 1
 typedef struct {
     uint8_t    status;
-} __attribute__ ((packed)) write_afh_mode_rp;
+} QEMU_PACKED write_afh_mode_rp;
 #define WRITE_AFH_MODE_RP_SIZE 1
 
 #define OCF_READ_EXT_INQUIRY_RESPONSE  0x0051
@@ -1163,18 +1163,18 @@ typedef struct {
     uint8_t    status;
     uint8_t    fec;
     uint8_t    data[240];
-} __attribute__ ((packed)) read_ext_inquiry_response_rp;
+} QEMU_PACKED read_ext_inquiry_response_rp;
 #define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242
 
 #define OCF_WRITE_EXT_INQUIRY_RESPONSE 0x0052
 typedef struct {
     uint8_t    fec;
     uint8_t    data[240];
-} __attribute__ ((packed)) write_ext_inquiry_response_cp;
+} QEMU_PACKED write_ext_inquiry_response_cp;
 #define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241
 typedef struct {
     uint8_t    status;
-} __attribute__ ((packed)) write_ext_inquiry_response_rp;
+} QEMU_PACKED write_ext_inquiry_response_rp;
 #define WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE 1
 
 /* Informational Parameters */
@@ -1188,34 +1188,34 @@ typedef struct {
     uint8_t    lmp_ver;
     uint16_t   manufacturer;
     uint16_t   lmp_subver;
-} __attribute__ ((packed)) read_local_version_rp;
+} QEMU_PACKED read_local_version_rp;
 #define READ_LOCAL_VERSION_RP_SIZE 9
 
 #define OCF_READ_LOCAL_COMMANDS                0x0002
 typedef struct {
     uint8_t    status;
     uint8_t    commands[64];
-} __attribute__ ((packed)) read_local_commands_rp;
+} QEMU_PACKED read_local_commands_rp;
 #define READ_LOCAL_COMMANDS_RP_SIZE 65
 
 #define OCF_READ_LOCAL_FEATURES                0x0003
 typedef struct {
     uint8_t    status;
     uint8_t    features[8];
-} __attribute__ ((packed)) read_local_features_rp;
+} QEMU_PACKED read_local_features_rp;
 #define READ_LOCAL_FEATURES_RP_SIZE 9
 
 #define OCF_READ_LOCAL_EXT_FEATURES    0x0004
 typedef struct {
     uint8_t    page_num;
-} __attribute__ ((packed)) read_local_ext_features_cp;
+} QEMU_PACKED read_local_ext_features_cp;
 #define READ_LOCAL_EXT_FEATURES_CP_SIZE 1
 typedef struct {
     uint8_t    status;
     uint8_t    page_num;
     uint8_t    max_page_num;
     uint8_t    features[8];
-} __attribute__ ((packed)) read_local_ext_features_rp;
+} QEMU_PACKED read_local_ext_features_rp;
 #define READ_LOCAL_EXT_FEATURES_RP_SIZE 11
 
 #define OCF_READ_BUFFER_SIZE           0x0005
@@ -1225,21 +1225,21 @@ typedef struct {
     uint8_t    sco_mtu;
     uint16_t   acl_max_pkt;
     uint16_t   sco_max_pkt;
-} __attribute__ ((packed)) read_buffer_size_rp;
+} QEMU_PACKED read_buffer_size_rp;
 #define READ_BUFFER_SIZE_RP_SIZE 8
 
 #define OCF_READ_COUNTRY_CODE          0x0007
 typedef struct {
     uint8_t    status;
     uint8_t    country_code;
-} __attribute__ ((packed)) read_country_code_rp;
+} QEMU_PACKED read_country_code_rp;
 #define READ_COUNTRY_CODE_RP_SIZE 2
 
 #define OCF_READ_BD_ADDR               0x0009
 typedef struct {
     uint8_t    status;
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) read_bd_addr_rp;
+} QEMU_PACKED read_bd_addr_rp;
 #define READ_BD_ADDR_RP_SIZE 7
 
 /* Status params */
@@ -1250,27 +1250,27 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint8_t    counter;
-} __attribute__ ((packed)) read_failed_contact_counter_rp;
+} QEMU_PACKED read_failed_contact_counter_rp;
 #define READ_FAILED_CONTACT_COUNTER_RP_SIZE 4
 
 #define OCF_RESET_FAILED_CONTACT_COUNTER       0x0002
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
-} __attribute__ ((packed)) reset_failed_contact_counter_rp;
+} QEMU_PACKED reset_failed_contact_counter_rp;
 #define RESET_FAILED_CONTACT_COUNTER_RP_SIZE 4
 
 #define OCF_READ_LINK_QUALITY          0x0003
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) read_link_quality_cp;
+} QEMU_PACKED read_link_quality_cp;
 #define READ_LINK_QUALITY_CP_SIZE 4
 
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint8_t    link_quality;
-} __attribute__ ((packed)) read_link_quality_rp;
+} QEMU_PACKED read_link_quality_rp;
 #define READ_LINK_QUALITY_RP_SIZE 4
 
 #define OCF_READ_RSSI                  0x0005
@@ -1278,7 +1278,7 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     int8_t     rssi;
-} __attribute__ ((packed)) read_rssi_rp;
+} QEMU_PACKED read_rssi_rp;
 #define READ_RSSI_RP_SIZE 4
 
 #define OCF_READ_AFH_MAP               0x0006
@@ -1287,21 +1287,21 @@ typedef struct {
     uint16_t   handle;
     uint8_t    mode;
     uint8_t    map[10];
-} __attribute__ ((packed)) read_afh_map_rp;
+} QEMU_PACKED read_afh_map_rp;
 #define READ_AFH_MAP_RP_SIZE 14
 
 #define OCF_READ_CLOCK                 0x0007
 typedef struct {
     uint16_t   handle;
     uint8_t    which_clock;
-} __attribute__ ((packed)) read_clock_cp;
+} QEMU_PACKED read_clock_cp;
 #define READ_CLOCK_CP_SIZE 3
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint32_t   clock;
     uint16_t   accuracy;
-} __attribute__ ((packed)) read_clock_rp;
+} QEMU_PACKED read_clock_rp;
 #define READ_CLOCK_RP_SIZE 9
 
 /* Testing commands */
@@ -1323,7 +1323,7 @@ typedef struct {
     uint8_t    pscan_mode;
     uint8_t    dev_class[3];
     uint16_t   clock_offset;
-} __attribute__ ((packed)) inquiry_info;
+} QEMU_PACKED inquiry_info;
 #define INQUIRY_INFO_SIZE 14
 
 #define EVT_CONN_COMPLETE              0x03
@@ -1333,7 +1333,7 @@ typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    link_type;
     uint8_t    encr_mode;
-} __attribute__ ((packed)) evt_conn_complete;
+} QEMU_PACKED evt_conn_complete;
 #define EVT_CONN_COMPLETE_SIZE 11
 
 #define EVT_CONN_REQUEST               0x04
@@ -1341,7 +1341,7 @@ typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    dev_class[3];
     uint8_t    link_type;
-} __attribute__ ((packed)) evt_conn_request;
+} QEMU_PACKED evt_conn_request;
 #define EVT_CONN_REQUEST_SIZE 10
 
 #define EVT_DISCONN_COMPLETE           0x05
@@ -1349,14 +1349,14 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint8_t    reason;
-} __attribute__ ((packed)) evt_disconn_complete;
+} QEMU_PACKED evt_disconn_complete;
 #define EVT_DISCONN_COMPLETE_SIZE 4
 
 #define EVT_AUTH_COMPLETE              0x06
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
-} __attribute__ ((packed)) evt_auth_complete;
+} QEMU_PACKED evt_auth_complete;
 #define EVT_AUTH_COMPLETE_SIZE 3
 
 #define EVT_REMOTE_NAME_REQ_COMPLETE   0x07
@@ -1364,7 +1364,7 @@ typedef struct {
     uint8_t    status;
     bdaddr_t   bdaddr;
     char       name[248];
-} __attribute__ ((packed)) evt_remote_name_req_complete;
+} QEMU_PACKED evt_remote_name_req_complete;
 #define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
 
 #define EVT_ENCRYPT_CHANGE             0x08
@@ -1372,14 +1372,14 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint8_t    encrypt;
-} __attribute__ ((packed)) evt_encrypt_change;
+} QEMU_PACKED evt_encrypt_change;
 #define EVT_ENCRYPT_CHANGE_SIZE 5
 
 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE      0x09
 typedef struct {
     uint8_t    status;
     uint16_t   handle;
-}  __attribute__ ((packed)) evt_change_conn_link_key_complete;
+}  QEMU_PACKED evt_change_conn_link_key_complete;
 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE 3
 
 #define EVT_MASTER_LINK_KEY_COMPLETE           0x0A
@@ -1387,7 +1387,7 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint8_t    key_flag;
-} __attribute__ ((packed)) evt_master_link_key_complete;
+} QEMU_PACKED evt_master_link_key_complete;
 #define EVT_MASTER_LINK_KEY_COMPLETE_SIZE 4
 
 #define EVT_READ_REMOTE_FEATURES_COMPLETE      0x0B
@@ -1395,7 +1395,7 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint8_t    features[8];
-} __attribute__ ((packed)) evt_read_remote_features_complete;
+} QEMU_PACKED evt_read_remote_features_complete;
 #define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
 
 #define EVT_READ_REMOTE_VERSION_COMPLETE       0x0C
@@ -1405,7 +1405,7 @@ typedef struct {
     uint8_t    lmp_ver;
     uint16_t   manufacturer;
     uint16_t   lmp_subver;
-} __attribute__ ((packed)) evt_read_remote_version_complete;
+} QEMU_PACKED evt_read_remote_version_complete;
 #define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
 
 #define EVT_QOS_SETUP_COMPLETE         0x0D
@@ -1414,14 +1414,14 @@ typedef struct {
     uint16_t   handle;
     uint8_t    flags;                  /* Reserved */
     hci_qos    qos;
-} __attribute__ ((packed)) evt_qos_setup_complete;
+} QEMU_PACKED evt_qos_setup_complete;
 #define EVT_QOS_SETUP_COMPLETE_SIZE (4 + HCI_QOS_CP_SIZE)
 
 #define EVT_CMD_COMPLETE               0x0E
 typedef struct {
     uint8_t    ncmd;
     uint16_t   opcode;
-} __attribute__ ((packed)) evt_cmd_complete;
+} QEMU_PACKED evt_cmd_complete;
 #define EVT_CMD_COMPLETE_SIZE 3
 
 #define EVT_CMD_STATUS                         0x0F
@@ -1429,19 +1429,19 @@ typedef struct {
     uint8_t    status;
     uint8_t    ncmd;
     uint16_t   opcode;
-} __attribute__ ((packed)) evt_cmd_status;
+} QEMU_PACKED evt_cmd_status;
 #define EVT_CMD_STATUS_SIZE 4
 
 #define EVT_HARDWARE_ERROR             0x10
 typedef struct {
     uint8_t    code;
-} __attribute__ ((packed)) evt_hardware_error;
+} QEMU_PACKED evt_hardware_error;
 #define EVT_HARDWARE_ERROR_SIZE 1
 
 #define EVT_FLUSH_OCCURRED             0x11
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) evt_flush_occurred;
+} QEMU_PACKED evt_flush_occurred;
 #define EVT_FLUSH_OCCURRED_SIZE 2
 
 #define EVT_ROLE_CHANGE                        0x12
@@ -1449,7 +1449,7 @@ typedef struct {
     uint8_t    status;
     bdaddr_t   bdaddr;
     uint8_t    role;
-} __attribute__ ((packed)) evt_role_change;
+} QEMU_PACKED evt_role_change;
 #define EVT_ROLE_CHANGE_SIZE 8
 
 #define EVT_NUM_COMP_PKTS              0x13
@@ -1459,7 +1459,7 @@ typedef struct {
         uint16_t handle;
         uint16_t num_packets;
     } connection[0];
-} __attribute__ ((packed)) evt_num_comp_pkts;
+} QEMU_PACKED evt_num_comp_pkts;
 #define EVT_NUM_COMP_PKTS_SIZE(num_hndl) (1 + 4 * (num_hndl))
 
 #define EVT_MODE_CHANGE                        0x14
@@ -1468,26 +1468,26 @@ typedef struct {
     uint16_t   handle;
     uint8_t    mode;
     uint16_t   interval;
-} __attribute__ ((packed)) evt_mode_change;
+} QEMU_PACKED evt_mode_change;
 #define EVT_MODE_CHANGE_SIZE 6
 
 #define EVT_RETURN_LINK_KEYS           0x15
 typedef struct {
     uint8_t    num_keys;
     /* variable length part */
-} __attribute__ ((packed)) evt_return_link_keys;
+} QEMU_PACKED evt_return_link_keys;
 #define EVT_RETURN_LINK_KEYS_SIZE 1
 
 #define EVT_PIN_CODE_REQ               0x16
 typedef struct {
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) evt_pin_code_req;
+} QEMU_PACKED evt_pin_code_req;
 #define EVT_PIN_CODE_REQ_SIZE 6
 
 #define EVT_LINK_KEY_REQ               0x17
 typedef struct {
     bdaddr_t   bdaddr;
-} __attribute__ ((packed)) evt_link_key_req;
+} QEMU_PACKED evt_link_key_req;
 #define EVT_LINK_KEY_REQ_SIZE 6
 
 #define EVT_LINK_KEY_NOTIFY            0x18
@@ -1495,7 +1495,7 @@ typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    link_key[16];
     uint8_t    key_type;
-} __attribute__ ((packed)) evt_link_key_notify;
+} QEMU_PACKED evt_link_key_notify;
 #define EVT_LINK_KEY_NOTIFY_SIZE 23
 
 #define EVT_LOOPBACK_COMMAND           0x19
@@ -1503,14 +1503,14 @@ typedef struct {
 #define EVT_DATA_BUFFER_OVERFLOW       0x1A
 typedef struct {
     uint8_t    link_type;
-} __attribute__ ((packed)) evt_data_buffer_overflow;
+} QEMU_PACKED evt_data_buffer_overflow;
 #define EVT_DATA_BUFFER_OVERFLOW_SIZE 1
 
 #define EVT_MAX_SLOTS_CHANGE           0x1B
 typedef struct {
     uint16_t   handle;
     uint8_t    max_slots;
-} __attribute__ ((packed)) evt_max_slots_change;
+} QEMU_PACKED evt_max_slots_change;
 #define EVT_MAX_SLOTS_CHANGE_SIZE 3
 
 #define EVT_READ_CLOCK_OFFSET_COMPLETE 0x1C
@@ -1518,7 +1518,7 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint16_t   clock_offset;
-} __attribute__ ((packed)) evt_read_clock_offset_complete;
+} QEMU_PACKED evt_read_clock_offset_complete;
 #define EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE 5
 
 #define EVT_CONN_PTYPE_CHANGED         0x1D
@@ -1526,20 +1526,20 @@ typedef struct {
     uint8_t    status;
     uint16_t   handle;
     uint16_t   ptype;
-} __attribute__ ((packed)) evt_conn_ptype_changed;
+} QEMU_PACKED evt_conn_ptype_changed;
 #define EVT_CONN_PTYPE_CHANGED_SIZE 5
 
 #define EVT_QOS_VIOLATION              0x1E
 typedef struct {
     uint16_t   handle;
-} __attribute__ ((packed)) evt_qos_violation;
+} QEMU_PACKED evt_qos_violation;
 #define EVT_QOS_VIOLATION_SIZE 2
 
 #define EVT_PSCAN_REP_MODE_CHANGE      0x20
 typedef struct {
     bdaddr_t   bdaddr;
     uint8_t    pscan_rep_mode;
-} __attribute__ ((packed)) evt_pscan_rep_mode_change;
+} QEMU_PACKED evt_pscan_rep_mode_change;
 #define EVT_PSCAN_REP_MODE_CHANGE_SIZE 7
 
 #define EVT_FLOW_SPEC_COMPLETE         0x21
@@ -1549,7 +1549,7 @@ typedef struct {
     uint8_t    flags;
     uint8_t    direction;
     hci_qos    qos;
-} __attribute__ ((packed)) evt_flow_spec_complete;
+} QEMU_PACKED evt_flow_spec_complete;
 #define EVT_FLOW_SPEC_COMPLETE_SIZE (5 + HCI_QOS_CP_SIZE)
 
 #define EVT_INQUIRY_RESULT_WITH_RSSI   0x22
@@ -1561,7 +1561,7 @@ typedef struct {
     uint8_t    dev_class[3];
     uint16_t   clock_offset;
     int8_t     rssi;
-} __attribute__ ((packed)) inquiry_info_with_rssi;
+} QEMU_PACKED inquiry_info_with_rssi;
 #define INQUIRY_INFO_WITH_RSSI_SIZE 15
 typedef struct {
     uint8_t    num_responses;
@@ -1572,7 +1572,7 @@ typedef struct {
     uint8_t    dev_class[3];
     uint16_t   clock_offset;
     int8_t     rssi;
-} __attribute__ ((packed)) inquiry_info_with_rssi_and_pscan_mode;
+} QEMU_PACKED inquiry_info_with_rssi_and_pscan_mode;
 #define INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE 16
 
 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE  0x23
@@ -1582,7 +1582,7 @@ typedef struct {
     uint8_t    page_num;
     uint8_t    max_page_num;
     uint8_t    features[8];
-} __attribute__ ((packed)) evt_read_remote_ext_features_complete;
+} QEMU_PACKED evt_read_remote_ext_features_complete;
 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE 13
 
 #define EVT_SYNC_CONN_COMPLETE         0x2C
@@ -1596,7 +1596,7 @@ typedef struct {
     uint16_t   rx_pkt_len;
     uint16_t   tx_pkt_len;
     uint8_t    air_mode;
-} __attribute__ ((packed)) evt_sync_conn_complete;
+} QEMU_PACKED evt_sync_conn_complete;
 #define EVT_SYNC_CONN_COMPLETE_SIZE 17
 
 #define EVT_SYNC_CONN_CHANGED          0x2D
@@ -1607,7 +1607,7 @@ typedef struct {
     uint8_t    retrans_window;
     uint16_t   rx_pkt_len;
     uint16_t   tx_pkt_len;
-} __attribute__ ((packed)) evt_sync_conn_changed;
+} QEMU_PACKED evt_sync_conn_changed;
 #define EVT_SYNC_CONN_CHANGED_SIZE 9
 
 #define EVT_SNIFF_SUBRATE              0x2E
@@ -1618,7 +1618,7 @@ typedef struct {
     uint16_t   max_local_latency;
     uint16_t   min_remote_timeout;
     uint16_t   min_local_timeout;
-} __attribute__ ((packed)) evt_sniff_subrate;
+} QEMU_PACKED evt_sniff_subrate;
 #define EVT_SNIFF_SUBRATE_SIZE 11
 
 #define EVT_EXTENDED_INQUIRY_RESULT    0x2F
@@ -1630,7 +1630,7 @@ typedef struct {
     uint16_t   clock_offset;
     int8_t     rssi;
     uint8_t    data[240];
-} __attribute__ ((packed)) extended_inquiry_info;
+} QEMU_PACKED extended_inquiry_info;
 #define EXTENDED_INQUIRY_INFO_SIZE 254
 
 #define EVT_TESTING                    0xFE
@@ -1656,22 +1656,22 @@ typedef struct {
 struct hci_command_hdr {
     uint16_t   opcode;         /* OCF & OGF */
     uint8_t    plen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_event_hdr {
     uint8_t    evt;
     uint8_t    plen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_acl_hdr {
     uint16_t   handle;         /* Handle & Flags(PB, BC) */
     uint16_t   dlen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_sco_hdr {
     uint16_t   handle;
     uint8_t    dlen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 /* L2CAP layer defines */
 
@@ -1718,25 +1718,25 @@ typedef struct {
     uint16_t   len;
     uint16_t   cid;
     uint8_t    data[0];
-} __attribute__ ((packed)) l2cap_hdr;
+} QEMU_PACKED l2cap_hdr;
 #define L2CAP_HDR_SIZE 4
 
 typedef struct {
     uint8_t    code;
     uint8_t    ident;
     uint16_t   len;
-} __attribute__ ((packed)) l2cap_cmd_hdr;
+} QEMU_PACKED l2cap_cmd_hdr;
 #define L2CAP_CMD_HDR_SIZE 4
 
 typedef struct {
     uint16_t   reason;
-} __attribute__ ((packed)) l2cap_cmd_rej;
+} QEMU_PACKED l2cap_cmd_rej;
 #define L2CAP_CMD_REJ_SIZE 2
 
 typedef struct {
     uint16_t   dcid;
     uint16_t   scid;
-} __attribute__ ((packed)) l2cap_cmd_rej_cid;
+} QEMU_PACKED l2cap_cmd_rej_cid;
 #define L2CAP_CMD_REJ_CID_SIZE 4
 
 /* reject reason */
@@ -1749,7 +1749,7 @@ enum bt_l2cap_rej_reason {
 typedef struct {
     uint16_t   psm;
     uint16_t   scid;
-} __attribute__ ((packed)) l2cap_conn_req;
+} QEMU_PACKED l2cap_conn_req;
 #define L2CAP_CONN_REQ_SIZE 4
 
 typedef struct {
@@ -1757,7 +1757,7 @@ typedef struct {
     uint16_t   scid;
     uint16_t   result;
     uint16_t   status;
-} __attribute__ ((packed)) l2cap_conn_rsp;
+} QEMU_PACKED l2cap_conn_rsp;
 #define L2CAP_CONN_RSP_SIZE 8
 
 /* connect result */
@@ -1780,7 +1780,7 @@ typedef struct {
     uint16_t   dcid;
     uint16_t   flags;
     uint8_t    data[0];
-} __attribute__ ((packed)) l2cap_conf_req;
+} QEMU_PACKED l2cap_conf_req;
 #define L2CAP_CONF_REQ_SIZE(datalen) (4 + (datalen))
 
 typedef struct {
@@ -1788,7 +1788,7 @@ typedef struct {
     uint16_t   flags;
     uint16_t   result;
     uint8_t    data[0];
-} __attribute__ ((packed)) l2cap_conf_rsp;
+} QEMU_PACKED l2cap_conf_rsp;
 #define L2CAP_CONF_RSP_SIZE(datalen) (6 + datalen)
 
 enum bt_l2cap_conf_res {
@@ -1802,7 +1802,7 @@ typedef struct {
     uint8_t    type;
     uint8_t    len;
     uint8_t    val[0];
-} __attribute__ ((packed)) l2cap_conf_opt;
+} QEMU_PACKED l2cap_conf_opt;
 #define L2CAP_CONF_OPT_SIZE 2
 
 enum bt_l2cap_conf_val {
@@ -1821,7 +1821,7 @@ typedef struct {
     uint32_t   peak_bandwidth;
     uint32_t   latency;
     uint32_t   delay_variation;
-} __attribute__ ((packed)) l2cap_conf_opt_qos;
+} QEMU_PACKED l2cap_conf_opt_qos;
 #define L2CAP_CONF_OPT_QOS_SIZE 22
 
 enum bt_l2cap_conf_opt_qos_st {
@@ -1841,25 +1841,25 @@ enum bt_l2cap_mode {
 typedef struct {
     uint16_t   dcid;
     uint16_t   scid;
-} __attribute__ ((packed)) l2cap_disconn_req;
+} QEMU_PACKED l2cap_disconn_req;
 #define L2CAP_DISCONN_REQ_SIZE 4
 
 typedef struct {
     uint16_t   dcid;
     uint16_t   scid;
-} __attribute__ ((packed)) l2cap_disconn_rsp;
+} QEMU_PACKED l2cap_disconn_rsp;
 #define L2CAP_DISCONN_RSP_SIZE 4
 
 typedef struct {
     uint16_t   type;
-} __attribute__ ((packed)) l2cap_info_req;
+} QEMU_PACKED l2cap_info_req;
 #define L2CAP_INFO_REQ_SIZE 2
 
 typedef struct {
     uint16_t   type;
     uint16_t   result;
     uint8_t    data[0];
-} __attribute__ ((packed)) l2cap_info_rsp;
+} QEMU_PACKED l2cap_info_rsp;
 #define L2CAP_INFO_RSP_SIZE 4
 
 /* info type */
index ec7ea8207b4a7f3c106affab0d4f44b9e695a893..4d0ef0d54cf1d83f1145fdb7fba14f87ed25827d 100644 (file)
@@ -2424,7 +2424,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
 {
     unsigned mode;
 
-    memory_region_transaction_begin();
     if ((s->vga.sr[0x17] & 0x44) == 0x44) {
         goto generic_io;
     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
@@ -2444,7 +2443,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
             unmap_linear_vram(s);
         }
     }
-    memory_region_transaction_commit();
 }
 
 
index 0b955e04f1e7ac4f54515378c1df46f5556a8875..156404d9f34e0d432865d26dfa62768d38ecdf9b 100644 (file)
@@ -26,7 +26,7 @@ static void collie_init(ram_addr_t ram_size,
 {
     StrongARMState *s;
     DriveInfo *dinfo;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 2);
+    ram_addr_t phys_flash;
 
     if (!cpu_model) {
         cpu_model = "sa1110";
@@ -34,19 +34,17 @@ static void collie_init(ram_addr_t ram_size,
 
     s = sa1110_init(collie_binfo.ram_size, cpu_model);
 
-    memory_region_init_rom_device(&phys_flash[0], &pflash_cfi01_ops_le,
-                                  NULL, "collie.fl1", 0x02000000);
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(SA_CS0, &phys_flash[0],
+    pflash_cfi01_register(SA_CS0, phys_flash,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00);
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
-    memory_region_init_rom_device(&phys_flash[1], &pflash_cfi01_ops_le,
-                                  NULL, "collie.fl2", 0x02000000);
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 1);
-    pflash_cfi01_register(SA_CS1, &phys_flash[1],
+    pflash_cfi01_register(SA_CS1, phys_flash,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00);
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
     sysbus_create_simple("scoop", 0x40800000, NULL);
 
index 1aec06611c04a987cabe48ffcbf8bf492a9244a4..a35f3820523c9102bcc0e5e671ffa57e44d6e84d 100644 (file)
@@ -80,15 +80,16 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
 static int pci_dec_21154_init_device(SysBusDevice *dev)
 {
     DECState *s;
+    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(DECState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-data-idx", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
index 30146b9c9d6c2d70a624c3000fb15dad19e9d5a1..eed9e3843c552e0201546abee2321fc3b7d40dcc 100644 (file)
@@ -10,7 +10,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 
@@ -22,8 +21,6 @@ static void dummy_m68k_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
@@ -40,8 +37,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
     env->vbr = 0;
 
     /* RAM at address zero */
-    memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size,
+        qemu_ram_alloc(NULL, "dummy_m68k.ram", ram_size) | IO_MEM_RAM);
 
     /* Load kernel.  */
     if (kernel_filename) {
index 7fb012bb067bf7f06c21c4c095c878fb3788a1f3..270be5e12785f0f07950ad257a802add5b259af4 100644 (file)
@@ -1,27 +1,21 @@
-#include "memory.h"
-
 /* NOR flash devices */
 typedef struct pflash_t pflash_t;
 
 /* pflash_cfi01.c */
-extern const MemoryRegionOps pflash_cfi01_ops_be;
-extern const MemoryRegionOps pflash_cfi01_ops_le;
-extern const MemoryRegionOps pflash_cfi02_ops_be;
-extern const MemoryRegionOps pflash_cfi02_ops_le;
-
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs,
                                 uint32_t sector_len, int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3);
+                                uint16_t id2, uint16_t id3, int be);
 
 /* pflash_cfi02.c */
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1);
+                                uint16_t unlock_addr0, uint16_t unlock_addr1,
+                                int be);
 
 /* nand.c */
 DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
@@ -42,12 +36,7 @@ uint32_t nand_getbuswidth(DeviceState *dev);
 #define NAND_MFR_MICRON                0x2c
 
 /* onenand.c */
-void onenand_base_update(void *opaque, target_phys_addr_t new);
-void onenand_base_unmap(void *opaque);
-void *onenand_init(BlockDriverState *bdrv,
-                uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
-                int regshift, qemu_irq irq);
-void *onenand_raw_otp(void *opaque);
+void *onenand_raw_otp(DeviceState *onenand_device);
 
 /* ecc.c */
 typedef struct {
index 663ad80116e079afe6565db613848220f5666063..8df265c61d2c224504b0c7f15e4bcad7376ef6a8 100644 (file)
@@ -214,7 +214,8 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value)
 
     FW_CFG_DPRINTF("write %d\n", value);
 
-    if (s->cur_entry & FW_CFG_WRITE_CHANNEL && s->cur_offset < e->len) {
+    if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback &&
+        s->cur_offset < e->len) {
         e->data[s->cur_offset++] = value;
         if (s->cur_offset == e->len) {
             e->callback(e->callback_opaque, e->data);
index a7731ecfb51dd4d4754310b1d1dc610a4a41e1a7..5e7bcfa278e80795de39fa9d6ec422a8f508a65a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * QEMU G364 framebuffer Emulator.
  *
- * Copyright (c) 2007-2009 Herve Poussineau
+ * Copyright (c) 2007-2011 Herve Poussineau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  */
 
 #include "hw.h"
-#include "mips.h"
 #include "console.h"
 #include "pixel_ops.h"
-
-//#define DEBUG_G364
-
-#ifdef DEBUG_G364
-#define DPRINTF(fmt, ...) \
-do { printf("g364: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "g364 ERROR: " fmt , ## __VA_ARGS__);} while (0)
+#include "trace.h"
+#include "sysbus.h"
 
 typedef struct G364State {
     /* hardware */
     uint8_t *vram;
-    MemoryRegion vram_region;
-    int vram_size;
+    uint32_t vram_size;
     qemu_irq irq;
+    MemoryRegion mem_vram;
+    MemoryRegion mem_ctrl;
     /* registers */
     uint8_t color_palette[256][3];
     uint8_t cursor_palette[3][3];
@@ -53,31 +44,31 @@ typedef struct G364State {
     int blanked;
 } G364State;
 
-#define REG_ID       0x000000
-#define REG_BOOT     0x080000
-#define REG_DISPLAY  0x080118
-#define REG_VDISPLAY 0x080150
-#define REG_CTLA     0x080300
-#define REG_TOP      0x080400
-#define REG_CURS_PAL 0x080508
-#define REG_CURS_POS 0x080638
-#define REG_CLR_PAL  0x080800
-#define REG_CURS_PAT 0x081000
-#define REG_RESET    0x180000
+#define REG_BOOT     0x000000
+#define REG_DISPLAY  0x000118
+#define REG_VDISPLAY 0x000150
+#define REG_CTLA     0x000300
+#define REG_TOP      0x000400
+#define REG_CURS_PAL 0x000508
+#define REG_CURS_POS 0x000638
+#define REG_CLR_PAL  0x000800
+#define REG_CURS_PAT 0x001000
+#define REG_RESET    0x100000
 
 #define CTLA_FORCE_BLANK 0x00000400
 #define CTLA_NO_CURSOR   0x00800000
 
 static inline int check_dirty(G364State *s, ram_addr_t page)
 {
-    return memory_region_get_dirty(&s->vram_region, page, DIRTY_MEMORY_VGA);
+    return memory_region_get_dirty(&s->mem_vram, page, DIRTY_MEMORY_VGA);
 }
 
 static inline void reset_dirty(G364State *s,
                                ram_addr_t page_min, ram_addr_t page_max)
 {
-    memory_region_reset_dirty(&s->vram_region, page_min,
-                              page_max + TARGET_PAGE_SIZE - 1,
+    memory_region_reset_dirty(&s->mem_vram,
+                              page_min,
+                              page_max + TARGET_PAGE_SIZE - page_min - 1,
                               DIRTY_MEMORY_VGA);
 }
 
@@ -111,7 +102,8 @@ static void g364fb_draw_graphic8(G364State *s)
             w = 4;
             break;
         default:
-            BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds));
+            hw_error("g364: unknown host depth %d",
+                     ds_get_bits_per_pixel(s->ds));
             return;
     }
 
@@ -263,7 +255,7 @@ static void g364fb_update_display(void *opaque)
     } else if (s->depth == 8) {
         g364fb_draw_graphic8(s);
     } else {
-        BADF("unknown guest depth %d\n", s->depth);
+        error_report("g364: unknown guest depth %d", s->depth);
     }
 
     qemu_irq_raise(s->irq);
@@ -276,13 +268,12 @@ static inline void g364fb_invalidate_display(void *opaque)
 
     s->blanked = 0;
     for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_region, i);
+        memory_region_set_dirty(&s->mem_vram, i);
     }
 }
 
-static void g364fb_reset(void *opaque)
+static void g364fb_reset(G364State *s)
 {
-    G364State *s = opaque;
     qemu_irq_lower(s->irq);
 
     memset(s->color_palette, 0, sizeof(s->color_palette));
@@ -293,7 +284,7 @@ static void g364fb_reset(void *opaque)
     s->top_of_screen = 0;
     s->width = s->height = 0;
     memset(s->vram, 0, s->vram_size);
-    g364fb_invalidate_display(opaque);
+    g364fb_invalidate_display(s);
 }
 
 static void g364fb_screen_dump(void *opaque, const char *filename)
@@ -305,7 +296,7 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
     FILE *f;
 
     if (s->depth != 8) {
-        BADF("unknown guest depth %d\n", s->depth);
+        error_report("g364: unknown guest depth %d", s->depth);
         return;
     }
 
@@ -337,7 +328,9 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
 }
 
 /* called for accesses to io ports */
-static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t g364fb_ctrl_read(void *opaque,
+                                 target_phys_addr_t addr,
+                                 unsigned int size)
 {
     G364State *s = opaque;
     uint32_t val;
@@ -354,9 +347,6 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
         val |= ((uint32_t)s->cursor_palette[idx][2] << 0);
     } else {
         switch (addr) {
-            case REG_ID:
-                val = 0x10; /* Mips G364 */
-                break;
             case REG_DISPLAY:
                 val = s->width / 4;
                 break;
@@ -368,33 +358,19 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
                 break;
             default:
             {
-                BADF("invalid read at [" TARGET_FMT_plx "]\n", addr);
+                error_report("g364: invalid read at [" TARGET_FMT_plx "]",
+                             addr);
                 val = 0;
                 break;
             }
         }
     }
 
-    DPRINTF("read 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
+    trace_g364fb_read(addr, val);
 
     return val;
 }
 
-static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
-    if (addr & 0x2)
-        return v >> 16;
-    else
-        return v & 0xffff;
-}
-
-static uint32_t g364fb_ctrl_readb(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
-    return (v >> (8 * (addr & 0x3))) & 0xff;
-}
-
 static void g364fb_update_depth(G364State *s)
 {
     static const int depths[8] = { 1, 2, 4, 8, 15, 16, 0 };
@@ -412,15 +388,18 @@ static void g364_invalidate_cursor_position(G364State *s)
     end = (ymax + 1) * ds_get_linesize(s->ds);
 
     for (i = start; i < end; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_region, i);
+        memory_region_set_dirty(&s->mem_vram, i);
     }
 }
 
-static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void g364fb_ctrl_write(void *opaque,
+                              target_phys_addr_t addr,
+                              uint64_t val,
+                              unsigned int size)
 {
     G364State *s = opaque;
 
-    DPRINTF("write 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
+    trace_g364fb_write(addr, val);
 
     if (addr >= REG_CLR_PAL && addr < REG_CLR_PAL + 0x800) {
         /* color palette */
@@ -443,124 +422,65 @@ static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t v
         g364fb_invalidate_display(s);
     } else {
         switch (addr) {
-            case REG_ID: /* Card identifier; read-only */
-            case REG_BOOT: /* Boot timing */
-            case 0x80108: /* Line timing: half sync */
-            case 0x80110: /* Line timing: back porch */
-            case 0x80120: /* Line timing: short display */
-            case 0x80128: /* Frame timing: broad pulse */
-            case 0x80130: /* Frame timing: v sync */
-            case 0x80138: /* Frame timing: v preequalise */
-            case 0x80140: /* Frame timing: v postequalise */
-            case 0x80148: /* Frame timing: v blank */
-            case 0x80158: /* Line timing: line time */
-            case 0x80160: /* Frame store: line start */
-            case 0x80168: /* vram cycle: mem init */
-            case 0x80170: /* vram cycle: transfer delay */
-            case 0x80200: /* vram cycle: mask register */
-                /* ignore */
-                break;
-            case REG_TOP:
-                s->top_of_screen = val;
-                g364fb_invalidate_display(s);
-                break;
-            case REG_DISPLAY:
-                s->width = val * 4;
-                break;
-            case REG_VDISPLAY:
-                s->height = val / 2;
-                break;
-            case REG_CTLA:
-                s->ctla = val;
-                g364fb_update_depth(s);
-                g364fb_invalidate_display(s);
-                break;
-            case REG_CURS_POS:
-                g364_invalidate_cursor_position(s);
-                s->cursor_position = val;
-                g364_invalidate_cursor_position(s);
-                break;
-            case REG_RESET:
-                g364fb_reset(s);
-                break;
-            default:
-                BADF("invalid write of 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
-                break;
+        case REG_BOOT: /* Boot timing */
+        case 0x00108: /* Line timing: half sync */
+        case 0x00110: /* Line timing: back porch */
+        case 0x00120: /* Line timing: short display */
+        case 0x00128: /* Frame timing: broad pulse */
+        case 0x00130: /* Frame timing: v sync */
+        case 0x00138: /* Frame timing: v preequalise */
+        case 0x00140: /* Frame timing: v postequalise */
+        case 0x00148: /* Frame timing: v blank */
+        case 0x00158: /* Line timing: line time */
+        case 0x00160: /* Frame store: line start */
+        case 0x00168: /* vram cycle: mem init */
+        case 0x00170: /* vram cycle: transfer delay */
+        case 0x00200: /* vram cycle: mask register */
+            /* ignore */
+            break;
+        case REG_TOP:
+            s->top_of_screen = val;
+            g364fb_invalidate_display(s);
+            break;
+        case REG_DISPLAY:
+            s->width = val * 4;
+            break;
+        case REG_VDISPLAY:
+            s->height = val / 2;
+            break;
+        case REG_CTLA:
+            s->ctla = val;
+            g364fb_update_depth(s);
+            g364fb_invalidate_display(s);
+            break;
+        case REG_CURS_POS:
+            g364_invalidate_cursor_position(s);
+            s->cursor_position = val;
+            g364_invalidate_cursor_position(s);
+            break;
+        case REG_RESET:
+            g364fb_reset(s);
+            break;
+        default:
+            error_report("g364: invalid write of 0x%" PRIx64
+                         " at [" TARGET_FMT_plx "]", val, addr);
+            break;
         }
     }
     qemu_irq_lower(s->irq);
 }
 
-static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);
-
-    if (addr & 0x2)
-        val = (val << 16) | (old_val & 0x0000ffff);
-    else
-        val = val | (old_val & 0xffff0000);
-    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
-}
-
-static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);
-
-    switch (addr & 3) {
-    case 0:
-        val = val | (old_val & 0xffffff00);
-        break;
-    case 1:
-        val = (val << 8) | (old_val & 0xffff00ff);
-        break;
-    case 2:
-        val = (val << 16) | (old_val & 0xff00ffff);
-        break;
-    case 3:
-        val = (val << 24) | (old_val & 0x00ffffff);
-        break;
-    }
-    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
-}
-
 static const MemoryRegionOps g364fb_ctrl_ops = {
-    .old_mmio = {
-        .read = {
-            g364fb_ctrl_readb,
-            g364fb_ctrl_readw,
-            g364fb_ctrl_readl,
-        },
-        .write = {
-            g364fb_ctrl_writeb,
-            g364fb_ctrl_writew,
-            g364fb_ctrl_writel,
-        },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+    .read = g364fb_ctrl_read,
+    .write = g364fb_ctrl_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
 };
 
-static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
+static int g364fb_post_load(void *opaque, int version_id)
 {
     G364State *s = opaque;
-    unsigned int i, vram_size;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    vram_size = qemu_get_be32(f);
-    if (vram_size < s->vram_size)
-        return -EINVAL;
-    qemu_get_buffer(f, s->vram, s->vram_size);
-    for (i = 0; i < 256; i++)
-        qemu_get_buffer(f, s->color_palette[i], 3);
-    for (i = 0; i < 3; i++)
-        qemu_get_buffer(f, s->cursor_palette[i], 3);
-    qemu_get_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
-    s->cursor_position = qemu_get_be32(f);
-    s->ctla = qemu_get_be32(f);
-    s->top_of_screen = qemu_get_be32(f);
-    s->width = qemu_get_be32(f);
-    s->height = qemu_get_be32(f);
 
     /* force refresh */
     g364fb_update_depth(s);
@@ -569,53 +489,80 @@ static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void g364fb_save(QEMUFile *f, void *opaque)
-{
-    G364State *s = opaque;
-    int i;
-
-    qemu_put_be32(f, s->vram_size);
-    qemu_put_buffer(f, s->vram, s->vram_size);
-    for (i = 0; i < 256; i++)
-        qemu_put_buffer(f, s->color_palette[i], 3);
-    for (i = 0; i < 3; i++)
-        qemu_put_buffer(f, s->cursor_palette[i], 3);
-    qemu_put_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
-    qemu_put_be32(f, s->cursor_position);
-    qemu_put_be32(f, s->ctla);
-    qemu_put_be32(f, s->top_of_screen);
-    qemu_put_be32(f, s->width);
-    qemu_put_be32(f, s->height);
-}
+static const VMStateDescription vmstate_g364fb = {
+    .name = "g364fb",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = g364fb_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, 0, vram_size),
+        VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3),
+        VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9),
+        VMSTATE_UINT16_ARRAY(cursor, G364State, 512),
+        VMSTATE_UINT32(cursor_position, G364State),
+        VMSTATE_UINT32(ctla, G364State),
+        VMSTATE_UINT32(top_of_screen, G364State),
+        VMSTATE_UINT32(width, G364State),
+        VMSTATE_UINT32(height, G364State),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-int g364fb_mm_init(MemoryRegion *system_memory,
-                   target_phys_addr_t vram_base,
-                   target_phys_addr_t ctrl_base, int it_shift,
-                   qemu_irq irq)
+static void g364fb_init(DeviceState *dev, G364State *s)
 {
-    G364State *s;
-    MemoryRegion *io_ctrl = g_new(MemoryRegion, 1);
-
-    s = g_malloc0(sizeof(G364State));
-
-    s->vram_size = 8 * 1024 * 1024;
-    memory_region_init_ram(&s->vram_region, NULL, "g364fb.vram", s->vram_size);
-    s->vram = memory_region_get_ram_ptr(&s->vram_region);
-    s->irq = irq;
-
-    qemu_register_reset(g364fb_reset, s);
-    register_savevm(NULL, "g364fb", 0, 1, g364fb_save, g364fb_load, s);
-    g364fb_reset(s);
+    s->vram = g_malloc0(s->vram_size);
 
     s->ds = graphic_console_init(g364fb_update_display,
                                  g364fb_invalidate_display,
                                  g364fb_screen_dump, NULL, s);
 
-    memory_region_add_subregion(system_memory, vram_base, &s->vram_region);
+    memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
+    memory_region_init_ram_ptr(&s->mem_vram, dev, "vram",
+                               s->vram_size, s->vram);
+    memory_region_set_coalescing(&s->mem_vram);
+}
+
+typedef struct {
+    SysBusDevice busdev;
+    G364State g364;
+} G364SysBusState;
 
-    memory_region_init_io(io_ctrl, &g364fb_ctrl_ops, s,
-                          "g364fb-ctrl", 0x200000);
-    memory_region_add_subregion(system_memory, ctrl_base, io_ctrl);
+static int g364fb_sysbus_init(SysBusDevice *dev)
+{
+    G364State *s = &FROM_SYSBUS(G364SysBusState, dev)->g364;
+
+    g364fb_init(&dev->qdev, s);
+    sysbus_init_irq(dev, &s->irq);
+    sysbus_init_mmio_region(dev, &s->mem_ctrl);
+    sysbus_init_mmio_region(dev, &s->mem_vram);
 
     return 0;
 }
+
+static void g364fb_sysbus_reset(DeviceState *d)
+{
+    G364SysBusState *s = DO_UPCAST(G364SysBusState, busdev.qdev, d);
+    g364fb_reset(&s->g364);
+}
+
+static SysBusDeviceInfo g364fb_sysbus_info = {
+    .init = g364fb_sysbus_init,
+    .qdev.name = "sysbus-g364",
+    .qdev.desc = "G364 framebuffer",
+    .qdev.size = sizeof(G364SysBusState),
+    .qdev.vmsd = &vmstate_g364fb,
+    .qdev.reset = g364fb_sysbus_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size,
+                          8 * 1024 * 1024),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void g364fb_register(void)
+{
+    sysbus_register_withprop(&g364fb_sysbus_info);
+}
+
+device_init(g364fb_register);
index 9d3ff7d5551e50405de8140615288466ebb92fd5..9a823e1c068f4f8b0497c6ca66899f9bb002032b 100644 (file)
@@ -92,15 +92,16 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
 static int pci_grackle_init_device(SysBusDevice *dev)
 {
     GrackleState *s;
+    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(GrackleState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-data-idx", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_grackle_reset, &s->host_state);
     return 0;
index d3a4bb4c67142c5932e8fb0f806c1deee43598b9..853f7e1ee80b74d7f3fe85a2a2c6adffc8066ce6 100644 (file)
@@ -48,8 +48,7 @@ static void connex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    const MemoryRegionOps *flash_ops;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    int be;
 
     uint32_t connex_rom = 0x01000000;
     uint32_t connex_ram = 0x04000000;
@@ -64,15 +63,14 @@ static void connex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "connext.rom", connex_rom);
-    if (!pflash_cfi01_register(0x00000000, flash,
+    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom",
+                                                          connex_rom),
                                dinfo->bdrv, sector_len, connex_rom / sector_len,
-                               2, 0, 0, 0, 0)) {
+                               2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
@@ -89,8 +87,7 @@ static void verdex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
-    const MemoryRegionOps *flash_ops;
+    int be;
 
     uint32_t verdex_rom = 0x02000000;
     uint32_t verdex_ram = 0x10000000;
@@ -105,15 +102,14 @@ static void verdex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "verdex.rom", verdex_rom);
-    if (!pflash_cfi01_register(0x00000000, flash,
+    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom",
+                                                          verdex_rom),
                                dinfo->bdrv, sector_len, verdex_rom / sector_len,
-                               2, 0, 0, 0, 0)) {
+                               2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
index 8bf312ab21f38886f9aaee5a3e625308e3df6faf..6128702533b7d010d50914d2c152610ec723ff55 100644 (file)
@@ -59,13 +59,13 @@ struct hpet_fw_entry
     uint64_t address;
     uint16_t min_tick;
     uint8_t page_prot;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hpet_fw_config
 {
     uint8_t count;
     struct hpet_fw_entry hpet[8];
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 extern struct hpet_fw_config hpet_cfg;
 #endif
index 29521babf7ac26de4e52d4abacf6441a7eae2627..f4fa1545bd59e26a70b47e9216a68b05814b3668 100644 (file)
@@ -710,6 +710,7 @@ static void ncq_cb(void *opaque, int ret)
     DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
             ncq_tfs->tag);
 
+    bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct);
     qemu_sglist_destroy(&ncq_tfs->sglist);
     ncq_tfs->used = 0;
 }
@@ -756,6 +757,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             ncq_tfs->is_read = 1;
 
             DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba);
+
+            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+                            BDRV_ACCT_READ);
             ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
                                            &ncq_tfs->sglist, ncq_tfs->lba,
                                            ncq_cb, ncq_tfs);
@@ -766,6 +771,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             ncq_tfs->is_read = 0;
 
             DPRINTF(port, "tag %d aio write %ld\n", ncq_tfs->tag, ncq_tfs->lba);
+
+            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+                            BDRV_ACCT_WRITE);
             ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
                                             &ncq_tfs->sglist, ncq_tfs->lba,
                                             ncq_cb, ncq_tfs);
index e456193b2b9d448f46b7a3545513b991f18b9d33..3c29d93b476177ea74c2bb8eff9b933212b3a2aa 100644 (file)
@@ -244,13 +244,13 @@ typedef struct AHCICmdHdr {
     uint32_t    status;
     uint64_t    tbl_addr;
     uint32_t    reserved[4];
-} __attribute__ ((packed)) AHCICmdHdr;
+} QEMU_PACKED AHCICmdHdr;
 
 typedef struct AHCI_SG {
     uint64_t    addr;
     uint32_t    reserved;
     uint32_t    flags_size;
-} __attribute__ ((packed)) AHCI_SG;
+} QEMU_PACKED AHCI_SG;
 
 typedef struct AHCIDevice AHCIDevice;
 
@@ -258,6 +258,7 @@ typedef struct NCQTransferState {
     AHCIDevice *drive;
     BlockDriverAIOCB *aiocb;
     QEMUSGList sglist;
+    BlockAcctCookie acct;
     int is_read;
     uint16_t sector_count;
     uint64_t lba;
@@ -320,7 +321,7 @@ typedef struct NCQFrame {
     uint8_t reserved8;
     uint8_t reserved9;
     uint8_t reserved10;
-} __attribute__ ((packed)) NCQFrame;
+} QEMU_PACKED NCQFrame;
 
 void ahci_init(AHCIState *s, DeviceState *qdev, int ports);
 void ahci_uninit(AHCIState *s);
index fe2fb0b8067d157a00938e8c6a3fcb010d30df67..f38d2896ae4c4eff77e7972b66e44fda436ef693 100644 (file)
@@ -104,17 +104,20 @@ static void cd_data_to_raw(uint8_t *buf, int lba)
     memset(buf, 0, 288);
 }
 
-static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
-                           int sector_size)
+static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size)
 {
     int ret;
 
     switch(sector_size) {
     case 2048:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
+        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf, 4);
+        bdrv_acct_done(s->bs, &s->acct);
         break;
     case 2352:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
+        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf + 16, 4);
+        bdrv_acct_done(s->bs, &s->acct);
         if (ret < 0)
             return ret;
         cd_data_to_raw(buf, lba);
@@ -181,7 +184,7 @@ void ide_atapi_cmd_reply_end(IDEState *s)
     } else {
         /* see if a new sector must be read */
         if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
-            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
+            ret = cd_read_sector(s, s->lba, s->io_buffer, s->cd_sector_size);
             if (ret < 0) {
                 ide_transfer_stop(s);
                 ide_atapi_io_error(s, ret);
@@ -250,6 +253,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
     s->io_buffer_index = 0;
 
     if (s->atapi_dma) {
+        bdrv_acct_start(s->bs, &s->acct, size, BDRV_ACCT_READ);
         s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
         s->bus->dma->ops->start_dma(s->bus->dma, s,
                                    ide_atapi_cmd_read_dma_cb);
@@ -322,10 +326,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
         s->status = READY_STAT | SEEK_STAT;
         s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
         ide_set_irq(s->bus);
-    eot:
-        s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
-        ide_set_inactive(s);
-        return;
+        goto eot;
     }
 
     s->io_buffer_index = 0;
@@ -343,9 +344,11 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
 #ifdef DEBUG_AIO
     printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
 #endif
+
     s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
     s->bus->dma->iov.iov_len = n * 4 * 512;
     qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
+
     s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
                                        &s->bus->dma->qiov, n * 4,
                                        ide_atapi_cmd_read_dma_cb, s);
@@ -355,6 +358,12 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
                             ASC_MEDIUM_NOT_PRESENT);
         goto eot;
     }
+
+    return;
+eot:
+    bdrv_acct_done(s->bs, &s->acct);
+    s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
+    ide_set_inactive(s);
 }
 
 /* start a CD-CDROM read command with DMA */
@@ -368,6 +377,8 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
     s->io_buffer_size = 0;
     s->cd_sector_size = sector_size;
 
+    bdrv_acct_start(s->bs, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ);
+
     /* XXX: check if BUSY_STAT should be set */
     s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
     s->bus->dma->ops->start_dma(s->bus->dma, s,
@@ -546,13 +557,13 @@ static void cmd_get_event_status_notification(IDEState *s,
         uint8_t reserved3[2];
         uint16_t len;
         uint8_t control;
-    } __attribute__((packed)) *gesn_cdb;
+    } QEMU_PACKED *gesn_cdb;
 
     struct {
         uint16_t len;
         uint8_t notification_class;
         uint8_t supported_events;
-    } __attribute((packed)) *gesn_event_header;
+    } QEMU_PACKED *gesn_event_header;
 
     enum notification_class_request_type {
         NCR_RESERVED1 = 1 << 0,
index d145b19b0cb2f9d99f21aaa761c208e9721ec5ef..40abc1edd25a2b59b431e0fb93d7cbf18318e543 100644 (file)
@@ -473,7 +473,10 @@ void ide_sector_read(IDEState *s)
 #endif
         if (n > s->req_nb_sectors)
             n = s->req_nb_sectors;
+
+        bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
         ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
+        bdrv_acct_done(s->bs, &s->acct);
         if (ret != 0) {
             if (ide_handle_rw_error(s, -ret,
                 BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
@@ -610,7 +613,10 @@ handle_rw_error:
     return;
 
 eot:
-   ide_set_inactive(s);
+    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
+        bdrv_acct_done(s->bs, &s->acct);
+    }
+    ide_set_inactive(s);
 }
 
 static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
@@ -619,6 +625,20 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
     s->io_buffer_index = 0;
     s->io_buffer_size = 0;
     s->dma_cmd = dma_cmd;
+
+    switch (dma_cmd) {
+    case IDE_DMA_READ:
+        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                        BDRV_ACCT_READ);
+        break;
+    case IDE_DMA_WRITE:
+        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                        BDRV_ACCT_WRITE);
+        break;
+    default:
+        break;
+    }
+
     s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb);
 }
 
@@ -641,7 +661,10 @@ void ide_sector_write(IDEState *s)
     n = s->nsector;
     if (n > s->req_nb_sectors)
         n = s->req_nb_sectors;
+
+    bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
     ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
+    bdrv_acct_done(s->bs, &s->acct);
 
     if (ret != 0) {
         if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
@@ -685,6 +708,7 @@ static void ide_flush_cb(void *opaque, int ret)
         }
     }
 
+    bdrv_acct_done(s->bs, &s->acct);
     s->status = READY_STAT | SEEK_STAT;
     ide_set_irq(s->bus);
 }
@@ -698,6 +722,7 @@ void ide_flush_cache(IDEState *s)
         return;
     }
 
+    bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
     acb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
     if (acb == NULL) {
         ide_flush_cb(s, -EIO);
index 02e805f070a50aeb8e6ee06353f499f96b759892..7f5ef8de1d678808df76bc794a0646e47f2b03d6 100644 (file)
@@ -440,6 +440,7 @@ struct IDEState {
     int lba;
     int cd_sector_size;
     int atapi_dma; /* true if dma is requested for the packet cmd */
+    BlockAcctCookie acct;
     /* ATA DMA state */
     int io_buffer_size;
     QEMUSGList sg;
index 44fb3fef600b9509da5217171d8563b0eb174573..fdf5d75082aea000d0a89ec6be002c6f36e78315 100644 (file)
@@ -52,8 +52,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         m->aiocb = NULL;
         qemu_sglist_destroy(&s->sg);
         ide_atapi_io_error(s, ret);
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
 
     if (s->io_buffer_size > 0) {
@@ -71,8 +70,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         ide_atapi_cmd_ok(s);
 
     if (io->len == 0) {
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
 
     /* launch next transfer */
@@ -92,9 +90,14 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         /* Note: media not present is the most likely case */
         ide_atapi_cmd_error(s, SENSE_NOT_READY,
                             ASC_MEDIUM_NOT_PRESENT);
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
+    return;
+
+done:
+    bdrv_acct_done(s->bs, &s->acct);
+    io->dma_end(opaque);
+    return;
 }
 
 static void pmac_ide_transfer_cb(void *opaque, int ret)
@@ -109,8 +112,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
         m->aiocb = NULL;
         qemu_sglist_destroy(&s->sg);
        ide_dma_error(s);
-        io->dma_end(io);
-        return;
+        goto done;
     }
 
     sector_num = ide_get_sector(s);
@@ -130,10 +132,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
     }
 
     /* end of DMA ? */
-
     if (io->len == 0) {
-        io->dma_end(io);
-       return;
+        goto done;
     }
 
     /* launch next transfer */
@@ -163,6 +163,12 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
 
     if (!m->aiocb)
         pmac_ide_transfer_cb(io, -1);
+    return;
+done:
+    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
+        bdrv_acct_done(s->bs, &s->acct);
+    }
+    io->dma_end(io);
 }
 
 static void pmac_ide_transfer(DBDMA_io *io)
@@ -172,10 +178,22 @@ static void pmac_ide_transfer(DBDMA_io *io)
 
     s->io_buffer_size = 0;
     if (s->drive_kind == IDE_CD) {
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
         pmac_ide_atapi_transfer_cb(io, 0);
         return;
     }
 
+    switch (s->dma_cmd) {
+    case IDE_DMA_READ:
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
+        break;
+    case IDE_DMA_WRITE:
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE);
+        break;
+    default:
+        break;
+    }
+
     pmac_ide_transfer_cb(io, 0);
 }
 
index 3c8982ea29e7e68ddaaa460d4e1b22867151ec76..281410899f68f82d65a241dd3b0a5c0bc32d4181 100644 (file)
 #include "boards.h"
 #include "arm-misc.h"
 #include "net.h"
-#include "exec-memory.h"
 
 typedef struct {
     SysBusDevice busdev;
     uint32_t memsz;
-    MemoryRegion flash;
-    bool flash_mapped;
+    uint32_t flash_offset;
     uint32_t cm_osc;
     uint32_t cm_ctrl;
     uint32_t cm_lock;
@@ -110,15 +108,9 @@ static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
 static void integratorcm_do_remap(integratorcm_state *s, int flash)
 {
     if (flash) {
-        if (s->flash_mapped) {
-            sysbus_del_memory(&s->busdev, &s->flash);
-            s->flash_mapped = false;
-        }
+        cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
     } else {
-        if (!s->flash_mapped) {
-            sysbus_add_memory_overlap(&s->busdev, 0, &s->flash, 1);
-            s->flash_mapped = true;
-        }
+        cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
     }
     //??? tlb_flush (cpu_single_env, 1);
 }
@@ -260,8 +252,7 @@ static int integratorcm_init(SysBusDevice *dev)
     }
     memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
     s->cm_init = 0x00000112;
-    memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000);
-    s->flash_mapped = false;
+    s->flash_offset = qemu_ram_alloc(NULL, "integrator.flash", 0x100000);
 
     iomemtype = cpu_register_io_memory(integratorcm_readfn,
                                        integratorcm_writefn, s,
@@ -465,9 +456,7 @@ static void integratorcp_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+    ram_addr_t ram_offset;
     qemu_irq pic[32];
     qemu_irq *cpu_pic;
     DeviceState *dev;
@@ -480,14 +469,13 @@ static void integratorcp_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
+    ram_offset = qemu_ram_alloc(NULL, "integrator.ram", ram_size);
     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero*/
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
     /* And again at address 0x80000000 */
-    memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
-    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
+    cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM);
 
     dev = qdev_create(NULL, "integrator_core");
     qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
index 607ec852fe65ebdbdceb448e72a84ceb12787131..a62a9419f32289f33dc7781618fca3cff0d9b71f 100644 (file)
@@ -29,7 +29,6 @@
 #include "loader.h"
 #include "elf.h"
 #include "trace.h"
-#include "exec-memory.h"
 
 #include "grlib.h"
 
@@ -101,9 +100,7 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
                                   const char *cpu_model)
 {
     CPUState   *env;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *prom = g_new(MemoryRegion, 1);
+    ram_addr_t  ram_offset, prom_offset;
     int         ret;
     char       *filename;
     qemu_irq   *cpu_irqs = NULL;
@@ -142,14 +139,14 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
         exit(1);
     }
 
-    memory_region_init_ram(ram, NULL, "leon3.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    ram_offset = qemu_ram_alloc(NULL, "leon3.ram", ram_size);
+    cpu_register_physical_memory(0x40000000, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Allocate BIOS */
     prom_size = 8 * 1024 * 1024; /* 8Mb */
-    memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size);
-    memory_region_set_readonly(prom, true);
-    memory_region_add_subregion(address_space_mem, 0x00000000, prom);
+    prom_offset = qemu_ram_alloc(NULL, "Leon3.bios", prom_size);
+    cpu_register_physical_memory(0x00000000, prom_size,
+                                 prom_offset | IO_MEM_ROM);
 
     /* Load boot prom */
     if (bios_name == NULL) {
index a84007b0ed99adc23b3bafb5b49c236311f20564..d18aad7435c1061b23e996c400fd1af2d0d49500 100644 (file)
@@ -28,7 +28,6 @@
 #include "elf.h"
 #include "lm32_hwsetup.h"
 #include "lm32.h"
-#include "exec-memory.h"
 
 typedef struct {
     CPUState *env;
@@ -77,9 +76,8 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     ResetInfo *reset_info;
     int i;
@@ -107,17 +105,16 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size);
+    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi02_ops_be,
-                                  NULL, "lm32_evr.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "lm32_evr.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
@@ -167,9 +164,8 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     HWSetup *hw;
     ResetInfo *reset_info;
@@ -204,17 +200,16 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    memory_region_init_ram(phys_ram, NULL, "lm32_uclinux.sdram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size);
+    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "lm32_uclinux.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "lm32_uclinux.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
index 82e957149da4d38154ae6824e89e25e20e04847a..4792f0e3ed1671b5af217a5c1cbf3e4d7e81fe5f 100644 (file)
@@ -17,7 +17,6 @@
 #include "flash.h"
 #include "blockdev.h"
 #include "sysbus.h"
-#include "exec-memory.h"
 
 /* Device addresses */
 #define MST_FPGA_PHYS  0x08000000
@@ -91,8 +90,7 @@ static struct arm_boot_info mainstone_binfo = {
     .ram_size = 0x04000000,
 };
 
-static void mainstone_common_init(MemoryRegion *address_space_mem,
-                ram_addr_t ram_size,
+static void mainstone_common_init(ram_addr_t ram_size,
                 const char *kernel_filename,
                 const char *kernel_cmdline, const char *initrd_filename,
                 const char *cpu_model, enum mainstone_model_e model, int arm_id)
@@ -103,23 +101,21 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
     DeviceState *mst_irq;
     DriveInfo *dinfo;
     int i;
-    MemoryRegion *rom = g_new(MemoryRegion, 1);
-    MemoryRegion *flashes = g_new(MemoryRegion, 2);
-    const MemoryRegionOps *flash_ops;
+    int be;
 
     if (!cpu_model)
         cpu_model = "pxa270-c5";
 
     /* Setup CPU & memory */
     cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model);
-    memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM);
-    memory_region_set_readonly(rom, true);
-    memory_region_add_subregion(address_space_mem, 0, rom);
+    cpu_register_physical_memory(0, MAINSTONE_ROM,
+                    qemu_ram_alloc(NULL, "mainstone.rom",
+                                   MAINSTONE_ROM) | IO_MEM_ROM);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
     /* There are two 32MiB flash devices on the board */
     for (i = 0; i < 2; i ++) {
@@ -130,14 +126,13 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
             exit(1);
         }
 
-        memory_region_init_rom_device(&flashes[i], flash_ops,
-                                      NULL, (i ? "mainstone.flash1"
-                                               : "mainstone.flash0"),
-                                      MAINSTONE_FLASH);
         if (!pflash_cfi01_register(mainstone_flash_base[i],
-                                   &flashes[i], dinfo->bdrv, sector_len,
-                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0,
-                                   0)) {
+                                   qemu_ram_alloc(NULL, i ? "mainstone.flash1" :
+                                                  "mainstone.flash0",
+                                                  MAINSTONE_FLASH),
+                                   dinfo->bdrv, sector_len,
+                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
+                                   be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
             exit(1);
         }
@@ -175,7 +170,7 @@ static void mainstone_init(ram_addr_t ram_size,
                 const char *kernel_filename, const char *kernel_cmdline,
                 const char *initrd_filename, const char *cpu_model)
 {
-    mainstone_common_init(get_system_memory(), ram_size, kernel_filename,
+    mainstone_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
 }
 
index 1c2c0c48aa9dc9ef6d49208dc4ee1491d4383280..8fe507f82fe7c1c5befbd2fe28d89b4e5a60eca7 100644 (file)
@@ -13,7 +13,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define SYS_FREQ 66000000
 
@@ -28,7 +27,6 @@
 #define PCSR_PRE_MASK   0x0f00
 
 typedef struct {
-    MemoryRegion iomem;
     qemu_irq irq;
     ptimer_state *timer;
     uint16_t pcsr;
@@ -45,7 +43,7 @@ static void m5208_timer_update(m5208_timer_state *s)
 }
 
 static void m5208_timer_write(void *opaque, target_phys_addr_t offset,
-                              uint64_t value, unsigned size)
+                              uint32_t value)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     int prescale;
@@ -106,8 +104,7 @@ static void m5208_timer_trigger(void *opaque)
     m5208_timer_update(s);
 }
 
-static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,
-                                 unsigned size)
+static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     switch (addr) {
@@ -123,14 +120,19 @@ static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static const MemoryRegionOps m5208_timer_ops = {
-    .read = m5208_timer_read,
-    .write = m5208_timer_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const m5208_timer_readfn[] = {
+   m5208_timer_read,
+   m5208_timer_read,
+   m5208_timer_read
 };
 
-static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr,
-                               unsigned size)
+static CPUWriteMemoryFunc * const m5208_timer_writefn[] = {
+   m5208_timer_write,
+   m5208_timer_write,
+   m5208_timer_write
+};
+
+static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr)
 {
     switch (addr) {
     case 0x110: /* SDCS0 */
@@ -152,36 +154,45 @@ static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr,
 }
 
 static void m5208_sys_write(void *opaque, target_phys_addr_t addr,
-                            uint64_t value, unsigned size)
+                            uint32_t value)
 {
     hw_error("m5208_sys_write: Bad offset 0x%x\n", (int)addr);
 }
 
-static const MemoryRegionOps m5208_sys_ops = {
-    .read = m5208_sys_read,
-    .write = m5208_sys_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const m5208_sys_readfn[] = {
+   m5208_sys_read,
+   m5208_sys_read,
+   m5208_sys_read
+};
+
+static CPUWriteMemoryFunc * const m5208_sys_writefn[] = {
+   m5208_sys_write,
+   m5208_sys_write,
+   m5208_sys_write
 };
 
-static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
+static void mcf5208_sys_init(qemu_irq *pic)
 {
-    MemoryRegion *iomem = g_new(MemoryRegion, 1);
+    int iomemtype;
     m5208_timer_state *s;
     QEMUBH *bh;
     int i;
 
+    iomemtype = cpu_register_io_memory(m5208_sys_readfn,
+                                       m5208_sys_writefn, NULL,
+                                       DEVICE_NATIVE_ENDIAN);
     /* SDRAMC.  */
-    memory_region_init_io(iomem, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
-    memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
+    cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype);
     /* Timers.  */
     for (i = 0; i < 2; i++) {
         s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
         bh = qemu_bh_new(m5208_timer_trigger, s);
         s->timer = ptimer_init(bh);
-        memory_region_init_io(&s->iomem, &m5208_timer_ops, s,
-                              "m5208-timer", 0x00004000);
-        memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
-                                    &s->iomem);
+        iomemtype = cpu_register_io_memory(m5208_timer_readfn,
+                                           m5208_timer_writefn, s,
+                                           DEVICE_NATIVE_ENDIAN);
+        cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000,
+                                     iomemtype);
         s->irq = pic[4 + i];
     }
 }
@@ -196,9 +207,6 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     uint64_t elf_entry;
     target_phys_addr_t entry;
     qemu_irq *pic;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5208";
@@ -213,12 +221,12 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     /* TODO: Configure BARs.  */
 
     /* DRAM at 0x40000000 */
-    memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    cpu_register_physical_memory(0x40000000, ram_size,
+        qemu_ram_alloc(NULL, "mcf5208.ram", ram_size) | IO_MEM_RAM);
 
     /* Internal SRAM.  */
-    memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384);
-    memory_region_add_subregion(address_space_mem, 0x80000000, sram);
+    cpu_register_physical_memory(0x80000000, 16384,
+        qemu_ram_alloc(NULL, "mcf5208.sram", 16384) | IO_MEM_RAM);
 
     /* Internal peripherals.  */
     pic = mcf_intc_init(0xfc048000, env);
@@ -227,7 +235,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]);
     mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]);
 
-    mcf5208_sys_init(address_space_mem, pic);
+    mcf5208_sys_init(pic);
 
     if (nb_nics > 1) {
         fprintf(stderr, "Too many NICs\n");
index fb48e37187ad7ba3f99b89455fafc02440600c00..cd360264c165e37856bcadc72cb2295ee4cee3b2 100644 (file)
@@ -97,8 +97,6 @@ struct MilkymistMinimac2State {
     NICConf conf;
     char *phy_model;
     target_phys_addr_t buffers_base;
-    MemoryRegion buffers;
-    MemoryRegion regs_region;
 
     qemu_irq rx_irq;
     qemu_irq tx_irq;
@@ -322,8 +320,8 @@ static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
     return size;
 }
 
-static uint64_t
-minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size)
+static uint32_t
+minimac2_read(void *opaque, target_phys_addr_t addr)
 {
     MilkymistMinimac2State *s = opaque;
     uint32_t r = 0;
@@ -352,8 +350,7 @@ minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size)
 }
 
 static void
-minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value,
-               unsigned size)
+minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     MilkymistMinimac2State *s = opaque;
 
@@ -398,14 +395,16 @@ minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     }
 }
 
-static const MemoryRegionOps minimac2_ops = {
-    .read = minimac2_read,
-    .write = minimac2_write,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const minimac2_read_fn[] = {
+    NULL,
+    NULL,
+    &minimac2_read,
+};
+
+static CPUWriteMemoryFunc * const minimac2_write_fn[] = {
+    NULL,
+    NULL,
+    &minimac2_write,
 };
 
 static int minimac2_can_rx(VLANClientState *nc)
@@ -458,23 +457,25 @@ static NetClientInfo net_milkymist_minimac2_info = {
 static int milkymist_minimac2_init(SysBusDevice *dev)
 {
     MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev);
+    int regs;
+    ram_addr_t buffers;
     size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
 
     sysbus_init_irq(dev, &s->rx_irq);
     sysbus_init_irq(dev, &s->tx_irq);
 
-    memory_region_init_io(&s->regs_region, &minimac2_ops, s,
-                          "minimac2-mmio", R_MAX * 4);
-    sysbus_init_mmio_region(dev, &s->regs_region);
+    regs = cpu_register_io_memory(minimac2_read_fn, minimac2_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, regs);
 
     /* register buffers memory */
-    memory_region_init_ram(&s->buffers, NULL, "milkymist_minimac2.buffers",
-                           buffers_size);
-    s->rx0_buf = memory_region_get_ram_ptr(&s->buffers);
+    buffers = qemu_ram_alloc(NULL, "milkymist_minimac2.buffers", buffers_size);
+    s->rx0_buf = qemu_get_ram_ptr(buffers);
     s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
     s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
 
-    sysbus_add_memory(dev, s->buffers_base, &s->buffers);
+    cpu_register_physical_memory(s->buffers_base, buffers_size,
+            buffers | IO_MEM_RAM);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
index ef4d9ee2ce06759825a09548f1866afc62f10e5e..fe4eedb2cb3e736a35c9ba311eac0beeb6aef39b 100644 (file)
@@ -49,9 +49,6 @@ struct MilkymistSoftUsbState {
     HIDState hid_kbd;
     HIDState hid_mouse;
 
-    MemoryRegion regs_region;
-    MemoryRegion pmem;
-    MemoryRegion dmem;
     qemu_irq irq;
 
     /* device properties */
@@ -71,8 +68,7 @@ struct MilkymistSoftUsbState {
 };
 typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
 
-static uint64_t softusb_read(void *opaque, target_phys_addr_t addr,
-                             unsigned size)
+static uint32_t softusb_read(void *opaque, target_phys_addr_t addr)
 {
     MilkymistSoftUsbState *s = opaque;
     uint32_t r = 0;
@@ -95,8 +91,7 @@ static uint64_t softusb_read(void *opaque, target_phys_addr_t addr,
 }
 
 static void
-softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
-              unsigned size)
+softusb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     MilkymistSoftUsbState *s = opaque;
 
@@ -115,14 +110,16 @@ softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     }
 }
 
-static const MemoryRegionOps softusb_mmio_ops = {
-    .read = softusb_read,
-    .write = softusb_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
+static CPUReadMemoryFunc * const softusb_read_fn[] = {
+    NULL,
+    NULL,
+    &softusb_read,
+};
+
+static CPUWriteMemoryFunc * const softusb_write_fn[] = {
+    NULL,
+    NULL,
+    &softusb_write,
 };
 
 static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
@@ -259,20 +256,23 @@ static void milkymist_softusb_reset(DeviceState *d)
 static int milkymist_softusb_init(SysBusDevice *dev)
 {
     MilkymistSoftUsbState *s = FROM_SYSBUS(typeof(*s), dev);
+    int softusb_regs;
+    ram_addr_t pmem_ram;
+    ram_addr_t dmem_ram;
 
     sysbus_init_irq(dev, &s->irq);
 
-    memory_region_init_io(&s->regs_region, &softusb_mmio_ops, s,
-                          "milkymist-softusb", R_MAX * 4);
-    sysbus_init_mmio_region(dev, &s->regs_region);
+    softusb_regs = cpu_register_io_memory(softusb_read_fn, softusb_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, softusb_regs);
 
     /* register pmem and dmem */
-    memory_region_init_ram(&s->pmem, NULL, "milkymist_softusb.pmem",
-                           s->pmem_size);
-    sysbus_add_memory(dev, s->pmem_base, &s->pmem);
-    memory_region_init_ram(&s->dmem, NULL, "milkymist_softusb.dmem",
-                           s->dmem_size);
-    sysbus_add_memory(dev, s->dmem_base, &s->dmem);
+    pmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.pmem", s->pmem_size);
+    cpu_register_physical_memory(s->pmem_base, s->pmem_size,
+            pmem_ram | IO_MEM_RAM);
+    dmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.dmem", s->dmem_size);
+    cpu_register_physical_memory(s->dmem_base, s->dmem_size,
+            dmem_ram | IO_MEM_RAM);
 
     hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
     hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
index 790cdcb41c0d829d64f213a642d85682538f1598..953d42f16baff83de021279cd56b5b989eaa6b03 100644 (file)
@@ -73,7 +73,7 @@ enum {
 struct vertex {
     int x;
     int y;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct MilkymistTMU2State {
     SysBusDevice busdev;
index ef21ccaba1ea931c8e5aa6741454a0574ec8a2e7..93288c8401951d3a7f15c5be95cf4236bd7d6a82 100644 (file)
@@ -29,7 +29,6 @@
 #include "blockdev.h"
 #include "milkymist-hw.h"
 #include "lm32.h"
-#include "exec-memory.h"
 
 #define BIOS_FILENAME    "mmone-bios.bin"
 #define BIOS_OFFSET      0x00860000
@@ -82,9 +81,8 @@ milkymist_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     int kernel_size;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *phys_sdram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_sdram;
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     int i;
     char *bios_filename;
@@ -111,17 +109,17 @@ milkymist_init(ram_addr_t ram_size_not_used,
 
     cpu_lm32_set_phys_msb_ignore(env, 1);
 
-    memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size);
-    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
+    phys_sdram = qemu_ram_alloc(NULL, "milkymist.sdram", sdram_size);
+    cpu_register_physical_memory(sdram_base, sdram_size,
+            phys_sdram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "milkymist.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
     pflash_cfi01_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 2,
-                          0x00, 0x89, 0x00, 0x1d);
+                          0x00, 0x89, 0x00, 0x1d, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
index 97d7b9e5adf17620f8b7befd033f53056cc4aac6..8ce41fc4be19c73c52bd146fb9c049896b22dc96 100644 (file)
--- a/hw/mips.h
+++ b/hw/mips.h
@@ -2,19 +2,12 @@
 #define HW_MIPS_H
 /* Definitions for mips board emulation.  */
 
-#include "memory.h"
-
 /* gt64xxx.c */
 PCIBus *gt64120_register(qemu_irq *pic);
 
 /* bonito.c */
 PCIBus *bonito_init(qemu_irq *pic);
 
-/* g364fb.c */
-int g364fb_mm_init(MemoryRegion *system_memory, target_phys_addr_t vram_base,
-                   target_phys_addr_t ctrl_base, int it_shift,
-                   qemu_irq irq);
-
 /* mipsnet.c */
 void mipsnet_init(int base, qemu_irq irq, NICInfo *nd);
 
index a74108646c77f17544617cf5f3b1a25b78383c78..f3c9f9320427cf13ccf1403cdd2f4de49776c2a8 100644 (file)
@@ -195,8 +195,20 @@ void mips_jazz_init (ram_addr_t ram_size,
     /* Video card */
     switch (jazz_model) {
     case JAZZ_MAGNUM:
-        g364fb_mm_init(get_system_memory(), 0x40000000, 0x60000000, 0,
-                       rc4030[3]);
+        dev = qdev_create(NULL, "sysbus-g364");
+        qdev_init_nofail(dev);
+        sysbus = sysbus_from_qdev(dev);
+        sysbus_mmio_map(sysbus, 0, 0x60080000);
+        sysbus_mmio_map(sysbus, 1, 0x40000000);
+        sysbus_connect_irq(sysbus, 0, rc4030[3]);
+        {
+            /* Simple ROM, so user doesn't have to provide one */
+            ram_addr_t rom_offset = qemu_ram_alloc(NULL, "g364fb.rom", 0x80000);
+            uint8_t *rom = qemu_get_ram_ptr(rom_offset);
+            cpu_register_physical_memory(0x60000000, 0x80000,
+                                         rom_offset | IO_MEM_ROM);
+            rom[0] = 0x10; /* Mips G364 */
+        }
         break;
     case JAZZ_PICA61:
         isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
index b5c9bcfa515952ee75dde4cdf2143e39a61106a9..a0adb566ab03ee97477ec13efe53e7cad70fa501 100644 (file)
@@ -46,7 +46,6 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -733,6 +732,12 @@ static int64_t load_kernel (void)
     return kernel_entry;
 }
 
+static void malta_mips_config(CPUState *env)
+{
+    env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
+                         ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC);
+}
+
 static void main_cpu_reset(void *opaque)
 {
     CPUState *env = opaque;
@@ -744,6 +749,8 @@ static void main_cpu_reset(void *opaque)
     if (loaderparams.kernel_filename) {
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
     }
+
+    malta_mips_config(env);
 }
 
 static void cpu_request_exit(void *opaque, int irq, int level)
@@ -763,10 +770,7 @@ void mips_malta_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
-    MemoryRegion *bios_1e0 = g_new(MemoryRegion, 1);
-    MemoryRegion *bios_1fc = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     target_long bios_size;
     int64_t kernel_entry;
     PCIBus *pci_bus;
@@ -781,7 +785,7 @@ void mips_malta_init (ram_addr_t ram_size,
     DriveInfo *fd[MAX_FD];
     int fl_idx = 0;
     int fl_sectors = 0;
-    const MemoryRegionOps *bios_ops;
+    int be;
 
     /* Make sure the first 3 serial ports are associated with a device. */
     for(i = 0; i < 3; i++) {
@@ -800,12 +804,19 @@ void mips_malta_init (ram_addr_t ram_size,
         cpu_model = "24Kf";
 #endif
     }
-    env = cpu_init(cpu_model);
-    if (!env) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
+
+    for (i = 0; i < smp_cpus; i++) {
+        env = cpu_init(cpu_model);
+        if (!env) {
+            fprintf(stderr, "Unable to find CPU definition\n");
+            exit(1);
+        }
+        /* Init internal devices */
+        cpu_mips_irq_init_cpu(env);
+        cpu_mips_clock_init(env);
+        qemu_register_reset(main_cpu_reset, env);
     }
-    qemu_register_reset(main_cpu_reset, env);
+    env = first_cpu;
 
     /* allocate RAM */
     if (ram_size > (256 << 20)) {
@@ -814,24 +825,23 @@ void mips_malta_init (ram_addr_t ram_size,
                 ((unsigned int)ram_size / (1 << 20)));
         exit(1);
     }
-#ifdef TARGET_WORDS_BIGENDIAN
-    bios_ops = &pflash_cfi01_ops_be;
-#else
-    bios_ops = &pflash_cfi01_ops_le;
-#endif
-
     ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
-    memory_region_init_rom_device(bios, bios_ops, NULL,
-                                  "mips_malta.bios", BIOS_SIZE);
+    bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE);
+
 
     cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Map the bios at two physical locations, as on the real board. */
-    memory_region_init_alias(bios_1e0, "bios-1e0", bios, 0, BIOS_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x1e000000LL, bios_1e0);
-    memory_region_init_alias(bios_1fc, "bios-1fc", bios, 0, BIOS_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios_1fc);
+    cpu_register_physical_memory(0x1e000000LL,
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
+    cpu_register_physical_memory(0x1fc00000LL,
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
 
+#ifdef TARGET_WORDS_BIGENDIAN
+    be = 1;
+#else
+    be = 0;
+#endif
     /* FPGA */
     malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
 
@@ -843,7 +853,7 @@ void mips_malta_init (ram_addr_t ram_size,
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
         kernel_entry = load_kernel();
-        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
+        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
     } else {
         dinfo = drive_get(IF_PFLASH, 0, fl_idx);
         if (dinfo) {
@@ -852,13 +862,13 @@ void mips_malta_init (ram_addr_t ram_size,
             fl_sectors = bios_size >> 16;
 #ifdef DEBUG_BOARD_INIT
             printf("Register parallel flash %d size " TARGET_FMT_lx " at "
-                   "addr %08llx '%s' %x\n",
-                   fl_idx, bios_size, 0x1e000000LL,
+                   "offset %08lx addr %08llx '%s' %x\n",
+                   fl_idx, bios_size, bios_offset, 0x1e000000LL,
                    bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-            pflash_cfi01_register(0x1e000000LL, bios,
+            pflash_cfi01_register(0x1e000000LL, bios_offset,
                                   dinfo->bdrv, 65536, fl_sectors,
-                                  4, 0x0000, 0x0000, 0x0000, 0x0000);
+                                  4, 0x0000, 0x0000, 0x0000, 0x0000, be);
             fl_idx++;
         } else {
             /* Load a BIOS image. */
@@ -883,7 +893,7 @@ void mips_malta_init (ram_addr_t ram_size,
            a neat trick which allows bi-endian firmware. */
 #ifndef TARGET_WORDS_BIGENDIAN
         {
-            uint32_t *addr = memory_region_get_ram_ptr(bios);
+            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
             uint32_t *end = addr + bios_size;
             while (addr < end) {
                 bswap32s(addr);
@@ -895,7 +905,7 @@ void mips_malta_init (ram_addr_t ram_size,
     /* Board ID = 0x420 (Malta Board with CoreLV)
        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
        map to the board ID. */
-    stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
+    stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420);
 
     /* Init internal devices */
     cpu_mips_irq_init_cpu(env);
@@ -960,6 +970,7 @@ static QEMUMachine mips_malta_machine = {
     .name = "malta",
     .desc = "MIPS Malta Core LV",
     .init = mips_malta_init,
+    .max_cpus = 16,
     .is_default = 1,
 };
 
index 51dc8684be740586a1076ff02efcd9f893c4b425..9d90568e4e36f3dd30fa9227df204faa58beafb8 100644 (file)
@@ -23,7 +23,6 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 
@@ -164,8 +163,7 @@ void mips_r4k_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     int bios_size;
     CPUState *env;
     ResetData *reset_info;
@@ -229,20 +227,18 @@ void mips_r4k_init (ram_addr_t ram_size,
     be = 0;
 #endif
     if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
-        memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE);
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem, 0x1fc00000, bios);
+        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE);
+       cpu_register_physical_memory(0x1fc00000, BIOS_SIZE,
+                                     bios_offset | IO_MEM_ROM);
+
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
-        memory_region_init_rom_device(bios,
-                                      (be ? &pflash_cfi01_ops_be
-                                          : &pflash_cfi01_ops_le),
-                                      NULL, "mips_r4k.bios", mips_rom);
-        if (!pflash_cfi01_register(0x1fc00000, bios,
+        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom);
+        if (!pflash_cfi01_register(0x1fc00000, bios_offset,
                                    dinfo->bdrv, sector_len,
                                    mips_rom / sector_len,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
        }
     }
index 5e74ee7fd736cf60f377a76ac4d585a12ebae326..63dd391176521fd94f9b2d136b57476f3042406d 100644 (file)
@@ -1502,7 +1502,6 @@ static void musicpal_init(ram_addr_t ram_size,
     unsigned long flash_size;
     DriveInfo *dinfo;
     ram_addr_t sram_off;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "arm926";
@@ -1566,23 +1565,21 @@ static void musicpal_init(ram_addr_t ram_size,
          * image is smaller than 32 MB.
          */
 #ifdef TARGET_WORDS_BIGENDIAN
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
-                                      NULL, "musicpal.flash", flash_size);
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
+                              "musicpal.flash", flash_size),
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA);
+                              0x5555, 0x2AAA, 1);
 #else
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
-                                      NULL, "musicpal.flash", flash_size);
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
+                              "musicpal.flash", flash_size),
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA);
+                              0x5555, 0x2AAA, 0);
 #endif
 
     }
index f7aae7a59eb04881abfb60ac59482396870bfc2c..af287dd6dc7380e5bba0d00cfee9865b0e00d345 100644 (file)
@@ -32,7 +32,7 @@
 #include "bt.h"
 #include "loader.h"
 #include "blockdev.h"
-#include "tusb6010.h"
+#include "sysbus.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
@@ -49,10 +49,10 @@ struct n800_s {
     int keymap[0x80];
     DeviceState *kbd;
 
-    TUSBState *usb;
+    DeviceState *usb;
     void *retu;
     void *tahvo;
-    void *nand;
+    DeviceState *nand;
 };
 
 /* GPIO pins */
@@ -167,13 +167,21 @@ static void n8x0_nand_setup(struct n800_s *s)
     char *otp_region;
     DriveInfo *dinfo;
 
-    dinfo = drive_get(IF_MTD, 0, 0);
+    s->nand = qdev_create(NULL, "onenand");
+    qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
     /* Either 0x40 or 0x48 are OK for the device ID */
-    s->nand = onenand_init(dinfo ? dinfo->bdrv : 0,
-                    NAND_MFR_SAMSUNG, 0x48, 0, 1,
-                    qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
-    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
-                    onenand_base_unmap, s->nand);
+    qdev_prop_set_uint16(s->nand, "device_id", 0x48);
+    qdev_prop_set_uint16(s->nand, "version_id", 0);
+    qdev_prop_set_int32(s->nand, "shift", 1);
+    dinfo = drive_get(IF_MTD, 0, 0);
+    if (dinfo && dinfo->bdrv) {
+        qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
+    }
+    qdev_init_nofail(s->nand);
+    sysbus_connect_irq(sysbus_from_qdev(s->nand), 0,
+                       qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
+    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS,
+                     sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0));
     otp_region = onenand_raw_otp(s->nand);
 
     memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
@@ -756,27 +764,21 @@ static void n8x0_uart_setup(struct n800_s *s)
     omap_uart_attach(s->cpu->uart[BT_UART], radio);
 }
 
-static void n8x0_usb_power_cb(void *opaque, int line, int level)
-{
-    struct n800_s *s = opaque;
-
-    tusb6010_power(s->usb, level);
-}
-
 static void n8x0_usb_setup(struct n800_s *s)
 {
-    qemu_irq tusb_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO);
-    qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
-    TUSBState *tusb = tusb6010_init(tusb_irq);
-
+    SysBusDevice *dev;
+    s->usb = qdev_create(NULL, "tusb6010");
+    dev = sysbus_from_qdev(s->usb);
+    qdev_init_nofail(s->usb);
+    sysbus_connect_irq(dev, 0,
+                       qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO));
     /* Using the NOR interface */
     omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
-                    tusb6010_async_io(tusb), NULL, NULL, tusb);
+                     sysbus_mmio_get_region(dev, 0));
     omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
-                    tusb6010_sync_io(tusb), NULL, NULL, tusb);
-
-    s->usb = tusb;
-    qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
+                     sysbus_mmio_get_region(dev, 1));
+    qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO,
+                          qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
 }
 
 /* Setup done before the main bootloader starts by some early setup code
index db101c61f33f1ed12986c55b6b596a588d3d4bfc..d9ab006ae0ce15101cf40e762915976971120b56 100644 (file)
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -118,11 +118,12 @@ void omap_sdrc_reset(struct omap_sdrc_s *s);
 
 /* OMAP2 general purpose memory controller */
 struct omap_gpmc_s;
-struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
+struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
+                                   target_phys_addr_t base,
+                                   qemu_irq irq, qemu_irq drq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
-                void (*base_upd)(void *opaque, target_phys_addr_t new),
-                void (*unmap)(void *opaque), void *opaque);
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem);
+void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand);
 
 /*
  * Common IRQ numbers for level 1 interrupt handler
@@ -788,6 +789,7 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
 # define cpu_is_omap2420(cpu)          (cpu->mpu_model == omap2420)
 # define cpu_is_omap2430(cpu)          (cpu->mpu_model == omap2430)
 # define cpu_is_omap3430(cpu)          (cpu->mpu_model == omap3430)
+# define cpu_is_omap3630(cpu)           (cpu->mpu_model == omap3630)
 
 # define cpu_is_omap15xx(cpu)          \
         (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu))
@@ -799,7 +801,8 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
 # define cpu_class_omap1(cpu)          \
         (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu))
 # define cpu_class_omap2(cpu)          cpu_is_omap24xx(cpu)
-# define cpu_class_omap3(cpu)          cpu_is_omap3430(cpu)
+# define cpu_class_omap3(cpu) \
+        (cpu_is_omap3430(cpu) || cpu_is_omap3630(cpu))
 
 struct omap_mpu_state_s {
     enum omap_mpu_model {
@@ -813,6 +816,7 @@ struct omap_mpu_state_s {
         omap2423,
         omap2430,
         omap3430,
+        omap3630,
     } mpu_model;
 
     CPUState *env;
index 7e5820a97bd9715dac22916097702795e416d717..ca088d9f5384f725d33729cba7152dabb902856f 100644 (file)
@@ -2402,7 +2402,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
     sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
 
     s->sdrc = omap_sdrc_init(0x68009000);
-    s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
+    s->gpmc = omap_gpmc_init(s, 0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ],
+                             s->drq[OMAP24XX_DMA_GPMC]);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
index 673dddd237fab9bcdcd4b54e6179db66a629aaf1..02f0c521071b1ffdc8bf87916a58e3e0732a503e 100644 (file)
 /* General-Purpose Memory Controller */
 struct omap_gpmc_s {
     qemu_irq irq;
+    qemu_irq drq;
     MemoryRegion iomem;
+    int accept_256;
 
+    uint8_t revision;
     uint8_t sysconfig;
     uint16_t irqst;
     uint16_t irqen;
+    uint16_t lastirq;
     uint16_t timeout;
     uint16_t config;
-    uint32_t prefconfig[2];
-    int prefcontrol;
-    int preffifo;
-    int prefcount;
     struct omap_gpmc_cs_file_s {
         uint32_t config[7];
-        target_phys_addr_t base;
-        size_t size;
         MemoryRegion *iomem;
         MemoryRegion container;
-        void (*base_update)(void *opaque, target_phys_addr_t new);
-        void (*unmap)(void *opaque);
-        void *opaque;
+        MemoryRegion nandiomem;
+        DeviceState *dev;
     } cs_file[8];
     int ecc_cs;
     int ecc_ptr;
     uint32_t ecc_cfg;
     ECCState ecc[9];
+    struct prefetch {
+        uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */
+        uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */
+        int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
+        int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
+        int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
+        MemoryRegion iomem;
+        uint8_t fifo[64];
+    } prefetch;
 };
 
+#define OMAP_GPMC_8BIT 0
+#define OMAP_GPMC_16BIT 1
+#define OMAP_GPMC_NOR 0
+#define OMAP_GPMC_NAND 2
+
+static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f)
+{
+    return (f->config[0] >> 10) & 3;
+}
+
+static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
+{
+    /* devsize field is really 2 bits but we ignore the high
+     * bit to ensure consistent behaviour if the guest sets
+     * it (values 2 and 3 are reserved in the TRM)
+     */
+    return (f->config[0] >> 12) & 1;
+}
+
+/* Extract the chip-select value from the prefetch config1 register */
+static int prefetch_cs(uint32_t config1)
+{
+    return (config1 >> 24) & 7;
+}
+
+static int prefetch_threshold(uint32_t config1)
+{
+    return (config1 >> 8) & 0x7f;
+}
+
 static void omap_gpmc_int_update(struct omap_gpmc_s *s)
 {
-    qemu_set_irq(s->irq, s->irqen & s->irqst);
+    /* The TRM is a bit unclear, but it seems to say that
+     * the TERMINALCOUNTSTATUS bit is set only on the
+     * transition when the prefetch engine goes from
+     * active to inactive, whereas the FIFOEVENTSTATUS
+     * bit is held high as long as the fifo has at
+     * least THRESHOLD bytes available.
+     * So we do the latter here, but TERMINALCOUNTSTATUS
+     * is set elsewhere.
+     */
+    if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) {
+        s->irqst |= 1;
+    }
+    if ((s->irqen & s->irqst) != s->lastirq) {
+        s->lastirq = s->irqen & s->irqst;
+        qemu_set_irq(s->irq, s->lastirq);
+    }
 }
 
-static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
+static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
 {
-    /* TODO: check for overlapping regions and report access errors */
-    if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
-                    (base < 0 || base >= 0x40) ||
-                    (base & 0x0f & ~mask)) {
-        fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
-                        __FUNCTION__);
+    if (s->prefetch.config1 & 4) {
+        qemu_set_irq(s->drq, value);
+    }
+}
+
+/* Access functions for when a NAND-like device is mapped into memory:
+ * all addresses in the region behave like accesses to the relevant
+ * GPMC_NAND_DATA_i register (which is actually implemented to call these)
+ */
+static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
+{
+    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
+    uint64_t v;
+    nand_setpins(f->dev, 0, 0, 0, 1, 0);
+    switch (omap_gpmc_devsize(f)) {
+    case OMAP_GPMC_8BIT:
+        v = nand_getio(f->dev);
+        if (size == 1) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 8);
+        if (size == 2) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 16);
+        v |= (nand_getio(f->dev) << 24);
+        return v;
+    case OMAP_GPMC_16BIT:
+        v = nand_getio(f->dev);
+        if (size == 1) {
+            /* 8 bit read from 16 bit device : probably a guest bug */
+            return v & 0xff;
+        }
+        if (size == 2) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 16);
+        return v;
+    default:
+        abort();
+    }
+}
+
+static void omap_nand_setio(DeviceState *dev, uint64_t value,
+                            int nandsize, int size)
+{
+    /* Write the specified value to the NAND device, respecting
+     * both size of the NAND device and size of the write access.
+     */
+    switch (nandsize) {
+    case OMAP_GPMC_8BIT:
+        switch (size) {
+        case 1:
+            nand_setio(dev, value & 0xff);
+            break;
+        case 2:
+            nand_setio(dev, value & 0xff);
+            nand_setio(dev, (value >> 8) & 0xff);
+            break;
+        case 4:
+        default:
+            nand_setio(dev, value & 0xff);
+            nand_setio(dev, (value >> 8) & 0xff);
+            nand_setio(dev, (value >> 16) & 0xff);
+            nand_setio(dev, (value >> 24) & 0xff);
+            break;
+        }
+    case OMAP_GPMC_16BIT:
+        switch (size) {
+        case 1:
+            /* writing to a 16bit device with 8bit access is probably a guest
+             * bug; pass the value through anyway.
+             */
+        case 2:
+            nand_setio(dev, value & 0xffff);
+            break;
+        case 4:
+        default:
+            nand_setio(dev, value & 0xffff);
+            nand_setio(dev, (value >> 16) & 0xffff);
+            break;
+        }
+    }
+}
+
+static void omap_nand_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t value, unsigned size)
+{
+    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
+    nand_setpins(f->dev, 0, 0, 0, 1, 0);
+    omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+}
+
+static const MemoryRegionOps omap_nand_ops = {
+    .read = omap_nand_read,
+    .write = omap_nand_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void fill_prefetch_fifo(struct omap_gpmc_s *s)
+{
+    /* Fill the prefetch FIFO by reading data from NAND.
+     * We do this synchronously, unlike the hardware which
+     * will do this asynchronously. We refill when the
+     * FIFO has THRESHOLD bytes free, and we always refill
+     * as much data as possible starting at the top end
+     * of the FIFO.
+     * (We have to refill at THRESHOLD rather than waiting
+     * for the FIFO to empty to allow for the case where
+     * the FIFO size isn't an exact multiple of THRESHOLD
+     * and we're doing DMA transfers.)
+     * This means we never need to handle wrap-around in
+     * the fifo-reading code, and the next byte of data
+     * to read is always fifo[63 - fifopointer].
+     */
+    int fptr;
+    int cs = prefetch_cs(s->prefetch.config1);
+    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
+    int bytes;
+    /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE
+     * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND.
+     * Instead believe the bit that says it is always a byte count.
+     */
+    bytes = 64 - s->prefetch.fifopointer;
+    if (bytes > s->prefetch.count) {
+        bytes = s->prefetch.count;
+    }
+    s->prefetch.count -= bytes;
+    s->prefetch.fifopointer += bytes;
+    fptr = 64 - s->prefetch.fifopointer;
+    /* Move the existing data in the FIFO so it sits just
+     * before what we're about to read in
+     */
+    while (fptr < (64 - bytes)) {
+        s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes];
+        fptr++;
+    }
+    while (fptr < 64) {
+        if (is16bit) {
+            uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2);
+            s->prefetch.fifo[fptr++] = v & 0xff;
+            s->prefetch.fifo[fptr++] = (v >> 8) & 0xff;
+        } else {
+            s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1);
+        }
+    }
+    if (s->prefetch.startengine && (s->prefetch.count == 0)) {
+        /* This was the final transfer: raise TERMINALCOUNTSTATUS */
+        s->irqst |= 2;
+        s->prefetch.startengine = 0;
+    }
+    /* If there are any bytes in the FIFO at this point then
+     * we must raise a DMA request (either this is a final part
+     * transfer, or we filled the FIFO in which case we certainly
+     * have THRESHOLD bytes available)
+     */
+    if (s->prefetch.fifopointer != 0) {
+        omap_gpmc_dma_update(s, 1);
+    }
+    omap_gpmc_int_update(s);
+}
+
+/* Access functions for a NAND-like device when the prefetch/postwrite
+ * engine is enabled -- all addresses in the region behave alike:
+ * data is read or written to the FIFO.
+ */
+static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr,
+                                        unsigned size)
+{
+    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
+    uint32_t data;
+    if (s->prefetch.config1 & 1) {
+        /* The TRM doesn't define the behaviour if you read from the
+         * FIFO when the prefetch engine is in write mode. We choose
+         * to always return zero.
+         */
+        return 0;
+    }
+    /* Note that trying to read an empty fifo repeats the last byte */
+    if (s->prefetch.fifopointer) {
+        s->prefetch.fifopointer--;
+    }
+    data = s->prefetch.fifo[63 - s->prefetch.fifopointer];
+    if (s->prefetch.fifopointer ==
+        (64 - prefetch_threshold(s->prefetch.config1))) {
+        /* We've drained THRESHOLD bytes now. So deassert the
+         * DMA request, then refill the FIFO (which will probably
+         * assert it again.)
+         */
+        omap_gpmc_dma_update(s, 0);
+        fill_prefetch_fifo(s);
+    }
+    omap_gpmc_int_update(s);
+    return data;
+}
+
+static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr,
+                                     uint64_t value, unsigned size)
+{
+    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
+    int cs = prefetch_cs(s->prefetch.config1);
+    if ((s->prefetch.config1 & 1) == 0) {
+        /* The TRM doesn't define the behaviour of writing to the
+         * FIFO when the prefetch engine is in read mode. We
+         * choose to ignore the write.
+         */
+        return;
+    }
+    if (s->prefetch.count == 0) {
+        /* The TRM doesn't define the behaviour of writing to the
+         * FIFO if the transfer is complete. We choose to ignore.
+         */
         return;
     }
+    /* The only reason we do any data buffering in postwrite
+     * mode is if we are talking to a 16 bit NAND device, in
+     * which case we need to buffer the first byte of the
+     * 16 bit word until the other byte arrives.
+     */
+    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
+    if (is16bit) {
+        /* fifopointer alternates between 64 (waiting for first
+         * byte of word) and 63 (waiting for second byte)
+         */
+        if (s->prefetch.fifopointer == 64) {
+            s->prefetch.fifo[0] = value;
+            s->prefetch.fifopointer--;
+        } else {
+            value = (value << 8) | s->prefetch.fifo[0];
+            omap_nand_write(&s->cs_file[cs], 0, value, 2);
+            s->prefetch.count--;
+            s->prefetch.fifopointer = 64;
+        }
+    } else {
+        /* Just write the byte : fifopointer remains 64 at all times */
+        omap_nand_write(&s->cs_file[cs], 0, value, 1);
+        s->prefetch.count--;
+    }
+    if (s->prefetch.count == 0) {
+        /* Final transfer: raise TERMINALCOUNTSTATUS */
+        s->irqst |= 2;
+        s->prefetch.startengine = 0;
+    }
+    omap_gpmc_int_update(s);
+}
+
+static const MemoryRegionOps omap_prefetch_ops = {
+    .read = omap_gpmc_prefetch_read,
+    .write = omap_gpmc_prefetch_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+};
 
-    if (!f->opaque)
+static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
+{
+    /* Return the MemoryRegion* to map/unmap for this chipselect */
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
+        return f->iomem;
+    }
+    if ((s->prefetch.config1 & 0x80) &&
+        (prefetch_cs(s->prefetch.config1) == cs)) {
+        /* The prefetch engine is enabled for this CS: map the FIFO */
+        return &s->prefetch.iomem;
+    }
+    return &f->nandiomem;
+}
+
+static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
+{
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    uint32_t mask = (f->config[6] >> 8) & 0xf;
+    uint32_t base = f->config[6] & 0x3f;
+    uint32_t size;
+
+    if (!f->iomem && !f->dev) {
+        return;
+    }
+
+    if (!(f->config[6] & (1 << 6))) {
+        /* Do nothing unless CSVALID */
         return;
+    }
 
-    f->base = base << 24;
-    f->size = (0x0fffffff & ~(mask << 24)) + 1;
+    /* TODO: check for overlapping regions and report access errors */
+    if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf
+         && !(s->accept_256 && !mask)) {
+        fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n",
+                 __func__, mask);
+    }
+
+    base <<= 24;
+    size = (0x0fffffff & ~(mask << 24)) + 1;
     /* TODO: rather than setting the size of the mapping (which should be
      * constant), the mask should cause wrapping of the address space, so
      * that the same memory becomes accessible at every <i>size</i> bytes
      * starting from <i>base</i>.  */
-    if (f->iomem) {
-        memory_region_init(&f->container, "omap-gpmc-file", f->size);
-        memory_region_add_subregion(&f->container, 0, f->iomem);
-        memory_region_add_subregion(get_system_memory(), f->base,
-                                    &f->container);
-    }
-
-    if (f->base_update)
-        f->base_update(f->opaque, f->base);
+    memory_region_init(&f->container, "omap-gpmc-file", size);
+    memory_region_add_subregion(&f->container, 0,
+                                omap_gpmc_cs_memregion(s, cs));
+    memory_region_add_subregion(get_system_memory(), base,
+                                &f->container);
 }
 
-static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
+static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
 {
-    if (f->size) {
-        if (f->unmap)
-            f->unmap(f->opaque);
-        if (f->iomem) {
-            memory_region_del_subregion(get_system_memory(), &f->container);
-            memory_region_del_subregion(&f->container, f->iomem);
-            memory_region_destroy(&f->container);
-        }
-        f->base = 0;
-        f->size = 0;
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    if (!(f->config[6] & (1 << 6))) {
+        /* Do nothing unless CSVALID */
+        return;
+    }
+    if (!f->iomem && !f->dev) {
+        return;
     }
+    memory_region_del_subregion(get_system_memory(), &f->container);
+    memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
+    memory_region_destroy(&f->container);
 }
 
 void omap_gpmc_reset(struct omap_gpmc_s *s)
@@ -115,25 +443,32 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
     omap_gpmc_int_update(s);
     s->timeout = 0;
     s->config = 0xa00;
-    s->prefconfig[0] = 0x00004000;
-    s->prefconfig[1] = 0x00000000;
-    s->prefcontrol = 0;
-    s->preffifo = 0;
-    s->prefcount = 0;
+    s->prefetch.config1 = 0x00004000;
+    s->prefetch.transfercount = 0x00000000;
+    s->prefetch.startengine = 0;
+    s->prefetch.fifopointer = 0;
+    s->prefetch.count = 0;
     for (i = 0; i < 8; i ++) {
-        if (s->cs_file[i].config[6] & (1 << 6))                        /* CSVALID */
-            omap_gpmc_cs_unmap(s->cs_file + i);
-        s->cs_file[i].config[0] = i ? 1 << 12 : 0;
+        omap_gpmc_cs_unmap(s, i);
         s->cs_file[i].config[1] = 0x101001;
         s->cs_file[i].config[2] = 0x020201;
         s->cs_file[i].config[3] = 0x10031003;
         s->cs_file[i].config[4] = 0x10f1111;
         s->cs_file[i].config[5] = 0;
         s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
-        if (s->cs_file[i].config[6] & (1 << 6))                        /* CSVALID */
-            omap_gpmc_cs_map(&s->cs_file[i],
-                            s->cs_file[i].config[6] & 0x1f,    /* MASKADDR */
-                        (s->cs_file[i].config[6] >> 8 & 0xf)); /* BASEADDR */
+
+        s->cs_file[i].config[6] = 0xf00;
+        /* In theory we could probe attached devices for some CFG1
+         * bits here, but we just retain them across resets as they
+         * were set initially by omap_gpmc_attach().
+         */
+        if (i == 0) {
+            s->cs_file[i].config[0] &= 0x00433e00;
+            s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
+            omap_gpmc_cs_map(s, i);
+        } else {
+            s->cs_file[i].config[0] &= 0x00403c00;
+        }
     }
     s->ecc_cs = 0;
     s->ecc_ptr = 0;
@@ -142,6 +477,24 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
         ecc_reset(&s->ecc[i]);
 }
 
+static int gpmc_wordaccess_only(target_phys_addr_t addr)
+{
+    /* Return true if the register offset is to a register that
+     * only permits word width accesses.
+     * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND
+     * for any chipselect.
+     */
+    if (addr >= 0x60 && addr <= 0x1d4) {
+        int cs = (addr - 0x60) / 0x30;
+        addr -= cs * 0x30;
+        if (addr >= 0x7c && addr < 0x88) {
+            /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */
+            return 0;
+        }
+    }
+    return 1;
+}
+
 static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
                                unsigned size)
 {
@@ -149,13 +502,13 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
-    if (size != 4) {
+    if (size != 4 && gpmc_wordaccess_only(addr)) {
         return omap_badwidth_read32(opaque, addr);
     }
 
     switch (addr) {
     case 0x000:        /* GPMC_REVISION */
-        return 0x20;
+        return s->revision;
 
     case 0x010:        /* GPMC_SYSCONFIG */
         return s->sysconfig;
@@ -187,36 +540,39 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
         addr -= cs * 0x30;
         f = s->cs_file + cs;
         switch (addr) {
-            case 0x60: /* GPMC_CONFIG1 */
-                return f->config[0];
-            case 0x64: /* GPMC_CONFIG2 */
-                return f->config[1];
-            case 0x68: /* GPMC_CONFIG3 */
-                return f->config[2];
-            case 0x6c: /* GPMC_CONFIG4 */
-                return f->config[3];
-            case 0x70: /* GPMC_CONFIG5 */
-                return f->config[4];
-            case 0x74: /* GPMC_CONFIG6 */
-                return f->config[5];
-            case 0x78: /* GPMC_CONFIG7 */
-                return f->config[6];
-            case 0x84: /* GPMC_NAND_DATA */
-                return 0;
+        case 0x60:      /* GPMC_CONFIG1 */
+            return f->config[0];
+        case 0x64:      /* GPMC_CONFIG2 */
+            return f->config[1];
+        case 0x68:      /* GPMC_CONFIG3 */
+            return f->config[2];
+        case 0x6c:      /* GPMC_CONFIG4 */
+            return f->config[3];
+        case 0x70:      /* GPMC_CONFIG5 */
+            return f->config[4];
+        case 0x74:      /* GPMC_CONFIG6 */
+            return f->config[5];
+        case 0x78:      /* GPMC_CONFIG7 */
+            return f->config[6];
+        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                return omap_nand_read(f, 0, size);
+            }
+            return 0;
         }
         break;
 
     case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
-        return s->prefconfig[0];
+        return s->prefetch.config1;
     case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
-        return s->prefconfig[1];
+        return s->prefetch.transfercount;
     case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
-        return s->prefcontrol;
+        return s->prefetch.startengine;
     case 0x1f0:        /* GPMC_PREFETCH_STATUS */
-        return (s->preffifo << 24) |
-                ((s->preffifo >
-                  ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
-                s->prefcount;
+        return (s->prefetch.fifopointer << 24) |
+                ((s->prefetch.fifopointer >=
+                  ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
+                s->prefetch.count;
 
     case 0x1f4:        /* GPMC_ECC_CONFIG */
         return s->ecc_cs;
@@ -251,7 +607,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
-    if (size != 4) {
+    if (size != 4 && gpmc_wordaccess_only(addr)) {
         return omap_badwidth_write32(opaque, addr, value);
     }
 
@@ -276,7 +632,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x018:        /* GPMC_IRQSTATUS */
-        s->irqen = ~value;
+        s->irqen &= ~value;
         omap_gpmc_int_update(s);
         break;
 
@@ -302,62 +658,109 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         addr -= cs * 0x30;
         f = s->cs_file + cs;
         switch (addr) {
-            case 0x60: /* GPMC_CONFIG1 */
-                f->config[0] = value & 0xffef3e13;
-                break;
-            case 0x64: /* GPMC_CONFIG2 */
-                f->config[1] = value & 0x001f1f8f;
-                break;
-            case 0x68: /* GPMC_CONFIG3 */
-                f->config[2] = value & 0x001f1f8f;
-                break;
-            case 0x6c: /* GPMC_CONFIG4 */
-                f->config[3] = value & 0x1f8f1f8f;
-                break;
-            case 0x70: /* GPMC_CONFIG5 */
-                f->config[4] = value & 0x0f1f1f1f;
-                break;
-            case 0x74: /* GPMC_CONFIG6 */
-                f->config[5] = value & 0x00000fcf;
-                break;
-            case 0x78: /* GPMC_CONFIG7 */
-                if ((f->config[6] ^ value) & 0xf7f) {
-                    if (f->config[6] & (1 << 6))               /* CSVALID */
-                        omap_gpmc_cs_unmap(f);
-                    if (value & (1 << 6))                      /* CSVALID */
-                        omap_gpmc_cs_map(f, value & 0x1f,      /* MASKADDR */
-                                        (value >> 8 & 0xf));   /* BASEADDR */
-                }
+        case 0x60:      /* GPMC_CONFIG1 */
+            f->config[0] = value & 0xffef3e13;
+            break;
+        case 0x64:      /* GPMC_CONFIG2 */
+            f->config[1] = value & 0x001f1f8f;
+            break;
+        case 0x68:      /* GPMC_CONFIG3 */
+            f->config[2] = value & 0x001f1f8f;
+            break;
+        case 0x6c:      /* GPMC_CONFIG4 */
+            f->config[3] = value & 0x1f8f1f8f;
+            break;
+        case 0x70:      /* GPMC_CONFIG5 */
+            f->config[4] = value & 0x0f1f1f1f;
+            break;
+        case 0x74:      /* GPMC_CONFIG6 */
+            f->config[5] = value & 0x00000fcf;
+            break;
+        case 0x78:      /* GPMC_CONFIG7 */
+            if ((f->config[6] ^ value) & 0xf7f) {
+                omap_gpmc_cs_unmap(s, cs);
                 f->config[6] = value & 0x00000f7f;
-                break;
-            case 0x7c: /* GPMC_NAND_COMMAND */
-            case 0x80: /* GPMC_NAND_ADDRESS */
-            case 0x84: /* GPMC_NAND_DATA */
-                break;
-
-            default:
-                goto bad_reg;
+                omap_gpmc_cs_map(s, cs);
+            }
+            break;
+        case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */
+                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+            }
+            break;
+        case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */
+                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+            }
+            break;
+        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                omap_nand_write(f, 0, value, size);
+            }
+            break;
+        default:
+            goto bad_reg;
         }
         break;
 
     case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
-        s->prefconfig[0] = value & 0x7f8f7fbf;
-        /* TODO: update interrupts, fifos, dmas */
+        if (!s->prefetch.startengine) {
+            uint32_t oldconfig1 = s->prefetch.config1;
+            uint32_t changed;
+            s->prefetch.config1 = value & 0x7f8f7fbf;
+            changed = oldconfig1 ^ s->prefetch.config1;
+            if (changed & (0x80 | 0x7000000)) {
+                /* Turning the engine on or off, or mapping it somewhere else.
+                 * cs_map() and cs_unmap() check the prefetch config and
+                 * overall CSVALID bits, so it is sufficient to unmap-and-map
+                 * both the old cs and the new one.
+                 */
+                int oldcs = prefetch_cs(oldconfig1);
+                int newcs = prefetch_cs(s->prefetch.config1);
+                omap_gpmc_cs_unmap(s, oldcs);
+                omap_gpmc_cs_map(s, oldcs);
+                if (newcs != oldcs) {
+                    omap_gpmc_cs_unmap(s, newcs);
+                    omap_gpmc_cs_map(s, newcs);
+                }
+            }
+        }
         break;
 
     case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
-        s->prefconfig[1] = value & 0x3fff;
+        if (!s->prefetch.startengine) {
+            s->prefetch.transfercount = value & 0x3fff;
+        }
         break;
 
     case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
-        s->prefcontrol = value & 1;
-        if (s->prefcontrol) {
-            if (s->prefconfig[0] & 1)
-                s->preffifo = 0x40;
-            else
-                s->preffifo = 0x00;
+        if (s->prefetch.startengine != (value & 1)) {
+            s->prefetch.startengine = value & 1;
+            if (s->prefetch.startengine) {
+                /* Prefetch engine start */
+                s->prefetch.count = s->prefetch.transfercount;
+                if (s->prefetch.config1 & 1) {
+                    /* Write */
+                    s->prefetch.fifopointer = 64;
+                } else {
+                    /* Read */
+                    s->prefetch.fifopointer = 0;
+                    fill_prefetch_fifo(s);
+                }
+            } else {
+                /* Prefetch engine forcibly stopped. The TRM
+                 * doesn't define the behaviour if you do this.
+                 * We clear the prefetch count, which means that
+                 * we permit no more writes, and don't read any
+                 * more data from NAND. The CPU can still drain
+                 * the FIFO of unread data.
+                 */
+                s->prefetch.count = 0;
+            }
+            omap_gpmc_int_update(s);
         }
-        /* TODO: start */
         break;
 
     case 0x1f4:        /* GPMC_ECC_CONFIG */
@@ -394,24 +797,47 @@ static const MemoryRegionOps omap_gpmc_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
+struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
+                                   target_phys_addr_t base,
+                                   qemu_irq irq, qemu_irq drq)
 {
+    int cs;
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
             g_malloc0(sizeof(struct omap_gpmc_s));
 
-    omap_gpmc_reset(s);
-
     memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
+    s->irq = irq;
+    s->drq = drq;
+    s->accept_256 = cpu_is_omap3630(mpu);
+    s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
+    s->lastirq = 0;
+    omap_gpmc_reset(s);
+
+    /* We have to register a different IO memory handler for each
+     * chip select region in case a NAND device is mapped there. We
+     * make the region the worst-case size of 256MB and rely on the
+     * container memory region in cs_map to chop it down to the actual
+     * guest-requested size.
+     */
+    for (cs = 0; cs < 8; cs++) {
+        memory_region_init_io(&s->cs_file[cs].nandiomem,
+                              &omap_nand_ops,
+                              &s->cs_file[cs],
+                              "omap-nand",
+                              256 * 1024 * 1024);
+    }
+
+    memory_region_init_io(&s->prefetch.iomem, &omap_prefetch_ops, s,
+                          "omap-gpmc-prefetch", 256 * 1024 * 1024);
     return s;
 }
 
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
-                void (*base_upd)(void *opaque, target_phys_addr_t new),
-                void (*unmap)(void *opaque), void *opaque)
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
 {
     struct omap_gpmc_cs_file_s *f;
+    assert(iomem);
 
     if (cs < 0 || cs >= 8) {
         fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
@@ -419,12 +845,29 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
     }
     f = &s->cs_file[cs];
 
+    omap_gpmc_cs_unmap(s, cs);
+    f->config[0] &= ~(0xf << 10);
     f->iomem = iomem;
-    f->base_update = base_upd;
-    f->unmap = unmap;
-    f->opaque = opaque;
+    omap_gpmc_cs_map(s, cs);
+}
 
-    if (f->config[6] & (1 << 6))                               /* CSVALID */
-        omap_gpmc_cs_map(f, f->config[6] & 0x1f,               /* MASKADDR */
-                        (f->config[6] >> 8 & 0xf));            /* BASEADDR */
+void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand)
+{
+    struct omap_gpmc_cs_file_s *f;
+    assert(nand);
+
+    if (cs < 0 || cs >= 8) {
+        fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
+        exit(-1);
+    }
+    f = &s->cs_file[cs];
+
+    omap_gpmc_cs_unmap(s, cs);
+    f->config[0] &= ~(0xf << 10);
+    f->config[0] |= (OMAP_GPMC_NAND << 10);
+    f->dev = nand;
+    if (nand_getbuswidth(f->dev) == 16) {
+        f->config[0] |= OMAP_GPMC_16BIT << 12;
+    }
+    omap_gpmc_cs_map(s, cs);
 }
index 70364f4c72dc958cc2cdf3d446e88c6449b64d6e..a7b687bc4197490e81af36fd17a140002a6d3325 100644 (file)
@@ -129,8 +129,7 @@ static void sx1_init(ram_addr_t ram_size,
     DriveInfo *dinfo;
     int fl_idx;
     uint32_t flash_size = flash0_size;
-    const MemoryRegionOps *flash_ops;
-    MemoryRegion *flash = g_new(MemoryRegion, 2);
+    int be;
 
     if (version == 2) {
         flash_size = flash2_size;
@@ -156,18 +155,17 @@ static void sx1_init(ram_addr_t ram_size,
 
     fl_idx = 0;
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
 
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
-        memory_region_init_rom_device(&flash[0], flash_ops,
-                                      NULL, "omap_sx1.flash0-1", flash_size);
-        if (!pflash_cfi01_register(OMAP_CS0_BASE, &flash[0],
+        if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL,
+                                   "omap_sx1.flash0-1", flash_size),
                                    dinfo->bdrv, sector_size,
                                    flash_size / sector_size,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
@@ -184,12 +182,11 @@ static void sx1_init(ram_addr_t ram_size,
         cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size,
                         OMAP_CS1_SIZE - flash1_size, io);
 
-        memory_region_init_rom_device(&flash[1], flash_ops,
-                                      NULL, "omap_sx1.flash1-1", flash1_size);
-        if (!pflash_cfi01_register(OMAP_CS1_BASE, &flash[1],
+        if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL,
+                                   "omap_sx1.flash1-1", flash1_size),
                                    dinfo->bdrv, sector_size,
                                    flash1_size / sector_size,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
index 00276a03cbee195b599d7729e008448dc9c8cfaa..6f68f70698b1a057f3eb0349e54a94713e97d3b0 100644 (file)
@@ -25,6 +25,7 @@
 #include "blockdev.h"
 #include "memory.h"
 #include "exec-memory.h"
+#include "sysbus.h"
 
 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
 #define PAGE_SHIFT     11
@@ -33,6 +34,7 @@
 #define BLOCK_SHIFT    (PAGE_SHIFT + 6)
 
 typedef struct {
+    SysBusDevice busdev;
     struct {
         uint16_t man;
         uint16_t dev;
@@ -49,6 +51,7 @@ typedef struct {
     uint8_t *current;
     MemoryRegion ram;
     MemoryRegion mapped_ram;
+    uint8_t current_direction;
     uint8_t *boot[2];
     uint8_t *data[2][2];
     MemoryRegion iomem;
@@ -120,27 +123,72 @@ static void onenand_mem_setup(OneNANDState *s)
                                         1);
 }
 
-void onenand_base_update(void *opaque, target_phys_addr_t new)
+static void onenand_intr_update(OneNANDState *s)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    s->base = new;
-
-    memory_region_add_subregion(get_system_memory(), s->base, &s->container);
+    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
 }
 
-void onenand_base_unmap(void *opaque)
+static void onenand_pre_save(void *opaque)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    memory_region_del_subregion(get_system_memory(), &s->container);
+    OneNANDState *s = opaque;
+    if (s->current == s->otp) {
+        s->current_direction = 1;
+    } else if (s->current == s->image) {
+        s->current_direction = 2;
+    } else {
+        s->current_direction = 0;
+    }
 }
 
-static void onenand_intr_update(OneNANDState *s)
+static int onenand_post_load(void *opaque, int version_id)
 {
-    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
+    OneNANDState *s = opaque;
+    switch (s->current_direction) {
+    case 0:
+        break;
+    case 1:
+        s->current = s->otp;
+        break;
+    case 2:
+        s->current = s->image;
+        break;
+    default:
+        return -1;
+    }
+    onenand_intr_update(s);
+    return 0;
 }
 
+static const VMStateDescription vmstate_onenand = {
+    .name = "onenand",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .pre_save = onenand_pre_save,
+    .post_load = onenand_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(current_direction, OneNANDState),
+        VMSTATE_INT32(cycle, OneNANDState),
+        VMSTATE_INT32(otpmode, OneNANDState),
+        VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8),
+        VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8),
+        VMSTATE_INT32(bufaddr, OneNANDState),
+        VMSTATE_INT32(count, OneNANDState),
+        VMSTATE_UINT16(command, OneNANDState),
+        VMSTATE_UINT16_ARRAY(config, OneNANDState, 2),
+        VMSTATE_UINT16(status, OneNANDState),
+        VMSTATE_UINT16(intstatus, OneNANDState),
+        VMSTATE_UINT16(wpstatus, OneNANDState),
+        VMSTATE_INT32(secs_cur, OneNANDState),
+        VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks),
+        VMSTATE_UINT8(ecc.cp, OneNANDState),
+        VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
+        VMSTATE_UINT16(ecc.count, OneNANDState),
+        VMSTATE_BUFFER_UNSAFE(otp, OneNANDState, 0, ((64 + 2) << PAGE_SHIFT)),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
 static void onenand_reset(OneNANDState *s, int cold)
 {
@@ -167,11 +215,17 @@ static void onenand_reset(OneNANDState *s, int cold)
         /* Lock the whole flash */
         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
 
-        if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
-            hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__);
+        if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) {
+            hw_error("%s: Loading the BootRAM failed.\n", __func__);
+        }
     }
 }
 
+static void onenand_system_reset(DeviceState *dev)
+{
+    onenand_reset(FROM_SYSBUS(OneNANDState, sysbus_from_qdev(dev)), 1);
+}
+
 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
                 void *dest)
 {
@@ -191,8 +245,8 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
     int result = 0;
 
     if (secn > 0) {
-        uint32_t size = (uint32_t) secn * 512;
-        const uint8_t *sp = (const uint8_t *) src;
+        uint32_t size = (uint32_t)secn * 512;
+        const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0;
         if (s->bdrv_cur) {
             dp = g_malloc(size);
@@ -203,7 +257,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
             if (sec + secn > s->secs_cur) {
                 result = 1;
             } else {
-                dp = (uint8_t *) s->current + (sec << 9);
+                dp = (uint8_t *)s->current + (sec << 9);
             }
         }
         if (!result) {
@@ -245,13 +299,13 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
 {
     int result = 0;
     if (secn > 0) {
-        const uint8_t *sp = (const uint8_t *) src;
+        const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0, *dpp = 0;
         if (s->bdrv_cur) {
             dp = g_malloc(512);
             if (!dp || bdrv_read(s->bdrv_cur,
-                                s->secs_cur + (sec >> 5),
-                                dp, 1) < 0) {
+                                 s->secs_cur + (sec >> 5),
+                                 dp, 1) < 0) {
                 result = 1;
             } else {
                 dpp = dp + ((sec & 31) << 4);
@@ -270,7 +324,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
             }
             if (s->bdrv_cur) {
                 result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5),
-                                dp, 1) < 0;
+                                    dp, 1) < 0;
             }
         }
         if (dp) {
@@ -326,7 +380,7 @@ fail:
     return 1;
 }
 
-static void onenand_command(OneNANDState *s, int cmd)
+static void onenand_command(OneNANDState *s)
 {
     int b;
     int sec;
@@ -346,7 +400,7 @@ static void onenand_command(OneNANDState *s, int cmd)
             s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1];    \
     buf += (s->bufaddr & 3) << 4;
 
-    switch (cmd) {
+    switch (s->command) {
     case 0x00: /* Load single/multiple sector data unit into buffer */
         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 
@@ -527,7 +581,7 @@ static void onenand_command(OneNANDState *s, int cmd)
         s->status |= ONEN_ERR_CMD;
         s->intstatus |= ONEN_INT;
         fprintf(stderr, "%s: unknown OneNAND command %x\n",
-                        __FUNCTION__, cmd);
+                        __func__, s->command);
     }
 
     onenand_intr_update(s);
@@ -659,7 +713,7 @@ static void onenand_write(void *opaque, target_phys_addr_t addr,
         if (s->intstatus & (1 << 15))
             break;
         s->command = value;
-        onenand_command(s, s->command);
+        onenand_command(s);
         break;
     case 0xf221:       /* System Configuration 1 */
         s->config[0] = value;
@@ -700,30 +754,25 @@ static const MemoryRegionOps onenand_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-void *onenand_init(BlockDriverState *bdrv,
-                uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
-                int regshift, qemu_irq irq)
+static int onenand_initfn(SysBusDevice *dev)
 {
-    OneNANDState *s = (OneNANDState *) g_malloc0(sizeof(*s));
-    uint32_t size = 1 << (24 + ((dev_id >> 4) & 7));
+    OneNANDState *s = (OneNANDState *)dev;
+    uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
     void *ram;
-
-    s->shift = regshift;
-    s->intr = irq;
+    s->base = (target_phys_addr_t)-1;
     s->rdy = NULL;
-    s->id.man = man_id;
-    s->id.dev = dev_id;
-    s->id.ver = ver_id;
     s->blocks = size >> BLOCK_SHIFT;
     s->secs = size >> 9;
     s->blockwp = g_malloc(s->blocks);
-    s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0;
+    s->density_mask = (s->id.dev & 0x08)
+        ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
     memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand",
                           0x10000 << s->shift);
-    s->bdrv = bdrv;
     if (!s->bdrv) {
         s->image = memset(g_malloc(size + (size >> 5)),
-                        0xff, size + (size >> 5));
+                          0xff, size + (size >> 5));
+    } else {
+        s->bdrv_cur = s->bdrv;
     }
     s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
                     0xff, (64 + 2) << PAGE_SHIFT);
@@ -736,15 +785,40 @@ void *onenand_init(BlockDriverState *bdrv,
     s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
     s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
     onenand_mem_setup(s);
+    sysbus_init_irq(dev, &s->intr);
+    sysbus_init_mmio_region(dev, &s->container);
+    vmstate_register(&dev->qdev,
+                     ((s->shift & 0x7f) << 24)
+                     | ((s->id.man & 0xff) << 16)
+                     | ((s->id.dev & 0xff) << 8)
+                     | (s->id.ver & 0xff),
+                     &vmstate_onenand, s);
+    return 0;
+}
 
-    onenand_reset(s, 1);
+static SysBusDeviceInfo onenand_info = {
+    .init = onenand_initfn,
+    .qdev.name = "onenand",
+    .qdev.size = sizeof(OneNANDState),
+    .qdev.reset = onenand_system_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
+        DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
+        DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
+        DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
+        DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
+        DEFINE_PROP_END_OF_LIST()
+    }
+};
 
-    return s;
+static void onenand_register_device(void)
+{
+    sysbus_register_withprop(&onenand_info);
 }
 
-void *onenand_raw_otp(void *opaque)
+void *onenand_raw_otp(DeviceState *onenand_device)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    return s->otp;
+    return FROM_SYSBUS(OneNANDState, sysbus_from_qdev(onenand_device))->otp;
 }
+
+device_init(onenand_register_device)
diff --git a/hw/pc.c b/hw/pc.c
index 263fb1a77356440b1661c0a07de2f194b1752716..5bc845aaea61f2d94afadf23ebadef3a0796227f 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -78,12 +78,12 @@ struct e820_entry {
     uint64_t address;
     uint64_t length;
     uint32_t type;
-} __attribute((__packed__, __aligned__(4)));
+} QEMU_PACKED __attribute((__aligned__(4)));
 
 struct e820_table {
     uint32_t count;
     struct e820_entry entry[E820_NR_ENTRIES];
-} __attribute((__packed__, __aligned__(4)));
+} QEMU_PACKED __attribute((__aligned__(4)));
 
 static struct e820_table e820_table;
 struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
index c5a0aa89794fe7886650677383865d9e22466b09..1fb105d51c9f6c737ab3c7ce313eaa06af54555e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * PCI stubs for plathome that doesn't support pci bus.
+ * PCI stubs for platforms that don't support pci bus.
  *
  * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
  *                    VA Linux Systems Japan K.K.
index 6124790f010c187023a29768da9c046ecbfeb18e..57ff7b1098a42d0eb485c642537f09c103d345e9 100644 (file)
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1811,6 +1811,25 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
     return next;
 }
 
+static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset)
+{
+    uint8_t next, prev, found = 0;
+
+    if (!(pdev->used[offset])) {
+        return 0;
+    }
+
+    assert(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST);
+
+    for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
+         prev = next + PCI_CAP_LIST_NEXT) {
+        if (next <= offset && next > found) {
+            found = next;
+        }
+    }
+    return found;
+}
+
 /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
    This is needed for an option rom which is used for more than one device. */
 static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
@@ -1952,11 +1971,30 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
                        uint8_t offset, uint8_t size)
 {
     uint8_t *config;
+    int i, overlapping_cap;
+
     if (!offset) {
         offset = pci_find_space(pdev, size);
         if (!offset) {
             return -ENOSPC;
         }
+    } else {
+        /* Verify that capabilities don't overlap.  Note: device assignment
+         * depends on this check to verify that the device is not broken.
+         * Should never trigger for emulated devices, but it's helpful
+         * for debugging these. */
+        for (i = offset; i < offset + size; i++) {
+            overlapping_cap = pci_find_capability_at_offset(pdev, i);
+            if (overlapping_cap) {
+                fprintf(stderr, "ERROR: %04x:%02x:%02x.%x "
+                        "Attempt to add PCI capability %x at offset "
+                        "%x overlaps existing capability %x at offset %x\n",
+                        pci_find_domain(pdev->bus), pci_bus_num(pdev->bus),
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+                        cap_id, offset, overlapping_cap, i);
+                return -EINVAL;
+            }
+        }
     }
 
     config = pdev->config + offset;
index 44c6c207a9fc1ebd23f3de795efe8fbec0bd38f5..2e8a29f1e3d3aa4d6c30a2a11db361b272f62a46 100644 (file)
@@ -94,72 +94,82 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
     return val;
 }
 
-static void pci_host_config_write(void *opaque, target_phys_addr_t addr,
-                                  uint64_t val, unsigned len)
+static void pci_host_config_write(ReadWriteHandler *handler,
+                                  pcibus_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",
+    PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n",
                 __func__, addr, len, val);
     s->config_reg = val;
 }
 
-static uint64_t pci_host_config_read(void *opaque, target_phys_addr_t addr,
-                                     unsigned len)
+static uint32_t pci_host_config_read(ReadWriteHandler *handler,
+                                     pcibus_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
     uint32_t val = s->config_reg;
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx32"\n",
+    PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n",
                 __func__, addr, len, val);
     return val;
 }
 
-static void pci_host_data_write(void *opaque, target_phys_addr_t addr,
-                                uint64_t val, unsigned len)
+static void pci_host_data_write(ReadWriteHandler *handler,
+                                pcibus_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
-    PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
-                addr, len, (unsigned)val);
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
+    PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n",
+                addr, len, val);
     if (s->config_reg & (1u << 31))
         pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
 }
 
-static uint64_t pci_host_data_read(void *opaque,
-                                   target_phys_addr_t addr, unsigned len)
+static uint32_t pci_host_data_read(ReadWriteHandler *handler,
+                                   pcibus_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
     uint32_t val;
     if (!(s->config_reg & (1 << 31)))
         return 0xffffffff;
     val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
-    PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n",
+    PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n",
                 addr, len, val);
     return val;
 }
 
-const MemoryRegionOps pci_host_conf_le_ops = {
-    .read = pci_host_config_read,
-    .write = pci_host_config_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-const MemoryRegionOps pci_host_conf_be_ops = {
-    .read = pci_host_config_read,
-    .write = pci_host_config_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
+static void pci_host_init(PCIHostState *s)
+{
+    s->conf_handler.write = pci_host_config_write;
+    s->conf_handler.read = pci_host_config_read;
+    s->data_handler.write = pci_host_data_write;
+    s->data_handler.read = pci_host_data_read;
+}
 
-const MemoryRegionOps pci_host_data_le_ops = {
-    .read = pci_host_data_read,
-    .write = pci_host_data_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
+int pci_host_conf_register_mmio(PCIHostState *s, int endian)
+{
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->conf_handler, endian);
+}
 
-const MemoryRegionOps pci_host_data_be_ops = {
-    .read = pci_host_data_read,
-    .write = pci_host_data_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s)
+{
+    pci_host_init(s);
+    register_ioport_simple(&s->conf_handler, ioport, 4, 4);
+    sysbus_init_ioports(&s->busdev, ioport, 4);
+}
 
+int pci_host_data_register_mmio(PCIHostState *s, int endian)
+{
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->data_handler, endian);
+}
 
+void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s)
+{
+    pci_host_init(s);
+    register_ioport_simple(&s->data_handler, ioport, 4, 1);
+    register_ioport_simple(&s->data_handler, ioport, 4, 2);
+    register_ioport_simple(&s->data_handler, ioport, 4, 4);
+    sysbus_init_ioports(&s->busdev, ioport, 4);
+}
index 0211086d70741120665b033e5651d8001c861c12..7f551143bb273e32210be23857d75c6ae3f94c8c 100644 (file)
 #define PCI_HOST_H
 
 #include "sysbus.h"
+#include "rwhandler.h"
 
 struct PCIHostState {
     SysBusDevice busdev;
-    MemoryRegion conf_mem;
-    MemoryRegion data_mem;
+    ReadWriteHandler conf_handler;
+    ReadWriteHandler data_handler;
     MemoryRegion *address_space;
     uint32_t config_reg;
     PCIBus *bus;
@@ -48,9 +49,12 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
 
-extern const MemoryRegionOps pci_host_conf_le_ops;
-extern const MemoryRegionOps pci_host_conf_be_ops;
-extern const MemoryRegionOps pci_host_data_le_ops;
-extern const MemoryRegionOps pci_host_data_be_ops;
+/* for mmio */
+int pci_host_conf_register_mmio(PCIHostState *s, int endian);
+int pci_host_data_register_mmio(PCIHostState *s, int endian);
+
+/* for ioio */
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s);
+void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s);
 
 #endif /* PCI_HOST_H */
index 39607bf31a8ce0ffa8e45eb6ecf424d4025953f9..5c9eb2f0ac305f9ae678e89ad70490d5ca43db05 100644 (file)
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -175,6 +175,14 @@ static void hotplug_event_notify(PCIDevice *dev)
     }
 }
 
+static void hotplug_event_clear(PCIDevice *dev)
+{
+    hotplug_event_update_event_status(dev);
+    if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) {
+        qemu_set_irq(dev->irq[dev->exp.hpev_intx], 0);
+    }
+}
+
 /*
  * A PCI Express Hot-Plug Event has occurred, so update slot status register
  * and notify OS of the event if necessary.
@@ -320,6 +328,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
     uint8_t *exp_cap = dev->config + pos;
     uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
 
+    if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) {
+        hotplug_event_clear(dev);
+    }
+
     if (!ranges_overlap(addr, len, pos + PCI_EXP_SLTCTL, 2)) {
         return;
     }
index 2ae65ec80701cd42688aea4954a5db43ca36d8cc..62c06eafd62663d8f4f568bac1624aedb996c51e 100644 (file)
@@ -415,7 +415,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
     int i;
 
     assert(err->status);
-    assert(err->status & (err->status - 1));
+    assert(!(err->status & (err->status - 1)));
 
     errcap &= ~(PCI_ERR_CAP_FEP_MASK | PCI_ERR_CAP_TLP);
     errcap |= PCI_ERR_CAP_FEP(first_bit);
@@ -495,7 +495,7 @@ static int pcie_aer_record_error(PCIDevice *dev,
     int fep = PCI_ERR_CAP_FEP(errcap);
 
     assert(err->status);
-    assert(err->status & (err->status - 1));
+    assert(!(err->status & (err->status - 1)));
 
     if (errcap & PCI_ERR_CAP_MHRE &&
         (pci_get_long(aer_cap + PCI_ERR_UNCOR_STATUS) & (1U << fep))) {
@@ -979,20 +979,21 @@ int do_pcie_aer_inejct_error(Monitor *mon,
     if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) {
         char *e = NULL;
         error_status = strtoul(error_name, &e, 0);
-        correctable = !!qdict_get_int(qdict, "correctable");
+        correctable = qdict_get_try_bool(qdict, "correctable", 0);
         if (!e || *e != '\0') {
             monitor_printf(mon, "invalid error status value. \"%s\"",
                            error_name);
             return -EINVAL;
         }
     }
+    err.status = error_status;
     err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn;
 
     err.flags = 0;
     if (correctable) {
         err.flags |= PCIE_AER_ERR_IS_CORRECTABLE;
     }
-    if (qdict_get_int(qdict, "advisory_non_fatal")) {
+    if (qdict_get_try_bool(qdict, "advisory_non_fatal", 0)) {
         err.flags |= PCIE_AER_ERR_MAYBE_ADVISORY;
     }
     if (qdict_haskey(qdict, "header0")) {
index 257fccaa88d06d7a88bc299a907ecf6afe8ad8d4..e3ca310efdf94c253378bdd36848e6f092cbb913 100644 (file)
@@ -149,7 +149,7 @@ petalogix_ml605_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = MEMORY_BASEADDR;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -169,15 +169,14 @@ petalogix_ml605_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_le,
-                                  NULL, "petalogix_ml605.flash", FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "petalogix_ml605.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* 5th parameter 2 means bank-width
      * 10th paremeter 0 means little-endian */
     pflash_cfi01_register(FLASH_BASEADDR, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          2, 0x89, 0x18, 0x0000, 0x0);
+                          2, 0x89, 0x18, 0x0000, 0x0, 0);
 
 
     cpu_irq = microblaze_pic_init_cpu(env);
index 14817452c60005c99dc99c75d7cee3aa7dcd54b2..a43fb4c95c9fc9529f9e9f9be4b5f1327d9c43b6 100644 (file)
@@ -127,7 +127,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = 0x90000000;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -148,14 +148,12 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "petalogix_s3adsp1800.flash",
-                                  FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xa0000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0);
+                          1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     cpu_irq = microblaze_pic_init_cpu(env);
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 2);
index 2144c6a3fd3a92ed361674889080fad14ddb00a1..90e1301c5e147a84962d36dda5c8ace12d89b0c0 100644 (file)
@@ -40,7 +40,6 @@
 #include "flash.h"
 #include "block.h"
 #include "qemu-timer.h"
-#include "exec-memory.h"
 
 #define PFLASH_BUG(fmt, ...) \
 do { \
@@ -75,7 +74,8 @@ struct pflash_t {
     target_phys_addr_t counter;
     unsigned int writeblock_size;
     QEMUTimer *timer;
-    MemoryRegion *mem;
+    ram_addr_t off;
+    int fl_mem;
     void *storage;
 };
 
@@ -89,7 +89,8 @@ static void pflash_timer (void *opaque)
     if (pfl->bypass) {
         pfl->wcycle = 2;
     } else {
-        memory_region_rom_device_set_readable(pfl->mem, true);
+        cpu_register_physical_memory(pfl->base, pfl->total_len,
+                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
         pfl->wcycle = 0;
     }
     pfl->cmd = 0;
@@ -262,7 +263,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
 
     if (!pfl->wcycle) {
         /* Set the device in I/O access mode */
-        memory_region_rom_device_set_readable(pfl->mem, false);
+        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
     }
 
     switch (pfl->wcycle) {
@@ -421,7 +422,8 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
            __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  reset_flash:
-    memory_region_rom_device_set_readable(pfl->mem, true);
+    cpu_register_physical_memory(pfl->base, pfl->total_len,
+                    pfl->off | IO_MEM_ROMD | pfl->fl_mem);
 
     pfl->bypass = 0;
     pfl->wcycle = 0;
@@ -512,20 +514,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-const MemoryRegionOps pflash_cfi01_ops_be = {
-    .old_mmio = {
-        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
-        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
+    &pflash_writeb_be,
+    &pflash_writew_be,
+    &pflash_writel_be,
 };
 
-const MemoryRegionOps pflash_cfi01_ops_le = {
-    .old_mmio = {
-        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
-        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
+    &pflash_readb_be,
+    &pflash_readw_be,
+    &pflash_readl_be,
+};
+
+static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
+    &pflash_writeb_le,
+    &pflash_writew_le,
+    &pflash_writel_le,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
+    &pflash_readb_le,
+    &pflash_readw_le,
+    &pflash_readl_le,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -564,11 +574,12 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3)
+                                uint16_t id2, uint16_t id3,
+                                int be)
 {
     pflash_t *pfl;
     target_phys_addr_t total_len;
@@ -586,16 +597,26 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
     pfl = g_malloc0(sizeof(pflash_t));
 
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = memory_region_get_ram_ptr(mem);
-    pfl->mem = mem;
-    memory_region_add_subregion(get_system_memory(), base, mem);
+    pfl->storage = qemu_get_ram_ptr(off);
+    if (be) {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
+                                             pflash_write_ops_be, pfl,
+                                             DEVICE_NATIVE_ENDIAN);
+    } else {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
+                                             pflash_write_ops_le, pfl,
+                                             DEVICE_NATIVE_ENDIAN);
+    }
+    pfl->off = off;
+    cpu_register_physical_memory(base, total_len,
+                    off | pfl->fl_mem | IO_MEM_ROMD);
 
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
         if (ret < 0) {
-            memory_region_del_subregion(get_system_memory(), mem);
+            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
index e7e0408fc4b9f698bf29104936a554d40b4cb3ab..ac5115e4c83aa63f5443f939ab9884306b75db09 100644 (file)
@@ -39,7 +39,6 @@
 #include "flash.h"
 #include "qemu-timer.h"
 #include "block.h"
-#include "exec-memory.h"
 
 //#define PFLASH_DEBUG
 #ifdef PFLASH_DEBUG
@@ -70,39 +69,25 @@ struct pflash_t {
     uint8_t cfi_len;
     uint8_t cfi_table[0x52];
     QEMUTimer *timer;
-    /* The device replicates the flash memory across its memory space.  Emulate
-     * that by having a container (.mem) filled with an array of aliases
-     * (.mem_mappings) pointing to the flash memory (.orig_mem).
-     */
-    MemoryRegion mem;
-    MemoryRegion *mem_mappings;    /* array; one per mapping */
-    MemoryRegion *orig_mem;
+    ram_addr_t off;
+    int fl_mem;
     int rom_mode;
     int read_counter; /* used for lazy switch-back to rom mode */
     void *storage;
 };
 
-/*
- * Set up replicated mappings of the same region.
- */
-static void pflash_setup_mappings(pflash_t *pfl, MemoryRegion *mem)
-{
-    unsigned i;
-    target_phys_addr_t size = memory_region_size(mem);
-
-    pfl->orig_mem = mem;
-    memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
-    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
-    for (i = 0; i < pfl->mappings; ++i) {
-        memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias", mem,
-                                 0, size);
-        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
-    }
-}
-
 static void pflash_register_memory(pflash_t *pfl, int rom_mode)
 {
-    memory_region_rom_device_set_readable(pfl->orig_mem, rom_mode);
+    unsigned long phys_offset = pfl->fl_mem;
+    int i;
+
+    if (rom_mode)
+        phys_offset |= pfl->off | IO_MEM_ROMD;
+    pfl->rom_mode = rom_mode;
+
+    for (i = 0; i < pfl->mappings; i++)
+        cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
+                                     pfl->chip_len, phys_offset);
 }
 
 static void pflash_timer (void *opaque)
@@ -553,20 +538,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-const MemoryRegionOps pflash_cfi02_ops_be = {
-    .old_mmio = {
-        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
-        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
+    &pflash_writeb_be,
+    &pflash_writew_be,
+    &pflash_writel_be,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
+    &pflash_readb_be,
+    &pflash_readw_be,
+    &pflash_readl_be,
 };
 
-const MemoryRegionOps pflash_cfi02_ops_le = {
-    .old_mmio = {
-        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
-        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
+    &pflash_writeb_le,
+    &pflash_writew_le,
+    &pflash_writel_le,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
+    &pflash_readb_le,
+    &pflash_readw_le,
+    &pflash_readl_le,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -605,12 +598,13 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1)
+                                uint16_t unlock_addr0, uint16_t unlock_addr1,
+                                int be)
 {
     pflash_t *pfl;
     int32_t chip_len;
@@ -625,22 +619,31 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
 #endif
     pfl = g_malloc0(sizeof(pflash_t));
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = memory_region_get_ram_ptr(mem);
+    pfl->storage = qemu_get_ram_ptr(off);
+    if (be) {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
+                                             pflash_write_ops_be,
+                                             pfl, DEVICE_NATIVE_ENDIAN);
+    } else {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
+                                             pflash_write_ops_le,
+                                             pfl, DEVICE_NATIVE_ENDIAN);
+    }
+    pfl->off = off;
     pfl->base = base;
     pfl->chip_len = chip_len;
     pfl->mappings = nb_mappings;
+    pflash_register_memory(pfl, 1);
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
+            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
     }
-    pflash_setup_mappings(pfl, mem);
-    pfl->rom_mode = 1;
-    memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem);
 #if 0 /* XXX: there should be a bit to set up read-only,
        *      the same way the hardware does (with WP pin).
        */
index 8f6ea42e2cb2270d2f7e4026a1af7e6a17578e75..c563c6e1a315abb6b42f4ec62f5087578214c6f3 100644 (file)
@@ -142,7 +142,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
     int i, r;
     uint32_t smram;
 
-    memory_region_transaction_begin();
     update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
                &d->pam_regions[0]);
     for(i = 0; i < 12; i++) {
@@ -163,7 +162,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
             d->smram_enabled = false;
         }
     }
-    memory_region_transaction_commit();
 }
 
 static void i440fx_set_smm(int val, void *arg)
@@ -237,16 +235,9 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev)
 {
     I440FXState *s = FROM_SYSBUS(I440FXState, dev);
 
-    memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
-                          "pci-conf-idx", 4);
-    sysbus_add_io(dev, 0xcf8, &s->conf_mem);
-    sysbus_init_ioports(&s->busdev, 0xcf8, 4);
-
-    memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s,
-                          "pci-conf-data", 4);
-    sysbus_add_io(dev, 0xcfc, &s->data_mem);
-    sysbus_init_ioports(&s->busdev, 0xcfc, 4);
+    pci_host_conf_register_ioport(0xcf8, s);
 
+    pci_host_data_register_ioport(0xcfc, s);
     return 0;
 }
 
index 1eb807c4c1b9b5838b2434da4aac38c2a8e82781..dec165e40fc0dd8a1d776a9576d3df77d409271f 100644 (file)
@@ -32,7 +32,6 @@
 #include "qemu-log.h"
 #include "loader.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define BIOS_FILENAME "ppc405_rom.bin"
 #define BIOS_SIZE (2048 * 1024)
@@ -182,9 +181,7 @@ static void ref405ep_init (ram_addr_t ram_size,
     ppc4xx_bd_info_t bd;
     CPUPPCState *env;
     qemu_irq *pic;
-    ram_addr_t sram_offset, bdloc;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    ram_addr_t sram_offset, bios_offset, bdloc;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size;
@@ -227,18 +224,18 @@ static void ref405ep_init (ram_addr_t ram_size,
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
         bios_size = bdrv_getlength(dinfo->bdrv);
-        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
-                                      NULL, "ef405ep.bios", bios_size);
+        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr %lx '%s' %d\n",
-               fl_idx, bios_size, -bios_size,
+               " at offset %08lx addr %lx '%s' %d\n",
+               fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     } else
 #endif
@@ -246,12 +243,12 @@ static void ref405ep_init (ram_addr_t ram_size,
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE);
+        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE);
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
+            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -262,9 +259,8 @@ static void ref405ep_init (ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem, (uint32_t)(-bios_size),
-                                    bios);
+        cpu_register_physical_memory((uint32_t)(-bios_size),
+                                     bios_size, bios_offset | IO_MEM_ROM);
     }
     /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -511,9 +507,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 {
     char *filename;
     qemu_irq *pic;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     long bios_size;
@@ -550,17 +544,17 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
-        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
-                                      NULL, "taihu_405ep.bios", bios_size);
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size);
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr %lx '%s' %d\n",
-               fl_idx, bios_size, -bios_size,
+               " at offset %08lx addr %lx '%s' %d\n",
+               fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     } else
 #endif
@@ -570,10 +564,10 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 #endif
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
-        memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE);
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE);
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
+            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -584,9 +578,8 @@ static void taihu_405ep_init(ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem,
-                                    (uint32_t)(-bios_size), bios);
+        cpu_register_physical_memory((uint32_t)(-bios_size),
+                                     bios_size, bios_offset | IO_MEM_ROM);
     }
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@@ -597,15 +590,15 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr " TARGET_FMT_lx " '%s'\n",
-               fl_idx, bios_size, (target_ulong)0xfc000000,
+               " at offset %08lx  addr " TARGET_FMT_lx " '%s'\n",
+               fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
                bdrv_get_device_name(dinfo->bdrv));
 #endif
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
-                                      NULL, "taihu_405ep.flash", bios_size);
-        pflash_cfi02_register(0xfc000000, flash,
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size);
+        pflash_cfi02_register(0xfc000000, bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     }
     /* Register CLPD & LCD display */
index 339b38ec7ab793c1f3df3faddfbd42fc566680f8..52e2663a01c7aa65dc4215b85ed4cdaad2d0ddc5 100644 (file)
@@ -368,12 +368,10 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index);
 
     /* CFGDATA */
-    memory_region_init_io(&controller->pci_state.data_mem,
-                          &pci_host_data_be_ops,
-                          &controller->pci_state, "pci-conf-data", 4);
-    memory_region_add_subregion(get_system_memory(),
-                                config_space + PCIC0_CFGDATA,
-                                &controller->pci_state.data_mem);
+    index = pci_host_data_register_mmio(&controller->pci_state, 1);
+    if (index < 0)
+        goto free;
+    cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index);
 
     /* Internal registers */
     index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller,
index 2db365d0b67c88eba873890607be150ca4d0bd55..4390aeb5594f976560684c0f48d4040df9bd843e 100644 (file)
@@ -79,6 +79,8 @@ struct PPCE500PCIState {
     uint32_t gasket_time;
     qemu_irq irq[4];
     /* mmio maps */
+    int cfgaddr;
+    int cfgdata;
     int reg;
 };
 
@@ -266,18 +268,18 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
     PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h);
 
-    sysbus_add_memory(dev, base + PCIE500_CFGADDR, &h->conf_mem);
-    sysbus_add_memory(dev, base + PCIE500_CFGDATA, &h->data_mem);
+    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, s->cfgaddr);
+    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, s->cfgdata);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  s->reg);
 }
 
 static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
 {
-    PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
-
-    sysbus_del_memory(dev, &h->conf_mem);
-    sysbus_del_memory(dev, &h->data_mem);
+    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4,
+                                 IO_MEM_UNASSIGNED);
+    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4,
+                                 IO_MEM_UNASSIGNED);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  IO_MEM_UNASSIGNED);
 }
@@ -307,10 +309,9 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
 
     pci_create_simple(b, 0, "e500-host-bridge");
 
-    memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h,
-                          "pci-conf-idx", 4);
-    memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h,
-                          "pci-conf-data", 4);
+    s->cfgaddr = pci_host_conf_register_mmio(&s->pci_state, DEVICE_BIG_ENDIAN);
+    s->cfgdata = pci_host_data_register_mmio(&s->pci_state,
+                                             DEVICE_LITTLE_ENDIAN);
     s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
                                     DEVICE_BIG_ENDIAN);
     sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap);
index 55e4e2509940a92825099b10df6cd7c64b975f09..c36232a808d1cfb4b7fcf3fc58e0729ed56a871a 100644 (file)
@@ -125,15 +125,9 @@ PCIBus *pci_prep_init(qemu_irq *pic,
                               address_space_io,
                               0, 4);
 
-    memory_region_init_io(&s->conf_mem, &pci_host_conf_be_ops, s,
-                          "pci-conf-idx", 1);
-    memory_region_add_subregion(address_space_io, 0xcf8, &s->conf_mem);
-    sysbus_init_ioports(&s->busdev, 0xcf8, 1);
-
-    memory_region_init_io(&s->conf_mem, &pci_host_data_be_ops, s,
-                          "pci-conf-data", 1);
-    memory_region_add_subregion(address_space_io, 0xcfc, &s->data_mem);
-    sysbus_init_ioports(&s->busdev, 0xcfc, 1);
+    pci_host_conf_register_ioport(0xcf8, s);
+
+    pci_host_data_register_ioport(0xcfc, s);
 
     PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read,
                                            PPC_PCIIO_write, s,
index 97f90153b79474a86fb27ba1a1902e13bf2aee08..b73290cb3f7ad8df4930cdf32ac17685824d4481 100644 (file)
@@ -70,7 +70,7 @@ struct PXA2xxLCDState {
     int orientation;
 };
 
-typedef struct __attribute__ ((__packed__)) {
+typedef struct QEMU_PACKED {
     uint32_t fdaddr;
     uint32_t fsaddr;
     uint32_t fidr;
index 1d9077db68bf50525207f295c1e774664514e051..45e24016fc65c76d644f7a5b7ae9ac4bd2dfc226 100644 (file)
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1388,11 +1388,7 @@ static void init_pipe_signaling(PCIQXLDevice *d)
        dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
        return;
    }
-#ifdef CONFIG_IOTHREAD
    fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
-#else
-   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
-#endif
    fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
    fcntl(d->pipe[0], F_SETOWN, getpid());
 
index 41aa2c2bd2059c3f6e43e84953924295bd154b60..771f3d0733a0e85302e25ed398b779745cc6fcfd 100644 (file)
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -209,7 +209,7 @@ static void main_cpu_reset(void *opaque)
     env->pc = s->vector;
 }
 
-static struct __attribute__((__packed__))
+static struct QEMU_PACKED
 {
     int mount_root_rdonly;
     int ramdisk_flags;
@@ -235,7 +235,6 @@ static void r2d_init(ram_addr_t ram_size,
     qemu_irq *irq;
     DriveInfo *dinfo;
     int i;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -268,13 +267,11 @@ static void r2d_init(ram_addr_t ram_size,
 
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
-                                  NULL, "r2d.flash", FLASH_SIZE);
-    pflash_cfi02_register(0x0, flash,
+    pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE),
                           dinfo ? dinfo->bdrv : NULL, (16 * 1024),
                           FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
-                          0x555, 0x2aa);
+                          0x555, 0x2aa, 0);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
index a2a20996a23d0de8f9c03fe082fcadb46db8d099..33e10709c6f3433e096c65850ee21c02afaa48c8 100644 (file)
@@ -50,7 +50,7 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } whi
 typedef struct dma_pagetable_entry {
     int32_t frame;
     int32_t owner;
-} __attribute__((packed)) dma_pagetable_entry;
+} QEMU_PACKED dma_pagetable_entry;
 
 #define DMA_PAGESIZE    4096
 #define DMA_REG_ENABLE  1
index d94b1eb53c50d9f4fbc3aa45fd6f34c9dfc2e74a..3cc830ff95a7f204f2af0193eae07e9778a48a34 100644 (file)
@@ -57,6 +57,7 @@ typedef struct SCSIDiskReq {
     struct iovec iov;
     QEMUIOVector qiov;
     uint32_t status;
+    BlockAcctCookie acct;
 } SCSIDiskReq;
 
 struct SCSIDiskState
@@ -107,10 +108,13 @@ static void scsi_cancel_io(SCSIRequest *req)
 static void scsi_read_complete(void * opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     int n;
 
     r->req.aiocb = NULL;
 
+    bdrv_acct_done(s->bs, &r->acct);
+
     if (ret) {
         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
             return;
@@ -161,6 +165,8 @@ static void scsi_read_data(SCSIRequest *req)
 
     r->iov.iov_len = n * 512;
     qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+
+    bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
     r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
                               scsi_read_complete, r);
     if (r->req.aiocb == NULL) {
@@ -207,11 +213,14 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
 static void scsi_write_complete(void * opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     uint32_t len;
     uint32_t n;
 
     r->req.aiocb = NULL;
 
+    bdrv_acct_done(s->bs, &r->acct);
+
     if (ret) {
         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
             return;
@@ -252,6 +261,8 @@ static void scsi_write_data(SCSIRequest *req)
     n = r->iov.iov_len / 512;
     if (n) {
         qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+
+        bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
         r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
                                    scsi_write_complete, r);
         if (r->req.aiocb == NULL) {
@@ -854,13 +865,19 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
         buflen = 8;
         break;
     case SYNCHRONIZE_CACHE:
+    {
+        BlockAcctCookie acct;
+
+        bdrv_acct_start(s->bs, &acct, 0, BDRV_ACCT_FLUSH);
         ret = bdrv_flush(s->bs);
+        bdrv_acct_done(s->bs, &acct);
         if (ret < 0) {
             if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
                 return -1;
             }
         }
         break;
+    }
     case GET_CONFIGURATION:
         memset(outbuf, 0, 8);
         /* ??? This should probably return much more information.  For now
index 76061bb7563f3bd742d9c2b70a1cf66469fa9eed..36f39300d580f03a98301b424348061b8f847717 100644 (file)
@@ -150,7 +150,7 @@ static int sh_pci_init_device(SysBusDevice *dev)
                               PCI_DEVFN(0, 0), 4);
     memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s,
                           "sh_pci", 0x224);
-    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_a7,
+    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_p4,
                              0, 0x224);
     isa_mmio_setup(&s->isa, 0x40000);
     sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap);
index 8f2e9653874e1d91a78850fad757d0bb70653932..c9ba43e8d0596158af476832ccdf4a4fa5edff8a 100644 (file)
 struct smbios_header {
     uint16_t length;
     uint8_t type;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 struct smbios_field {
     struct smbios_header header;
     uint8_t type;
     uint16_t offset;
     uint8_t data[];
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 struct smbios_table {
     struct smbios_header header;
     uint8_t data[];
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 #define SMBIOS_FIELD_ENTRY 0
 #define SMBIOS_TABLE_ENTRY 1
index 3a5169dbd34756b9da03ee33e8a8695da2bba6c9..94e3641f9a6d1260385cf75d38e0cdc72ebdda1e 100644 (file)
@@ -26,7 +26,7 @@ struct smbios_structure_header {
     uint8_t type;
     uint8_t length;
     uint16_t handle;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 0 - BIOS Information */
 struct smbios_type_0 {
@@ -42,7 +42,7 @@ struct smbios_type_0 {
     uint8_t system_bios_minor_release;
     uint8_t embedded_controller_major_release;
     uint8_t embedded_controller_minor_release;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 1 - System Information */
 struct smbios_type_1 {
@@ -55,7 +55,7 @@ struct smbios_type_1 {
     uint8_t wake_up_type;
     uint8_t sku_number_str;
     uint8_t family_str;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 3 - System Enclosure (v2.3) */
 struct smbios_type_3 {
@@ -74,7 +74,7 @@ struct smbios_type_3 {
     uint8_t number_of_power_cords;
     uint8_t contained_element_count;
     // contained elements follow
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 4 - Processor Information (v2.0) */
 struct smbios_type_4 {
@@ -94,7 +94,7 @@ struct smbios_type_4 {
     uint16_t l1_cache_handle;
     uint16_t l2_cache_handle;
     uint16_t l3_cache_handle;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 16 - Physical Memory Array
  *   Associated with one type 17 (Memory Device).
@@ -107,7 +107,7 @@ struct smbios_type_16 {
     uint32_t maximum_capacity;
     uint16_t memory_error_information_handle;
     uint16_t number_of_memory_devices;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 /* SMBIOS type 17 - Memory Device
  *   Associated with one type 19
  */
@@ -124,7 +124,7 @@ struct smbios_type_17 {
     uint8_t bank_locator_str;
     uint8_t memory_type;
     uint16_t type_detail;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 19 - Memory Array Mapped Address */
 struct smbios_type_19 {
@@ -133,7 +133,7 @@ struct smbios_type_19 {
     uint32_t ending_address;
     uint16_t memory_array_handle;
     uint8_t partition_width;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 20 - Memory Device Mapped Address */
 struct smbios_type_20 {
@@ -145,18 +145,18 @@ struct smbios_type_20 {
     uint8_t partition_row_position;
     uint8_t interleave_position;
     uint8_t interleaved_data_depth;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 32 - System Boot Information */
 struct smbios_type_32 {
     struct smbios_structure_header header;
     uint8_t reserved[6];
     uint8_t boot_status;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 127 -- End-of-table */
 struct smbios_type_127 {
     struct smbios_structure_header header;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 #endif /*QEMU_SMBIOS_H */
index afcd135c8f42b71b9394d48585338b2610de07cc..3009bd56ce7bbad1828ffb0e92bd54714c449055 100644 (file)
--- a/hw/srp.h
+++ b/hw/srp.h
@@ -106,7 +106,7 @@ struct srp_indirect_buf {
     struct srp_direct_buf    table_desc;
     uint32_t                 len;
     struct srp_direct_buf    desc_list[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 enum {
     SRP_MULTICHAN_SINGLE = 0,
@@ -141,7 +141,7 @@ struct srp_login_rsp {
     uint16_t   buf_fmt;
     uint8_t    rsp_flags;
     uint8_t    reserved2[25];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct srp_login_rej {
     uint8_t    opcode;
@@ -177,7 +177,7 @@ struct srp_tsk_mgmt {
     uint8_t    reserved1[6];
     uint64_t   tag;
     uint8_t    reserved2[4];
-    uint64_t   lun __attribute__((packed));
+    uint64_t   lun QEMU_PACKED;
     uint8_t    reserved3[2];
     uint8_t    tsk_mgmt_func;
     uint8_t    reserved4;
@@ -198,7 +198,7 @@ struct srp_cmd {
     uint8_t    data_in_desc_cnt;
     uint64_t   tag;
     uint8_t    reserved2[4];
-    uint64_t   lun __attribute__((packed));
+    uint64_t   lun QEMU_PACKED;
     uint8_t    reserved3;
     uint8_t    task_attr;
     uint8_t    reserved4;
@@ -235,6 +235,6 @@ struct srp_rsp {
     uint32_t   sense_data_len;
     uint32_t   resp_data_len;
     uint8_t    data[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #endif /* SCSI_SRP_H */
index 2bf1c235dc657bc8b8ccd8cd0094166d95f6f9ed..9b0db7f5115e86dbe6d5b50f0377607f24f0e6a9 100644 (file)
@@ -15,7 +15,6 @@
 #include "i2c.h"
 #include "net.h"
 #include "boards.h"
-#include "exec-memory.h"
 
 #define GPIO_A 0
 #define GPIO_B 1
@@ -1261,7 +1260,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
         0x40024000, 0x40025000, 0x40026000};
     static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
 
-    MemoryRegion *address_space_mem = get_system_memory();
     qemu_irq *pic;
     DeviceState *gpio_dev[7];
     qemu_irq gpio_in[7][8];
@@ -1276,8 +1274,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 
     flash_size = ((board->dc0 & 0xffff) + 1) << 1;
     sram_size = (board->dc0 >> 18) + 1;
-    pic = armv7m_init(address_space_mem,
-                      flash_size, sram_size, kernel_filename, cpu_model);
+    pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
 
     if (board->dc1 & (1 << 16)) {
         dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
index d5613ffffdce9c38c90a26ec15b6e2caa1cde1b2..f9bd3da20954cb4aebf7376c4a9739a57ecbe09d 100644 (file)
@@ -69,7 +69,7 @@ typedef struct {
     NICState *nic;
     NICConf conf;
     qemu_irq irq;
-    MemoryRegion mmio;
+    int mmio_index;
 } stellaris_enet_state;
 
 static void stellaris_enet_update(stellaris_enet_state *s)
@@ -130,8 +130,7 @@ static int stellaris_enet_can_receive(VLANClientState *nc)
     return (s->np < 31);
 }
 
-static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
-                                    unsigned size)
+static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
     uint32_t val;
@@ -199,7 +198,7 @@ static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
 }
 
 static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
-                                 uint64_t value, unsigned size)
+                        uint32_t value)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
 
@@ -304,12 +303,17 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
     }
 }
 
-static const MemoryRegionOps stellaris_enet_ops = {
-    .read = stellaris_enet_read,
-    .write = stellaris_enet_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const stellaris_enet_readfn[] = {
+   stellaris_enet_read,
+   stellaris_enet_read,
+   stellaris_enet_read
 };
 
+static CPUWriteMemoryFunc * const stellaris_enet_writefn[] = {
+   stellaris_enet_write,
+   stellaris_enet_write,
+   stellaris_enet_write
+};
 static void stellaris_enet_reset(stellaris_enet_state *s)
 {
     s->mdv = 0x80;
@@ -387,7 +391,7 @@ static void stellaris_enet_cleanup(VLANClientState *nc)
 
     unregister_savevm(&s->busdev.qdev, "stellaris_enet", s);
 
-    memory_region_destroy(&s->mmio);
+    cpu_unregister_io_memory(s->mmio_index);
 
     g_free(s);
 }
@@ -404,9 +408,10 @@ static int stellaris_enet_init(SysBusDevice *dev)
 {
     stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev);
 
-    memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet",
-                          0x1000);
-    sysbus_init_mmio_region(dev, &s->mmio);
+    s->mmio_index = cpu_register_io_memory(stellaris_enet_readfn,
+                                           stellaris_enet_writefn, s,
+                                           DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, s->mmio_index);
     sysbus_init_irq(dev, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
index 1b60e4ef59d6f17606e8e765bdc81d7b5e115ea5..32e6ab9bebb7fdcd6e51a6659240898a26d8b8ba 100644 (file)
@@ -261,7 +261,9 @@ void cpu_check_irqs(CPUState *env)
         pil |= 1 << 14;
     }
 
-    if (!pil) {
+    /* The bit corresponding to psrpil is (1<< psrpil), the next bit
+       is (2 << psrpil). */
+    if (pil < (2 << env->psrpil)){
         if (env->interrupt_request & CPU_INTERRUPT_HARD) {
             CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
                            env->interrupt_index);
@@ -293,10 +295,12 @@ void cpu_check_irqs(CPUState *env)
                 break;
             }
         }
-    } else {
+    } else if (env->interrupt_request & CPU_INTERRUPT_HARD) {
         CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
                        "current interrupt %x\n",
                        pil, env->pil_in, env->softint, env->interrupt_index);
+        env->interrupt_index = 0;
+        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
     }
 }
 
index 6e89f065b48c338fa93c1c5822f8a0c22711a505..c365d39d24804186d397cbc78496e04fa4957da2 100644 (file)
@@ -131,6 +131,11 @@ void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
     dev->mmio[n].memory = memory;
 }
 
+MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n)
+{
+    return dev->mmio[n].memory;
+}
+
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 {
     pio_addr_t i;
@@ -256,32 +261,3 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
 
     return strdup(path);
 }
-
-void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem)
-{
-    memory_region_add_subregion(get_system_memory(), addr, mem);
-}
-
-void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
-                               MemoryRegion *mem, unsigned priority)
-{
-    memory_region_add_subregion_overlap(get_system_memory(), addr, mem,
-                                        priority);
-}
-
-void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem)
-{
-    memory_region_del_subregion(get_system_memory(), mem);
-}
-
-void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem)
-{
-    memory_region_add_subregion(get_system_io(), addr, mem);
-}
-
-void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem)
-{
-    memory_region_del_subregion(get_system_io(), mem);
-}
index b3e1f99db513726205f5cf66407534660a3724ac..aa3d3832775c2517aa5c1fbc6f97edb1697066ba 100644 (file)
@@ -50,6 +50,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
 void sysbus_init_mmio_cb2(SysBusDevice *dev,
                           mmio_mapfunc cb, mmio_mapfunc unmap);
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
+MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
@@ -57,14 +58,6 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr);
-void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem);
-void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
-                               MemoryRegion *mem, unsigned priority);
-void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem);
-void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
-                   MemoryRegion *mem);
-void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem);
 
 /* Legacy helper function for creating devices.  */
 DeviceState *sysbus_create_varargs(const char *name,
index b2bf35934d13e33c3f8a5cbed062da27cb9b77b0..de6ffc61336d71ceec840e7df6664756db98568c 100644 (file)
 #include "usb.h"
 #include "omap.h"
 #include "irq.h"
-#include "tusb6010.h"
+#include "devices.h"
+#include "sysbus.h"
 
-struct TUSBState {
+typedef struct TUSBState {
+    SysBusDevice busdev;
     MemoryRegion iomem[2];
     qemu_irq irq;
     MUSBState *musb;
@@ -59,7 +61,7 @@ struct TUSBState {
     uint32_t pullup[2];
     uint32_t control_config;
     uint32_t otg_timer_val;
-};
+} TUSBState;
 
 #define TUSB_DEVCLOCK                  60000000        /* 60 MHz */
 
@@ -234,16 +236,6 @@ struct TUSBState {
 #define TUSB_EP_CONFIG_XFR_SIZE(v)     ((v) & 0x7fffffff)
 #define TUSB_PROD_TEST_RESET_VAL       0xa596
 
-MemoryRegion *tusb6010_sync_io(TUSBState *s)
-{
-    return &s->iomem[0];
-}
-
-MemoryRegion *tusb6010_async_io(TUSBState *s)
-{
-    return &s->iomem[1];
-}
-
 static void tusb_intr_update(TUSBState *s)
 {
     if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY)
@@ -723,9 +715,33 @@ static void tusb_musb_core_intr(void *opaque, int source, int level)
     }
 }
 
-TUSBState *tusb6010_init(qemu_irq intr)
+static void tusb6010_power(TUSBState *s, int on)
 {
-    TUSBState *s = g_malloc0(sizeof(*s));
+    if (!on) {
+        s->power = 0;
+    } else if (!s->power && on) {
+        s->power = 1;
+        /* Pull the interrupt down after TUSB6010 comes up.  */
+        s->intr_ok = 0;
+        tusb_intr_update(s);
+        qemu_mod_timer(s->pwr_timer,
+                       qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2);
+    }
+}
+
+static void tusb6010_irq(void *opaque, int source, int level)
+{
+    if (source) {
+        tusb_musb_core_intr(opaque, source - 1, level);
+    } else {
+        tusb6010_power(opaque, level);
+    }
+}
+
+static void tusb6010_reset(DeviceState *dev)
+{
+    TUSBState *s = FROM_SYSBUS(TUSBState, sysbus_from_qdev(dev));
+    int i;
 
     s->test_reset = TUSB_PROD_TEST_RESET_VAL;
     s->host_mode = 0;
@@ -735,28 +751,59 @@ TUSBState *tusb6010_init(qemu_irq intr)
     s->mask = 0xffffffff;
     s->intr = 0x00000000;
     s->otg_timer_val = 0;
-    memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async",
-                          UINT32_MAX);
-    s->irq = intr;
+    s->scratch = 0;
+    s->prcm_config = 0;
+    s->prcm_mngmt = 0;
+    s->intr_ok = 0;
+    s->usbip_intr = 0;
+    s->usbip_mask = 0;
+    s->gpio_intr = 0;
+    s->gpio_mask = 0;
+    s->gpio_config = 0;
+    s->dma_intr = 0;
+    s->dma_mask = 0;
+    s->dma_map = 0;
+    s->dma_config = 0;
+    s->ep0_config = 0;
+    s->wkup_mask = 0;
+    s->pullup[0] = s->pullup[1] = 0;
+    s->control_config = 0;
+    for (i = 0; i < 15; i++) {
+        s->rx_config[i] = s->tx_config[i] = 0;
+    }
+}
+
+static int tusb6010_init(SysBusDevice *dev)
+{
+    TUSBState *s = FROM_SYSBUS(TUSBState, dev);
+    qemu_irq *musb_irqs;
+    int i;
     s->otg_timer = qemu_new_timer_ns(vm_clock, tusb_otg_tick, s);
     s->pwr_timer = qemu_new_timer_ns(vm_clock, tusb_power_tick, s);
-    s->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s,
-                            __musb_irq_max));
-
-    return s;
+    memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async",
+                          UINT32_MAX);
+    sysbus_init_mmio_region(dev, &s->iomem[0]);
+    sysbus_init_mmio_region(dev, &s->iomem[1]);
+    sysbus_init_irq(dev, &s->irq);
+    qdev_init_gpio_in(&dev->qdev, tusb6010_irq, __musb_irq_max + 1);
+    musb_irqs = g_new0(qemu_irq, __musb_irq_max);
+    for (i = 0; i < __musb_irq_max; i++) {
+        musb_irqs[i] = qdev_get_gpio_in(&dev->qdev, i + 1);
+    }
+    s->musb = musb_init(musb_irqs);
+    return 0;
 }
 
-void tusb6010_power(TUSBState *s, int on)
-{
-    if (!on)
-        s->power = 0;
-    else if (!s->power && on) {
-        s->power = 1;
+static SysBusDeviceInfo tusb6010_info = {
+    .init = tusb6010_init,
+    .qdev.name = "tusb6010",
+    .qdev.size = sizeof(TUSBState),
+    .qdev.reset = tusb6010_reset,
+};
 
-        /* Pull the interrupt down after TUSB6010 comes up.  */
-        s->intr_ok = 0;
-        tusb_intr_update(s);
-        qemu_mod_timer(s->pwr_timer,
-                       qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2);
-    }
+static void tusb6010_register_device(void)
+{
+    sysbus_register_withprop(&tusb6010_info);
 }
+
+device_init(tusb6010_register_device)
diff --git a/hw/tusb6010.h b/hw/tusb6010.h
deleted file mode 100644 (file)
index b85ee86..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * tusb6010 interfaces
- *
- * Copyright 2011 Red Hat, Inc. and/or its affiliates
- *
- * Authors:
- *  Avi Kivity <avi@redhat.com>
- *
- * Derived from hw/devices.h.
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef TUSB6010_H
-#define TUSB6010_H
-
-#include "targphys.h"
-#include "memory.h"
-
-typedef struct TUSBState TUSBState;
-TUSBState *tusb6010_init(qemu_irq intr);
-MemoryRegion *tusb6010_sync_io(TUSBState *s);
-MemoryRegion *tusb6010_async_io(TUSBState *s);
-void tusb6010_power(TUSBState *s, int on);
-
-#endif
index 600cd1e5bd7a3791c8aa8a5ae053b6a8d0ec192a..f896f8c76b3b10f2abac40c114a9a6047a2d461d 100644 (file)
@@ -41,6 +41,7 @@ static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
 typedef struct UNINState {
     SysBusDevice busdev;
     PCIHostState host_state;
+    ReadWriteHandler data_handler;
 } UNINState;
 
 static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -99,70 +100,67 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
     return retval;
 }
 
-static void unin_data_write(void *opaque, target_phys_addr_t addr,
-                            uint64_t val, unsigned len)
+static void unin_data_write(ReadWriteHandler *handler,
+                            pcibus_t addr, uint32_t val, int len)
 {
-    UNINState *s = opaque;
-    UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n",
-                 addr, len, val);
+    UNINState *s = container_of(handler, UNINState, data_handler);
+    UNIN_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
     pci_data_write(s->host_state.bus,
                    unin_get_config_reg(s->host_state.config_reg, addr),
                    val, len);
 }
 
-static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr,
-                               unsigned len)
+static uint32_t unin_data_read(ReadWriteHandler *handler,
+                               pcibus_t addr, int len)
 {
-    UNINState *s = opaque;
+    UNINState *s = container_of(handler, UNINState, data_handler);
     uint32_t val;
 
     val = pci_data_read(s->host_state.bus,
                         unin_get_config_reg(s->host_state.config_reg, addr),
                         len);
-    UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n",
-                 addr, len, val);
+    UNIN_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
     return val;
 }
 
-static const MemoryRegionOps unin_data_ops = {
-    .read = unin_data_read,
-    .write = unin_data_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
 static int pci_unin_main_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Use values found on a real PowerMac */
     /* Uninorth main bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
-                          "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    s->data_handler.read = unin_data_read;
+    s->data_handler.write = unin_data_write;
+    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
+                                                 DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
     return 0;
 }
 
-
 static int pci_u3_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth U3 AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
-                          "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    s->data_handler.read = unin_data_read;
+    s->data_handler.write = unin_data_write;
+    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
+                                                 DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
 
@@ -172,32 +170,34 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
 static int pci_unin_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
 static int pci_unin_internal_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth internal bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
index 66aeb211af4ba52f8dea593a15149455825862d4..c2f924101486201a3307d9702de749e7d8c9c204 100644 (file)
@@ -176,56 +176,56 @@ enum {
      */
 };
 
-typedef struct __attribute__ ((__packed__)) CCID_Header {
+typedef struct QEMU_PACKED CCID_Header {
     uint8_t     bMessageType;
     uint32_t    dwLength;
     uint8_t     bSlot;
     uint8_t     bSeq;
 } CCID_Header;
 
-typedef struct __attribute__ ((__packed__)) CCID_BULK_IN {
+typedef struct QEMU_PACKED CCID_BULK_IN {
     CCID_Header hdr;
     uint8_t     bStatus;        /* Only used in BULK_IN */
     uint8_t     bError;         /* Only used in BULK_IN */
 } CCID_BULK_IN;
 
-typedef struct __attribute__ ((__packed__)) CCID_SlotStatus {
+typedef struct QEMU_PACKED CCID_SlotStatus {
     CCID_BULK_IN b;
     uint8_t     bClockStatus;
 } CCID_SlotStatus;
 
-typedef struct __attribute__ ((__packed__)) CCID_Parameter {
+typedef struct QEMU_PACKED CCID_Parameter {
     CCID_BULK_IN b;
     uint8_t     bProtocolNum;
     uint8_t     abProtocolDataStructure[0];
 } CCID_Parameter;
 
-typedef struct __attribute__ ((__packed__)) CCID_DataBlock {
+typedef struct QEMU_PACKED CCID_DataBlock {
     CCID_BULK_IN b;
     uint8_t      bChainParameter;
     uint8_t      abData[0];
 } CCID_DataBlock;
 
 /* 6.1.4 PC_to_RDR_XfrBlock */
-typedef struct __attribute__ ((__packed__)) CCID_XferBlock {
+typedef struct QEMU_PACKED CCID_XferBlock {
     CCID_Header  hdr;
     uint8_t      bBWI; /* Block Waiting Timeout */
     uint16_t     wLevelParameter; /* XXX currently unused */
     uint8_t      abData[0];
 } CCID_XferBlock;
 
-typedef struct __attribute__ ((__packed__)) CCID_IccPowerOn {
+typedef struct QEMU_PACKED CCID_IccPowerOn {
     CCID_Header hdr;
     uint8_t     bPowerSelect;
     uint16_t    abRFU;
 } CCID_IccPowerOn;
 
-typedef struct __attribute__ ((__packed__)) CCID_IccPowerOff {
+typedef struct QEMU_PACKED CCID_IccPowerOff {
     CCID_Header hdr;
     uint16_t    abRFU;
 } CCID_IccPowerOff;
 
-typedef struct __attribute__ ((__packed__)) CCID_SetParameters {
+typedef struct QEMU_PACKED CCID_SetParameters {
     CCID_Header hdr;
     uint8_t     bProtocolNum;
     uint16_t   abRFU;
index 851fd689b32427279f81e54d2133c6885e1641c0..125fb293f23f21787a3ba1657706f3412936734c 100644 (file)
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -176,6 +176,7 @@ static void vga_update_memory_access(VGACommonState *s)
             size = 0x8000;
             break;
         case 3:
+        default:
             base = 0xb8000;
             size = 0x8000;
             break;
index 18860678ba059ecf70c69caecb16e82b42ab7f9f..0870cb7d8590db00fdc5ec880386665adc4b1a9e 100644 (file)
@@ -515,11 +515,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
     };
     struct VirtQueue *vvq = virtio_get_queue(vdev, idx);
 
-    if (!vdev->binding->set_host_notifier) {
-        fprintf(stderr, "binding does not support host notifiers\n");
-        return -ENOSYS;
-    }
-
     vq->num = state.num = virtio_queue_get_num(vdev, idx);
     r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state);
     if (r) {
@@ -567,12 +562,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
         r = -errno;
         goto fail_alloc;
     }
-    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, true);
-    if (r < 0) {
-        fprintf(stderr, "Error binding host notifier: %d\n", -r);
-        goto fail_host_notifier;
-    }
-
     file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
     r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file);
     if (r) {
@@ -591,8 +580,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
 
 fail_call:
 fail_kick:
-    vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
-fail_host_notifier:
 fail_alloc:
     cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
                               0, 0);
@@ -618,12 +605,6 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev,
         .index = idx,
     };
     int r;
-    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
-    if (r < 0) {
-        fprintf(stderr, "vhost VQ %d host cleanup failed: %d\n", idx, r);
-        fflush(stderr);
-    }
-    assert (r >= 0);
     r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state);
     if (r < 0) {
         fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
@@ -697,6 +678,60 @@ bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev)
         hdev->force;
 }
 
+/* Stop processing guest IO notifications in qemu.
+ * Start processing them in vhost in kernel.
+ */
+int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
+{
+    int i, r;
+    if (!vdev->binding->set_host_notifier) {
+        fprintf(stderr, "binding does not support host notifiers\n");
+        r = -ENOSYS;
+        goto fail;
+    }
+
+    for (i = 0; i < hdev->nvqs; ++i) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, true);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier binding failed: %d\n", i, -r);
+            goto fail_vq;
+        }
+    }
+
+    return 0;
+fail_vq:
+    while (--i >= 0) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier cleanup error: %d\n", i, -r);
+            fflush(stderr);
+        }
+        assert (r >= 0);
+    }
+fail:
+    return r;
+}
+
+/* Stop processing guest IO notifications in vhost.
+ * Start processing them in qemu.
+ * This might actually run the qemu handlers right away,
+ * so virtio in qemu must be completely setup when this is called.
+ */
+void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
+{
+    int i, r;
+
+    for (i = 0; i < hdev->nvqs; ++i) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier cleanup failed: %d\n", i, -r);
+            fflush(stderr);
+        }
+        assert (r >= 0);
+    }
+}
+
+/* Host notifiers must be enabled at this point. */
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i, r;
@@ -762,6 +797,7 @@ fail:
     return r;
 }
 
+/* Host notifiers must be enabled at this point. */
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i, r;
index c8c595a147d48f36b67795d4f33d735005d5a7ca..c9452f073297f96725635d1cf5fa244e56a3a417 100644 (file)
@@ -46,5 +46,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
+int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
+void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
 
 #endif
index a55981200d5cf6c1fd71b5dd3e533e7bb4cfd1ce..950a6b8d990389702164e7ceb7b0565d93f1a2c6 100644 (file)
@@ -139,16 +139,22 @@ int vhost_net_start(struct vhost_net *net,
 {
     struct vhost_vring_file file = { };
     int r;
+
+    net->dev.nvqs = 2;
+    net->dev.vqs = net->vqs;
+
+    r = vhost_dev_enable_notifiers(&net->dev, dev);
+    if (r < 0) {
+        goto fail_notifiers;
+    }
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc,
                              sizeof(struct virtio_net_hdr_mrg_rxbuf));
     }
 
-    net->dev.nvqs = 2;
-    net->dev.vqs = net->vqs;
     r = vhost_dev_start(&net->dev, dev);
     if (r < 0) {
-        return r;
+        goto fail_start;
     }
 
     net->vc->info->poll(net->vc, false);
@@ -173,6 +179,9 @@ fail:
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
     }
+fail_start:
+    vhost_dev_disable_notifiers(&net->dev, dev);
+fail_notifiers:
     return r;
 }
 
@@ -190,6 +199,7 @@ void vhost_net_stop(struct vhost_net *net,
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
     }
+    vhost_dev_disable_notifiers(&net->dev, dev);
 }
 
 void vhost_net_cleanup(struct vhost_net *net)
index aa9e51222f6323fe8f4451f51fc8cb3c8843bea1..333050cdacf0f5c0c764a2ec39415b5a4951b59b 100644 (file)
@@ -196,7 +196,7 @@ static void virtex_init(ram_addr_t ram_size,
     target_phys_addr_t ram_base = 0;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     clk_setup_t clk_setup[7];
     int kernel_size;
@@ -215,13 +215,12 @@ static void virtex_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "ram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "virtex.flash", FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xfc000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0);
+                          1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0);
index e20cf6bc0dbb53aff1b1f7f75a6d3f3cc482ce1e..73300ddc864a31e1b197bc540259f3cb23ab0c35 100644 (file)
@@ -50,6 +50,6 @@ struct virtio_balloon_config
 typedef struct VirtIOBalloonStat {
     uint16_t tag;
     uint64_t val;
-} __attribute__((packed)) VirtIOBalloonStat;
+} QEMU_PACKED VirtIOBalloonStat;
 
 #endif
index dad8c0a6a279a3364cc6088bb7871c225e5e0811..2a8ccd0aa924c857b6ad05d4e248876383bc9668 100644 (file)
@@ -47,6 +47,7 @@ typedef struct VirtIOBlockReq
     struct virtio_scsi_inhdr *scsi;
     QEMUIOVector qiov;
     struct VirtIOBlockReq *next;
+    BlockAcctCookie acct;
 } VirtIOBlockReq;
 
 static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
@@ -58,8 +59,6 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
     stb_p(&req->in->status, status);
     virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
     virtio_notify(&s->vdev, s->vq);
-
-    g_free(req);
 }
 
 static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
@@ -81,6 +80,8 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
         vm_stop(VMSTOP_DISKFULL);
     } else {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        bdrv_acct_done(s->bs, &req->acct);
+        g_free(req);
         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
     }
 
@@ -100,6 +101,8 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+    bdrv_acct_done(req->dev->bs, &req->acct);
+    g_free(req);
 }
 
 static void virtio_blk_flush_complete(void *opaque, int ret)
@@ -113,6 +116,8 @@ static void virtio_blk_flush_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+    bdrv_acct_done(req->dev->bs, &req->acct);
+    g_free(req);
 }
 
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
@@ -155,6 +160,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
      */
     if (req->elem.out_num < 2 || req->elem.in_num < 3) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        g_free(req);
         return;
     }
 
@@ -163,6 +169,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
      */
     if (req->elem.out_num > 2 && req->elem.in_num > 3) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+        g_free(req);
         return;
     }
 
@@ -229,11 +236,13 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
     stl_p(&req->scsi->data_len, hdr.dxfer_len);
 
     virtio_blk_req_complete(req, status);
+    g_free(req);
 }
 #else
 static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
 {
     virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+    g_free(req);
 }
 #endif /* __linux__ */
 
@@ -266,6 +275,8 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
     BlockDriverAIOCB *acb;
 
+    bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
+
     /*
      * Make sure all outstanding writes are posted to the backing device.
      */
@@ -284,6 +295,8 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 
     sector = ldq_p(&req->out->sector);
 
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
+
     trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
 
     if (sector & req->dev->sector_mask) {
@@ -317,6 +330,8 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
 
     sector = ldq_p(&req->out->sector);
 
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
+
     if (sector & req->dev->sector_mask) {
         virtio_blk_rw_complete(req, -EIO);
         return;
@@ -370,6 +385,7 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
                 s->serial ? s->serial : "",
                 MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
         virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+        g_free(req);
     } else if (type & VIRTIO_BLK_T_OUT) {
         qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
                                  req->elem.out_num - 1);
index 5645d2bf3c37ca8f5e174f30eab5ab67693863a8..244dce45aa31b9f6f85d3135c0d4e6cab3bf9475 100644 (file)
@@ -49,7 +49,7 @@ struct virtio_blk_config
     uint8_t alignment_offset;
     uint16_t min_io_size;
     uint32_t opt_io_size;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* These two define direction. */
 #define VIRTIO_BLK_T_IN         0
index 8af9a1ce55fd8d8814d02cd8906e7c7c6d76c194..44687414c95cb5ac8f283cb9b839af95dc9af971 100644 (file)
@@ -72,7 +72,7 @@ struct virtio_net_config
     uint8_t mac[ETH_ALEN];
     /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
     uint16_t status;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* This is the first element of the scatter-gather list.  If you don't
  * specify GSO or CSUM features, you can simply ignore the header. */
index 36e9d222e58a421375e8cfe74caba55f99449246..ab138038c0edf7f48af363a5032dcf5a7669da6f 100644 (file)
@@ -37,7 +37,7 @@ struct virtio_console_config {
     uint16_t rows;
 
     uint32_t max_nr_ports;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct virtio_console_control {
     uint32_t id;               /* Port number */
index 52d2d26f1b63de5fdacb8296332abe410699bcf0..aa682376ad8095837267657b68986eb6174dc5bb 100644 (file)
@@ -70,7 +70,7 @@ struct vmsvga_state_s {
 
     union {
         uint32_t *fifo;
-        struct __attribute__((__packed__)) {
+        struct QEMU_PACKED {
             uint32_t min;
             uint32_t max;
             uint32_t next_cmd;
index 31f91514f2b2cba017fb612d5d9e1e858de8c40c..bd5c66916bc134dc6366c62e884e19ada1b1b599 100644 (file)
@@ -79,6 +79,7 @@ struct ioreq {
 
     struct XenBlkDev    *blkdev;
     QLIST_ENTRY(ioreq)   list;
+    BlockAcctCookie     acct;
 };
 
 struct XenBlkDev {
@@ -401,6 +402,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
     ioreq_unmap(ioreq);
     ioreq_finish(ioreq);
+    bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
     qemu_bh_schedule(ioreq->blkdev->bh);
 }
 
@@ -419,6 +421,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
+        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_READ);
         ioreq->aio_inflight++;
         bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
@@ -429,6 +432,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         if (!ioreq->req.nr_segments) {
             break;
         }
+
+        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_WRITE);
         ioreq->aio_inflight++;
         bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
                         &ioreq->v, ioreq->v.size / BLOCK_SIZE,
index f35ba8461a07770675ca7455def47cef7bd8e741..6f44c8466eeb8b1610a44940b9085fe0e53cd857 100644 (file)
@@ -50,6 +50,7 @@
 struct xlx_ethlite
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq irq;
     NICState *nic;
     NICConf conf;
@@ -70,7 +71,8 @@ static inline void eth_pulse_irq(struct xlx_ethlite *s)
     }
 }
 
-static uint32_t eth_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+eth_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_ethlite *s = opaque;
     uint32_t r = 0;
@@ -98,10 +100,12 @@ static uint32_t eth_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+eth_write(void *opaque, target_phys_addr_t addr,
+          uint64_t val64, unsigned int size)
 {
     struct xlx_ethlite *s = opaque;
     unsigned int base = 0;
+    uint32_t value = val64;
 
     addr >>= 2;
     switch (addr) 
@@ -146,12 +150,14 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     }
 }
 
-static CPUReadMemoryFunc * const eth_read[] = {
-    NULL, NULL, &eth_readl,
-};
-
-static CPUWriteMemoryFunc * const eth_write[] = {
-    NULL, NULL, &eth_writel,
+static const MemoryRegionOps eth_ops = {
+    .read = eth_read,
+    .write = eth_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static int eth_can_rx(VLANClientState *nc)
@@ -206,13 +212,12 @@ static NetClientInfo net_xilinx_ethlite_info = {
 static int xilinx_ethlite_init(SysBusDevice *dev)
 {
     struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev);
-    int regs;
 
     sysbus_init_irq(dev, &s->irq);
     s->rxbuf = 0;
 
-    regs = cpu_register_io_memory(eth_read, eth_write, s, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, regs);
+    memory_region_init_io(&s->mmio, &eth_ops, s, "xilinx-ethlite", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
index cb72d5a14e6adf47904247e6e31b17e8450d863a..58b73d95cc6f35a22fe95bf2dde5f432f208c69a 100644 (file)
@@ -40,6 +40,7 @@
 struct xlx_pic
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq parent_irq;
 
     /* Configuration reg chosen at synthesis-time. QEMU populates
@@ -72,7 +73,8 @@ static void update_irq(struct xlx_pic *p)
     }
 }
 
-static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+pic_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_pic *p = opaque;
     uint32_t r = 0;
@@ -91,9 +93,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+pic_write(void *opaque, target_phys_addr_t addr,
+          uint64_t val64, unsigned int size)
 {
     struct xlx_pic *p = opaque;
+    uint32_t value = val64;
 
     addr >>= 2;
     D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value));
@@ -116,14 +120,14 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     update_irq(p);
 }
 
-static CPUReadMemoryFunc * const pic_read[] = {
-    NULL, NULL,
-    &pic_readl,
-};
-
-static CPUWriteMemoryFunc * const pic_write[] = {
-    NULL, NULL,
-    &pic_writel,
+static const MemoryRegionOps pic_ops = {
+    .read = pic_read,
+    .write = pic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static void irq_handler(void *opaque, int irq, int level)
@@ -148,13 +152,12 @@ static void irq_handler(void *opaque, int irq, int level)
 static int xilinx_intc_init(SysBusDevice *dev)
 {
     struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev);
-    int pic_regs;
 
     qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
     sysbus_init_irq(dev, &p->parent_irq);
 
-    pic_regs = cpu_register_io_memory(pic_read, pic_write, p, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, pic_regs);
+    memory_region_init_io(&p->mmio, &pic_ops, p, "xilinx-pic", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &p->mmio);
     return 0;
 }
 
index f1c7abc99e0fe65bac515e86d3c8a1127ebd1c78..8779c56f0bac85252491df0178c2c1e2cc50030a 100644 (file)
@@ -59,6 +59,7 @@ struct xlx_timer
 struct timerblock
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq irq;
     uint32_t nr_timers;
     uint32_t freq_hz;
@@ -85,7 +86,8 @@ static void timer_update_irq(struct timerblock *t)
     qemu_set_irq(t->irq, !!irq);
 }
 
-static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+timer_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct timerblock *t = opaque;
     struct xlx_timer *xt;
@@ -134,11 +136,13 @@ static void timer_enable(struct xlx_timer *xt)
 }
 
 static void
-timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+timer_write(void *opaque, target_phys_addr_t addr,
+            uint64_t val64, unsigned int size)
 {
     struct timerblock *t = opaque;
     struct xlx_timer *xt;
     unsigned int timer;
+    uint32_t value = val64;
 
     addr >>= 2;
     timer = timer_from_addr(addr);
@@ -166,14 +170,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     timer_update_irq(t);
 }
 
-static CPUReadMemoryFunc * const timer_read[] = {
-    NULL, NULL,
-    &timer_readl,
-};
-
-static CPUWriteMemoryFunc * const timer_write[] = {
-    NULL, NULL,
-    &timer_writel,
+static const MemoryRegionOps timer_ops = {
+    .read = timer_read,
+    .write = timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static void timer_hit(void *opaque)
@@ -192,7 +196,6 @@ static int xilinx_timer_init(SysBusDevice *dev)
 {
     struct timerblock *t = FROM_SYSBUS(typeof (*t), dev);
     unsigned int i;
-    int timer_regs;
 
     /* All timers share a single irq line.  */
     sysbus_init_irq(dev, &t->irq);
@@ -209,9 +212,9 @@ static int xilinx_timer_init(SysBusDevice *dev)
         ptimer_set_freq(xt->ptimer, t->freq_hz);
     }
 
-    timer_regs = cpu_register_io_memory(timer_read, timer_write, t,
-                                        DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs);
+    memory_region_init_io(&t->mmio, &timer_ops, t, "xilinx-timer",
+                          R_MAX * 4 * t->nr_timers);
+    sysbus_init_mmio_region(dev, &t->mmio);
     return 0;
 }
 
index 467a26cc9eb2b452bfe0158d4150738d099c70b7..ceb7b4d9ed19f1a35426e790c4b8d4a7fff9da15 100644 (file)
@@ -49,6 +49,7 @@
 struct xlx_uartlite
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     CharDriverState *chr;
     qemu_irq irq;
 
@@ -82,7 +83,8 @@ static void uart_update_status(struct xlx_uartlite *s)
     s->regs[R_STATUS] = r;
 }
 
-static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+uart_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_uartlite *s = opaque;
     uint32_t r = 0;
@@ -107,9 +109,11 @@ static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+uart_write(void *opaque, target_phys_addr_t addr,
+           uint64_t val64, unsigned int size)
 {
     struct xlx_uartlite *s = opaque;
+    uint32_t value = val64;
     unsigned char ch = value;
 
     addr >>= 2;
@@ -147,16 +151,14 @@ uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     uart_update_irq(s);
 }
 
-static CPUReadMemoryFunc * const uart_read[] = {
-    &uart_readl,
-    &uart_readl,
-    &uart_readl,
-};
-
-static CPUWriteMemoryFunc * const uart_write[] = {
-    &uart_writel,
-    &uart_writel,
-    &uart_writel,
+static const MemoryRegionOps uart_ops = {
+    .read = uart_read,
+    .write = uart_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4
+    }
 };
 
 static void uart_rx(void *opaque, const uint8_t *buf, int size)
@@ -196,14 +198,12 @@ static void uart_event(void *opaque, int event)
 static int xilinx_uartlite_init(SysBusDevice *dev)
 {
     struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
-    int uart_regs;
 
     sysbus_init_irq(dev, &s->irq);
 
     uart_update_status(s);
-    uart_regs = cpu_register_io_memory(uart_read, uart_write, s,
-                                       DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, uart_regs);
+    memory_region_init_io(&s->mmio, &uart_ops, s, "xilinx-uartlite", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     s->chr = qdev_init_chardev(&dev->qdev);
     if (s->chr)
diff --git a/hw/z2.c b/hw/z2.c
index d7b8d5327bb46923c8be8c6f9ec0641d55b0a96c..f93a1bf0fe369d37e5a4d8a93b1e80abdf5f4b6a 100644 (file)
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -280,11 +280,10 @@ static void z2_init(ram_addr_t ram_size,
     uint32_t sector_len = 0x10000;
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    const MemoryRegionOps *flash_ops;
+    int be;
     void *z2_lcd;
     i2c_bus *bus;
     DeviceState *wm;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "pxa270-c5";
@@ -294,9 +293,9 @@ static void z2_init(ram_addr_t ram_size,
     cpu = pxa270_init(z2_binfo.ram_size, cpu_model);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!dinfo) {
@@ -305,11 +304,11 @@ static void z2_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "z2.flash0", Z2_FLASH_SIZE);
-    if (!pflash_cfi01_register(Z2_FLASH_BASE, flash,
+    if (!pflash_cfi01_register(Z2_FLASH_BASE,
+                               qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE),
                                dinfo->bdrv, sector_len,
-                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0)) {
+                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
+                               be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
index c24aeb5763e36e9e1a2248b6c837861f8d4a44b8..0eeacf7cb3fb82aec031ac5750adfcf9d4929e9f 100644 (file)
@@ -246,7 +246,7 @@ device_init(scoop_register);
 
 #define MAGIC_CHG(a, b, c, d)  ((d << 24) | (c << 16) | (b << 8) | a)
 
-static struct __attribute__ ((__packed__)) sl_param_info {
+static struct QEMU_PACKED sl_param_info {
     uint32_t comadj_keyword;
     int32_t comadj;
 
diff --git a/i386.ld b/i386.ld
index f8df7bf8dd66fffb768e14f9aa14397f5177b522..cc3f160af07c21ceeb0fe62bf3772ad7b314ac41 100644 (file)
--- a/i386.ld
+++ b/i386.ld
@@ -42,16 +42,16 @@ SECTIONS
   .rel.plt      :
   {
     *(.rel.plt)
-    PROVIDE_HIDDEN (__rel_iplt_start = .);
+    PROVIDE (__rel_iplt_start = .);
     *(.rel.iplt)
-    PROVIDE_HIDDEN (__rel_iplt_end = .);
+    PROVIDE (__rel_iplt_end = .);
   }
   .rela.plt       :
   {
     *(.rela.plt)
-    PROVIDE_HIDDEN (__rela_iplt_start = .);
+    PROVIDE (__rela_iplt_start = .);
     *(.rela.iplt)
-    PROVIDE_HIDDEN (__rela_iplt_end = .);
+    PROVIDE (__rela_iplt_end = .);
   }
   .init          : { *(.init)  } =0x47ff041f
   .text      :
index 4deae1e6ab533464cacb7413935aac72d3579a0f..4cc1c5ade616eedb5c5687e9b62a7c7b4d187e31 100644 (file)
@@ -80,12 +80,64 @@ int qemu_set_fd_handler2(int fd,
     return 0;
 }
 
+typedef struct IOTrampoline
+{
+    GIOChannel *chan;
+    IOHandler *fd_read;
+    IOHandler *fd_write;
+    void *opaque;
+    guint tag;
+} IOTrampoline;
+
+static gboolean fd_trampoline(GIOChannel *chan, GIOCondition cond, gpointer opaque)
+{
+    IOTrampoline *tramp = opaque;
+
+    if ((cond & G_IO_IN) && tramp->fd_read) {
+        tramp->fd_read(tramp->opaque);
+    }
+
+    if ((cond & G_IO_OUT) && tramp->fd_write) {
+        tramp->fd_write(tramp->opaque);
+    }
+
+    return TRUE;
+}
+
 int qemu_set_fd_handler(int fd,
                         IOHandler *fd_read,
                         IOHandler *fd_write,
                         void *opaque)
 {
-    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
+    static IOTrampoline fd_trampolines[FD_SETSIZE];
+    IOTrampoline *tramp = &fd_trampolines[fd];
+
+    if (tramp->tag != 0) {
+        g_io_channel_unref(tramp->chan);
+        g_source_remove(tramp->tag);
+        tramp->tag = 0;
+    }
+
+    if (fd_read || fd_write || opaque) {
+        GIOCondition cond = 0;
+
+        tramp->fd_read = fd_read;
+        tramp->fd_write = fd_write;
+        tramp->opaque = opaque;
+
+        if (fd_read) {
+            cond |= G_IO_IN | G_IO_ERR;
+        }
+
+        if (fd_write) {
+            cond |= G_IO_OUT | G_IO_ERR;
+        }
+
+        tramp->chan = g_io_channel_unix_new(fd);
+        tramp->tag = g_io_add_watch(tramp->chan, cond, fd_trampoline, tramp);
+    }
+
+    return 0;
 }
 
 void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds)
index 0ae2e2697edd41f6a6047b19acb2579b3067c163..fbb9ff3bef7ab9f6a957627561629c2b705e042a 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -479,7 +479,7 @@ static int kvm_check_many_ioeventfds(void)
      * Older kernels have a 6 device limit on the KVM io bus.  Find out so we
      * can avoid creating too many ioeventfds.
      */
-#if defined(CONFIG_EVENTFD) && defined(CONFIG_IOTHREAD)
+#if defined(CONFIG_EVENTFD)
     int ioeventfds[7];
     int i, ret = 0;
     for (i = 0; i < ARRAY_SIZE(ioeventfds); i++) {
index b3f5e6c0119c2c88e667bab6563ee0fedcd6dbdd..bf052bcc128c846e0487c7625c71bd82c277f820 100644 (file)
@@ -20,7 +20,7 @@ QEMU_CFLAGS+=$(GLIB_CFLAGS)
 libcacard.lib-y=$(addsuffix .lo,$(basename $(libcacard-y)))
 
 vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o
-       $(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS) -lrt,"  LINK  $@")
+       $(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
 
 clean:
        rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo .libs/* *.la *.pc
@@ -39,7 +39,7 @@ install-libcacard:
        @echo "libtool is missing, please install and rerun configure"; exit 1
 else
 libcacard.la: $(libcacard.lib-y) $(QEMU_OBJS_LIB)
-       $(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs) -lrt,"  lt LINK $@")
+       $(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs),"  lt LINK $@")
 
 libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in
        sed -e 's|@LIBDIR@|$(libdir)|' \
index a7b38340dcc3ef7976fea6cf8a755ab95572905f..2191f6038c0156284c99f34bb1714ae02e6c5edd 100644 (file)
@@ -585,7 +585,7 @@ main(
                 printf(" recv APDU: ");
                 print_byte_array(pbSendBuffer, mhHeader.length);
             }
-            /* Transmit recieved APDU */
+            /* Transmit received APDU */
             dwSendLength = mhHeader.length;
             dwRecvLength = sizeof(pbRecvBuffer);
             reader = vreader_get_reader_by_id(mhHeader.reader_id);
index 07ad07a58f31e5c8ded51c6c90990778f0a37247..89276eb6a5e415950da9f2f3ef851f180c0cdcec 100644 (file)
@@ -3064,10 +3064,10 @@ static void setup_frame(int sig, struct target_sigaction *ka,
         goto give_sigsegv;
 
     /* Set up registers for signal handler */
-    regs->gregs[15] = (unsigned long) frame;
+    regs->gregs[15] = frame_addr;
     regs->gregs[4] = signal; /* Arg for signal handler */
     regs->gregs[5] = 0;
-    regs->gregs[6] = (unsigned long) &frame->sc;
+    regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
     regs->pc = (unsigned long) ka->_sa_handler;
 
     unlock_user_struct(frame, frame_addr, 1);
@@ -3127,10 +3127,10 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
         goto give_sigsegv;
 
     /* Set up registers for signal handler */
-    regs->gregs[15] = (unsigned long) frame;
+    regs->gregs[15] = frame_addr;
     regs->gregs[4] = signal; /* Arg for signal handler */
-    regs->gregs[5] = (unsigned long) &frame->info;
-    regs->gregs[6] = (unsigned long) &frame->uc;
+    regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
+    regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
     regs->pc = (unsigned long) ka->_sa_handler;
 
     unlock_user_struct(frame, frame_addr, 1);
@@ -3381,11 +3381,12 @@ static void setup_frame(int sig, struct target_sigaction *ka,
         goto badframe;
 
     /* Set up registers for signal handler */
-    env->regs[1] = (unsigned long) frame;
+    env->regs[1] = frame_addr;
     /* Signal handler args: */
     env->regs[5] = sig; /* Arg 0: signum */
     env->regs[6] = 0;
-    env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */
+    /* arg 1: sigcontext */
+    env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
 
     /* Offset of 4 to handle microblaze rtid r14, 0 */
     env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
@@ -3559,11 +3560,11 @@ static void setup_frame(int sig, struct target_sigaction *ka,
        setup_sigcontext(&frame->sc, env);
 
        /* Move the stack and setup the arguments for the handler.  */
-       env->regs[R_SP] = (uint32_t) (unsigned long) frame;
+       env->regs[R_SP] = frame_addr;
        env->regs[10] = sig;
        env->pc = (unsigned long) ka->_sa_handler;
        /* Link SRP so the guest returns through the trampoline.  */
-       env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
+       env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
 
        unlock_user_struct(frame, frame_addr, 1);
        return;
@@ -3769,11 +3770,11 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     }
 
     /* Set up registers for signal handler */
-    env->regs[15] = (target_ulong)(unsigned long) frame;
+    env->regs[15] = frame_addr;
     env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
 
     env->regs[2] = sig; //map_signal(sig);
-    env->regs[3] = (target_ulong)(unsigned long) &frame->sc;
+    env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
 
     /* We forgot to include these in the sigcontext.
        To avoid breaking binary compatibility, they are passed as args. */
@@ -3844,12 +3845,12 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     }
 
     /* Set up registers for signal handler */
-    env->regs[15] = (target_ulong)(unsigned long) frame;
+    env->regs[15] = frame_addr;
     env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
 
     env->regs[2] = sig; //map_signal(sig);
-    env->regs[3] = (target_ulong)(unsigned long) &frame->info;
-    env->regs[4] = (target_ulong)(unsigned long) &frame->uc;
+    env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
+    env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
     return;
 
 give_sigsegv:
index a117407d8452832aee1126b4ff77ca6bdf71413b..15c44d45a8d1d4fa901eac2d961a7ba2424d15a8 100644 (file)
@@ -1120,7 +1120,7 @@ struct target_stat64 {
        abi_ulong       __pad7;         /* will be high 32 bits of ctime someday */
 
        unsigned long long      st_ino;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #ifdef TARGET_ARM
 struct target_eabi_stat64 {
@@ -1151,7 +1151,7 @@ struct target_eabi_stat64 {
         abi_ulong    target_st_ctime_nsec;
 
         unsigned long long st_ino;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 #endif
 
 #elif defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
@@ -1294,7 +1294,7 @@ struct target_stat {
 #endif
 };
 
-struct __attribute__((__packed__)) target_stat64 {
+struct QEMU_PACKED target_stat64 {
        unsigned long long st_dev;
         unsigned long long st_ino;
        unsigned int st_mode;
@@ -1341,7 +1341,7 @@ struct target_stat {
 };
 
 /* FIXME: Microblaze no-mmu user-space has a difference stat64 layout...  */
-struct __attribute__((__packed__)) target_stat64 {
+struct QEMU_PACKED target_stat64 {
        uint64_t st_dev;
 #define TARGET_STAT64_HAS_BROKEN_ST_INO 1
        uint32_t pad0;
@@ -1428,7 +1428,7 @@ struct target_stat64 {
        abi_ulong       target_st_ctime_nsec;
 
        unsigned long long      st_ino;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #elif defined(TARGET_ABI_MIPSN64)
 
@@ -1680,7 +1680,7 @@ struct target_stat {
 /* This matches struct stat64 in glibc2.1, hence the absolutely
  * insane amounts of padding around dev_t's.
  */
-struct __attribute__((__packed__)) target_stat64 {
+struct QEMU_PACKED target_stat64 {
        unsigned long long      st_dev;
        unsigned char   __pad0[4];
 
@@ -2095,7 +2095,7 @@ struct target_flock64 {
        unsigned long long l_start;
        unsigned long long l_len;
        int  l_pid;
-}__attribute__((packed));
+} QEMU_PACKED;
 
 #ifdef TARGET_ARM
 struct target_eabi_flock64 {
@@ -2105,7 +2105,7 @@ struct target_eabi_flock64 {
        unsigned long long l_start;
        unsigned long long l_len;
        int  l_pid;
-}__attribute__((packed));
+} QEMU_PACKED;
 #endif
 
 /* soundcard defines */
index 7fde10e8f36254685058e153c93a39c4d4a28a94..bab01ee863181985291e02a9e455cc720c04ff97 100644 (file)
@@ -70,12 +70,12 @@ struct m68k_gdb_stat {
   gdb_time_t  gdb_st_atime;   /* time of last access */
   gdb_time_t  gdb_st_mtime;   /* time of last modification */
   gdb_time_t  gdb_st_ctime;   /* time of last change */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct gdb_timeval {
   gdb_time_t tv_sec;  /* second */
   uint64_t tv_usec;   /* microsecond */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define GDB_O_RDONLY   0x0
 #define GDB_O_WRONLY   0x1
index 8e9ac460e8813e63fb2f3622c3704035250cbb45..57f0fa44ff5b501ee9cb1a740fc5acd311f169dc 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -304,7 +304,7 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
     }
 
     if (!fr->readable) {
-        phys_offset &= TARGET_PAGE_MASK;
+        phys_offset &= ~TARGET_PAGE_MASK & ~IO_MEM_ROMD;
     }
 
     cpu_register_physical_memory_log(fr->addr.start,
@@ -962,11 +962,14 @@ void memory_region_init_alias(MemoryRegion *mr,
 
 void memory_region_init_rom_device(MemoryRegion *mr,
                                    const MemoryRegionOps *ops,
+                                   void *opaque,
                                    DeviceState *dev,
                                    const char *name,
                                    uint64_t size)
 {
     memory_region_init(mr, name, size);
+    mr->ops = ops;
+    mr->opaque = opaque;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_rom_device;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
@@ -1060,7 +1063,7 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
 
     assert(mr->terminates);
 
-    return qemu_get_ram_ptr(mr->ram_addr);
+    return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
 }
 
 static void memory_region_update_coalesced_range(MemoryRegion *mr)
index 0553cc7526e47eac69eeac79558ffa59a1d42156..06b83ae76b3ec050f20d6a02b7b262750b42c66e 100644 (file)
--- a/memory.h
+++ b/memory.h
@@ -235,6 +235,7 @@ void memory_region_init_alias(MemoryRegion *mr,
  */
 void memory_region_init_rom_device(MemoryRegion *mr,
                                    const MemoryRegionOps *ops,
+                                   void *opaque,
                                    DeviceState *dev, /* FIXME: layering violation */
                                    const char *name,
                                    uint64_t size);
diff --git a/mips.ld b/mips.ld
index 4294761c199b234faf204f6269a55db8fd788e1f..7b610ceed47d3a3a40df4e785b1f752595fa41a0 100644 (file)
--- a/mips.ld
+++ b/mips.ld
@@ -79,36 +79,34 @@ SECTIONS
   }
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN (0x40000) - ((0x40000 - .) & (0x40000 - 1)); . = DATA_SEGMENT_ALIGN (0x40000, 0x1000);
   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table .gcc_except_table.*) }
   /* Thread Local Storage sections  */
   .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors          :
   {
index ada51d0c232e025bd5e1f1cab639358e379fce05..df0f622067a8a1f9912aeb7f540ad38b2edc5ec1 100644 (file)
--- a/monitor.c
+++ b/monitor.c
 #include "json-parser.h"
 #include "osdep.h"
 #include "cpu.h"
-#ifdef CONFIG_SIMPLE_TRACE
-#include "trace.h"
+#include "trace/control.h"
+#ifdef CONFIG_TRACE_SIMPLE
+#include "trace/simple.h"
 #endif
+#include "trace/control.h"
 #include "ui/qemu-spice.h"
 
 //#define DEBUG
@@ -592,18 +594,18 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict)
     help_cmd(mon, qdict_get_try_str(qdict, "name"));
 }
 
-#ifdef CONFIG_SIMPLE_TRACE
-static void do_change_trace_event_state(Monitor *mon, const QDict *qdict)
+static void do_trace_event_set_state(Monitor *mon, const QDict *qdict)
 {
     const char *tp_name = qdict_get_str(qdict, "name");
     bool new_state = qdict_get_bool(qdict, "option");
-    int ret = st_change_trace_event_state(tp_name, new_state);
+    int ret = trace_event_set_state(tp_name, new_state);
 
     if (!ret) {
         monitor_printf(mon, "unknown event name \"%s\"\n", tp_name);
     }
 }
 
+#ifdef CONFIG_SIMPLE_TRACE
 static void do_trace_file(Monitor *mon, const QDict *qdict)
 {
     const char *op = qdict_get_try_str(qdict, "op");
@@ -996,17 +998,17 @@ static void do_info_cpu_stats(Monitor *mon)
 }
 #endif
 
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_TRACE_SIMPLE)
 static void do_info_trace(Monitor *mon)
 {
     st_print_trace((FILE *)mon, &monitor_fprintf);
 }
+#endif
 
-static void do_info_trace_events(Monitor *mon)
+static void do_trace_print_events(Monitor *mon)
 {
-    st_print_trace_events((FILE *)mon, &monitor_fprintf);
+    trace_print_events((FILE *)mon, &monitor_fprintf);
 }
-#endif
 
 /**
  * do_quit(): Quit QEMU execution
@@ -1189,7 +1191,6 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d
 {
     const char *protocol  = qdict_get_str(qdict, "protocol");
     const char *fdname = qdict_get_str(qdict, "fdname");
-    int skipauth = qdict_get_try_bool(qdict, "skipauth", 0);
     CharDriverState *s;
 
     if (strcmp(protocol, "spice") == 0) {
@@ -1203,6 +1204,7 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d
 #ifdef CONFIG_VNC
     } else if (strcmp(protocol, "vnc") == 0) {
        int fd = monitor_get_fd(mon, fdname);
+        int skipauth = qdict_get_try_bool(qdict, "skipauth", 0);
        vnc_display_add_client(NULL, fd, skipauth);
        return 0;
 #endif
@@ -3135,7 +3137,7 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show roms",
         .mhandler.info = do_info_roms,
     },
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_TRACE_SIMPLE)
     {
         .name       = "trace",
         .args_type  = "",
@@ -3143,14 +3145,14 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show current contents of trace buffer",
         .mhandler.info = do_info_trace,
     },
+#endif
     {
         .name       = "trace-events",
         .args_type  = "",
         .params     = "",
         .help       = "show available trace-events & their state",
-        .mhandler.info = do_info_trace_events,
+        .mhandler.info = do_trace_print_events,
     },
-#endif
     {
         .name       = NULL,
     },
diff --git a/nbd.h b/nbd.h
index b38d0d08de2d80bdf545251f8b02921234b973c5..96f77fe2d13f336ffba5ab4bff3e45e66e66e055 100644 (file)
--- a/nbd.h
+++ b/nbd.h
@@ -31,13 +31,13 @@ struct nbd_request {
     uint64_t handle;
     uint64_t from;
     uint32_t len;
-} __attribute__ ((__packed__));
+} QEMU_PACKED;
 
 struct nbd_reply {
     uint32_t magic;
     uint32_t error;
     uint64_t handle;
-} __attribute__ ((__packed__));
+} QEMU_PACKED;
 
 enum {
     NBD_CMD_READ = 0,
diff --git a/net.h b/net.h
index 5a7881cf671e231b18cb346566e20642a44c8553..9f633f8432f6e37da36e4d738f603327a5e3424c 100644 (file)
--- a/net.h
+++ b/net.h
@@ -174,11 +174,6 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
-#ifdef __sun__
-#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
-#else
-#define SMBD_COMMAND "/usr/sbin/smbd"
-#endif
 
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
 
index 3b39d21183bc0beff3fba27f085a6692a02ca6d0..c6cda5dcb2b8cb22661a023246585e43bdcd0fb2 100644 (file)
@@ -529,7 +529,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
     fclose(f);
 
     snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
-             SMBD_COMMAND, smb_conf);
+             CONFIG_SMBD_COMMAND, smb_conf);
 
     if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0) {
         slirp_smb_cleanup(s);
index babb0940dd6c20c9c64bbf146684085a10662b90..3193dbf83c0e398665c1fad3e941fb5e20070a4f 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "block/raw-posix-aio.h"
 
+static void do_spawn_thread(void);
 
 struct qemu_paiocb {
     BlockDriverAIOCB common;
@@ -64,6 +65,9 @@ static pthread_attr_t attr;
 static int max_threads = 64;
 static int cur_threads = 0;
 static int idle_threads = 0;
+static int new_threads = 0;     /* backlog of threads we need to create */
+static int pending_threads = 0; /* threads created but not running yet */
+static QEMUBH *new_thread_bh;
 static QTAILQ_HEAD(, qemu_paiocb) request_list;
 
 #ifdef CONFIG_PREADV
@@ -311,6 +315,11 @@ static void *aio_thread(void *unused)
 
     pid = getpid();
 
+    mutex_lock(&lock);
+    pending_threads--;
+    mutex_unlock(&lock);
+    do_spawn_thread();
+
     while (1) {
         struct qemu_paiocb *aiocb;
         ssize_t ret = 0;
@@ -381,11 +390,20 @@ static void *aio_thread(void *unused)
     return NULL;
 }
 
-static void spawn_thread(void)
+static void do_spawn_thread(void)
 {
     sigset_t set, oldset;
 
-    cur_threads++;
+    mutex_lock(&lock);
+    if (!new_threads) {
+        mutex_unlock(&lock);
+        return;
+    }
+
+    new_threads--;
+    pending_threads++;
+
+    mutex_unlock(&lock);
 
     /* block all signals */
     if (sigfillset(&set)) die("sigfillset");
@@ -396,6 +414,27 @@ static void spawn_thread(void)
     if (sigprocmask(SIG_SETMASK, &oldset, NULL)) die("sigprocmask restore");
 }
 
+static void spawn_thread_bh_fn(void *opaque)
+{
+    do_spawn_thread();
+}
+
+static void spawn_thread(void)
+{
+    cur_threads++;
+    new_threads++;
+    /* If there are threads being created, they will spawn new workers, so
+     * we don't spend time creating many threads in a loop holding a mutex or
+     * starving the current vcpu.
+     *
+     * If there are no idle threads, ask the main thread to create one, so we
+     * inherit the correct affinity instead of the vcpu affinity.
+     */
+    if (!pending_threads) {
+        qemu_bh_schedule(new_thread_bh);
+    }
+}
+
 static void qemu_paio_submit(struct qemu_paiocb *aiocb)
 {
     aiocb->ret = -EINPROGRESS;
@@ -665,6 +704,7 @@ int paio_init(void)
         die2(ret, "pthread_attr_setdetachstate");
 
     QTAILQ_INIT(&request_list);
+    new_thread_bh = qemu_bh_new(spawn_thread_bh_fn, NULL);
 
     posix_aio_state = s;
     return 0;
diff --git a/ppc.ld b/ppc.ld
index 5248ef15a540c272f16e3b6247ce7b5f86ce7d78..69aa3f228dc70fd8a15d9d0859e75597a20b8400 100644 (file)
--- a/ppc.ld
+++ b/ppc.ld
@@ -79,36 +79,34 @@ SECTIONS
   }
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000);
   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table .gcc_except_table.*) }
   /* Thread Local Storage sections  */
   .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors          :
   {
index dea0dbda21c29b0e2377d937dfb0d1ae3b5dd814..0059ee53acea5ca2607500537c6e9fedfe6d6ca3 100644 (file)
--- a/ppc64.ld
+++ b/ppc64.ld
@@ -81,14 +81,12 @@ SECTIONS
   .sdata2         : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) }
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { KEEP (*(.gcc_except_table))
 *(.gcc_except_table.*) } /* Adjust the address for the data segment.  We want to
 adjust up to +     the same address within the page on the next page up.  */
   . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN
 (0x10000, 0x1000);   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { KEEP (*(.gcc_except_table))
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { KEEP (*(.gcc_except_table))
 *(.gcc_except_table.*) }   /* Thread Local Storage sections  */
   .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
index 1eb6b9a70972e083e9d5e6aaeae3b04490bbeb3e..7a7854fd06ff92cf4a41dc498634f9b95e3d70c5 100644 (file)
@@ -55,7 +55,8 @@ static QemuOptsList qemu_drive_opts = {
         },{
             .name = "cache",
             .type = QEMU_OPT_STRING,
-            .help = "host cache usage (none, writeback, writethrough, unsafe)",
+            .help = "host cache usage (none, writeback, writethrough, "
+                    "directsync, unsafe)",
         },{
             .name = "aio",
             .type = QEMU_OPT_STRING,
@@ -302,20 +303,21 @@ static QemuOptsList qemu_mon_opts = {
     },
 };
 
-#ifdef CONFIG_SIMPLE_TRACE
 static QemuOptsList qemu_trace_opts = {
     .name = "trace",
     .implied_opt_name = "trace",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
     .desc = {
         {
+            .name = "events",
+            .type = QEMU_OPT_STRING,
+        },{
             .name = "file",
             .type = QEMU_OPT_STRING,
         },
         { /* end of list */ }
     },
 };
-#endif
 
 static QemuOptsList qemu_cpudef_opts = {
     .name = "cpudef",
@@ -516,9 +518,7 @@ static QemuOptsList *vm_config_groups[32] = {
     &qemu_global_opts,
     &qemu_mon_opts,
     &qemu_cpudef_opts,
-#ifdef CONFIG_SIMPLE_TRACE
     &qemu_trace_opts,
-#endif
     &qemu_option_rom_opts,
     &qemu_machine_opts,
     &qemu_boot_opts,
index a80f437c595b7132544323fa8f664d648d54981e..2a385a3bb8f510bd817273bb5f7a2067d423b1ee 100644 (file)
@@ -115,3 +115,47 @@ void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex)
 
     trace_qemu_co_mutex_unlock_return(mutex, self);
 }
+
+void qemu_co_rwlock_init(CoRwlock *lock)
+{
+    memset(lock, 0, sizeof(*lock));
+    qemu_co_queue_init(&lock->queue);
+}
+
+void qemu_co_rwlock_rdlock(CoRwlock *lock)
+{
+    while (lock->writer) {
+        qemu_co_queue_wait(&lock->queue);
+    }
+    lock->reader++;
+}
+
+void qemu_co_rwlock_unlock(CoRwlock *lock)
+{
+    assert(qemu_in_coroutine());
+    if (lock->writer) {
+        lock->writer = false;
+        while (!qemu_co_queue_empty(&lock->queue)) {
+            /*
+             * Wakeup every body. This will include some
+             * writers too.
+             */
+            qemu_co_queue_next(&lock->queue);
+        }
+    } else {
+        lock->reader--;
+        assert(lock->reader >= 0);
+        /* Wakeup only one waiting writer */
+        if (!lock->reader) {
+            qemu_co_queue_next(&lock->queue);
+        }
+    }
+}
+
+void qemu_co_rwlock_wrlock(CoRwlock *lock)
+{
+    while (lock->writer || lock->reader) {
+        qemu_co_queue_wait(&lock->queue);
+    }
+    lock->writer = true;
+}
index 2f2fd9555236e275c1aa7d213dd89e71b75777a4..b8fc4f43328c0b5e482bd425888d7c2a599b1e35 100644 (file)
@@ -156,4 +156,36 @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
  */
 void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
 
+typedef struct CoRwlock {
+    bool writer;
+    int reader;
+    CoQueue queue;
+} CoRwlock;
+
+/**
+ * Initialises a CoRwlock. This must be called before any other operation
+ * is used on the CoRwlock
+ */
+void qemu_co_rwlock_init(CoRwlock *lock);
+
+/**
+ * Read locks the CoRwlock. If the lock cannot be taken immediately because
+ * of a parallel writer, control is transferred to the caller of the current
+ * coroutine.
+ */
+void qemu_co_rwlock_rdlock(CoRwlock *lock);
+
+/**
+ * Write Locks the mutex. If the lock cannot be taken immediately because
+ * of a parallel reader, control is transferred to the caller of the current
+ * coroutine.
+ */
+void qemu_co_rwlock_wrlock(CoRwlock *lock);
+
+/**
+ * Unlocks the read/write lock and schedules the next coroutine that was
+ * waiting for this lock to be run.
+ */
+void qemu_co_rwlock_unlock(CoRwlock *lock);
+
 #endif /* QEMU_COROUTINE_H */
index 858d75a361df9f5e39accdee2020ad09496657bf..49320133c6edbe72817aaa1f63f44b9fb6b488db 100644 (file)
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -51,7 +51,7 @@ static struct GAState *ga_state;
 
 static void quit_handler(int sig)
 {
-    g_debug("recieved signal num %d, quitting", sig);
+    g_debug("received signal num %d, quitting", sig);
 
     if (g_main_loop_is_running(ga_state->main_loop)) {
         g_main_loop_quit(ga_state->main_loop);
index 1299e83ef2ec2ff267662b1f0d1b784d06b4e165..4be00a5eddd7383834fc801c66aaf1a9d19e6321 100644 (file)
@@ -28,9 +28,9 @@ STEXI
 ETEXI
 
 DEF("convert", img_convert,
-    "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
+    "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
 STEXI
-@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
 DEF("info", img_info,
index 95f3219571c43af676a735d37088c76d0f33fc26..6a3973163f82f483b6b627a9f97bd4314d8cdea4 100644 (file)
@@ -66,7 +66,8 @@ static void help(void)
            "  'filename' is a disk image filename\n"
            "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
            "  'cache' is the cache mode used to write the output disk image, the valid\n"
-           "    options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
+           "    options are: 'none', 'writeback' (default), 'writethrough', 'directsync'\n"
+           "    and 'unsafe'\n"
            "  'size' is the disk image size in bytes. Optional suffixes\n"
            "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
            "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
@@ -81,6 +82,8 @@ static void help(void)
            "       rebasing in this case (useful for renaming the backing file)\n"
            "  '-h' with or without a command shows this help and lists the supported formats\n"
            "  '-p' show progress of command (only certain commands)\n"
+           "  '-S' indicates the consecutive number of bytes that must contain only zeros\n"
+           "       for qemu-img to create a sparse image during conversion\n"
            "\n"
            "Parameters to snapshot subcommand:\n"
            "  'snapshot' is the name of the snapshot to create, apply or delete\n"
@@ -183,27 +186,6 @@ static int read_password(char *buf, int buf_size)
 }
 #endif
 
-static int set_cache_flag(const char *mode, int *flags)
-{
-    *flags &= ~BDRV_O_CACHE_MASK;
-
-    if (!strcmp(mode, "none") || !strcmp(mode, "off")) {
-        *flags |= BDRV_O_CACHE_WB;
-        *flags |= BDRV_O_NOCACHE;
-    } else if (!strcmp(mode, "writeback")) {
-        *flags |= BDRV_O_CACHE_WB;
-    } else if (!strcmp(mode, "unsafe")) {
-        *flags |= BDRV_O_CACHE_WB;
-        *flags |= BDRV_O_NO_FLUSH;
-    } else if (!strcmp(mode, "writethrough")) {
-        /* this is the default */
-    } else {
-        return -1;
-    }
-
-    return 0;
-}
-
 static int print_block_option_help(const char *filename, const char *fmt)
 {
     BlockDriver *drv, *proto_drv;
@@ -495,7 +477,7 @@ static int img_commit(int argc, char **argv)
     filename = argv[optind++];
 
     flags = BDRV_O_RDWR;
-    ret = set_cache_flag(cache, &flags);
+    ret = bdrv_parse_cache_flags(cache, &flags);
     if (ret < 0) {
         error_report("Invalid cache option: %s", cache);
         return -1;
@@ -590,6 +572,48 @@ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
     return v;
 }
 
+/*
+ * Like is_allocated_sectors, but if the buffer starts with a used sector,
+ * up to 'min' consecutive sectors containing zeros are ignored. This avoids
+ * breaking up write requests for only small sparse areas.
+ */
+static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
+    int min)
+{
+    int ret;
+    int num_checked, num_used;
+
+    if (n < min) {
+        min = n;
+    }
+
+    ret = is_allocated_sectors(buf, n, pnum);
+    if (!ret) {
+        return ret;
+    }
+
+    num_used = *pnum;
+    buf += BDRV_SECTOR_SIZE * *pnum;
+    n -= *pnum;
+    num_checked = num_used;
+
+    while (n > 0) {
+        ret = is_allocated_sectors(buf, n, pnum);
+
+        buf += BDRV_SECTOR_SIZE * *pnum;
+        n -= *pnum;
+        num_checked += *pnum;
+        if (ret) {
+            num_used = num_checked;
+        } else if (*pnum >= min) {
+            break;
+        }
+    }
+
+    *pnum = num_used;
+    return 1;
+}
+
 /*
  * Compares two buffers sector by sector. Returns 0 if the first sector of both
  * buffers matches, non-zero otherwise.
@@ -640,6 +664,7 @@ static int img_convert(int argc, char **argv)
     char *options = NULL;
     const char *snapshot_name = NULL;
     float local_progress;
+    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
 
     fmt = NULL;
     out_fmt = "raw";
@@ -647,7 +672,7 @@ static int img_convert(int argc, char **argv)
     out_baseimg = NULL;
     compress = 0;
     for(;;) {
-        c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
+        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
         if (c == -1) {
             break;
         }
@@ -682,6 +707,18 @@ static int img_convert(int argc, char **argv)
         case 's':
             snapshot_name = optarg;
             break;
+        case 'S':
+        {
+            int64_t sval;
+            sval = strtosz_suffix(optarg, NULL, STRTOSZ_DEFSUFFIX_B);
+            if (sval < 0) {
+                error_report("Invalid minimum zero buffer size for sparse output specified");
+                return 1;
+            }
+
+            min_sparse = sval / BDRV_SECTOR_SIZE;
+            break;
+        }
         case 'p':
             progress = 1;
             break;
@@ -819,7 +856,7 @@ static int img_convert(int argc, char **argv)
     }
 
     flags = BDRV_O_RDWR;
-    ret = set_cache_flag(cache, &flags);
+    ret = bdrv_parse_cache_flags(cache, &flags);
     if (ret < 0) {
         error_report("Invalid cache option: %s", cache);
         return -1;
@@ -834,7 +871,7 @@ static int img_convert(int argc, char **argv)
     bs_i = 0;
     bs_offset = 0;
     bdrv_get_geometry(bs[0], &bs_sectors);
-    buf = g_malloc(IO_BUF_SIZE);
+    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
 
     if (compress) {
         ret = bdrv_get_info(out_bs, &bdi);
@@ -890,7 +927,8 @@ static int img_convert(int argc, char **argv)
 
                 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
                 if (ret < 0) {
-                    error_report("error while reading");
+                    error_report("error while reading sector %" PRId64 ": %s",
+                                 bs_num, strerror(-ret));
                     goto out;
                 }
 
@@ -908,8 +946,8 @@ static int img_convert(int argc, char **argv)
                 ret = bdrv_write_compressed(out_bs, sector_num, buf,
                                             cluster_sectors);
                 if (ret != 0) {
-                    error_report("error while compressing sector %" PRId64,
-                          sector_num);
+                    error_report("error while compressing sector %" PRId64
+                                 ": %s", sector_num, strerror(-ret));
                     goto out;
                 }
             }
@@ -972,7 +1010,8 @@ static int img_convert(int argc, char **argv)
 
             ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
             if (ret < 0) {
-                error_report("error while reading");
+                error_report("error while reading sector %" PRId64 ": %s",
+                             sector_num - bs_offset, strerror(-ret));
                 goto out;
             }
             /* NOTE: at the same time we convert, we do not write zero
@@ -988,10 +1027,11 @@ static int img_convert(int argc, char **argv)
                    sectors that are entirely 0, since whatever data was
                    already there is garbage, not 0s. */
                 if (!has_zero_init || out_baseimg ||
-                    is_allocated_sectors(buf1, n, &n1)) {
+                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
                     ret = bdrv_write(out_bs, sector_num, buf1, n1);
                     if (ret < 0) {
-                        error_report("error while writing");
+                        error_report("error while writing sector %" PRId64
+                                     ": %s", sector_num, strerror(-ret));
                         goto out;
                     }
                 }
@@ -1006,7 +1046,7 @@ out:
     qemu_progress_end();
     free_option_parameters(create_options);
     free_option_parameters(param);
-    g_free(buf);
+    qemu_vfree(buf);
     if (out_bs) {
         bdrv_delete(out_bs);
     }
@@ -1291,7 +1331,7 @@ static int img_rebase(int argc, char **argv)
     qemu_progress_print(0, 100);
 
     flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
-    ret = set_cache_flag(cache, &flags);
+    ret = bdrv_parse_cache_flags(cache, &flags);
     if (ret < 0) {
         error_report("Invalid cache option: %s", cache);
         return -1;
@@ -1373,8 +1413,8 @@ static int img_rebase(int argc, char **argv)
         uint8_t * buf_new;
         float local_progress;
 
-        buf_old = g_malloc(IO_BUF_SIZE);
-        buf_new = g_malloc(IO_BUF_SIZE);
+        buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
+        buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
 
         bdrv_get_geometry(bs, &num_sectors);
 
@@ -1430,8 +1470,8 @@ static int img_rebase(int argc, char **argv)
             qemu_progress_print(local_progress, 100);
         }
 
-        g_free(buf_old);
-        g_free(buf_new);
+        qemu_vfree(buf_old);
+        qemu_vfree(buf_new);
     }
 
     /*
index 495a1b66954b0eea22f74d0bbe57c22806a3a0aa..70fa321dff50734958a7674efc231358ca0028f8 100644 (file)
@@ -40,6 +40,11 @@ indicates that target image must be compressed (qcow format only)
 with or without a command shows help and lists the supported formats
 @item -p
 display progress bar (convert and rebase commands only)
+@item -S @var{size}
+indicates the consecutive number of bytes that must contain only zeros
+for qemu-img to create a sparse image during conversion. This value is rounded
+down to the nearest 512 bytes. You may use the common size suffixes like
+@code{k} for kilobytes.
 @end table
 
 Parameters to snapshot subcommand:
@@ -86,7 +91,7 @@ it doesn't need to be specified separately in this case.
 
 Commit the changes recorded in @var{filename} in its base image.
 
-@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 
 Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
 using format @var{output_fmt}. It can be optionally compressed (@code{-c}
index d86815dc04050cf0b0c9377c075e587d8a3265e2..659ecb2db7eef01b580d75193826a19de0f67702 100644 (file)
@@ -133,7 +133,7 @@ ETEXI
 DEF("drive", HAS_ARG, QEMU_OPTION_drive,
     "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
     "       [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
-    "       [,cache=writethrough|writeback|none|unsafe][,format=f]\n"
+    "       [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
     "       [,serial=s][,addr=A][,id=name][,aio=threads|native]\n"
     "       [,readonly=on|off]\n"
     "                use 'file' as a drive image\n", QEMU_ARCH_ALL)
@@ -164,7 +164,7 @@ These options have the same definition as they have in @option{-hdachs}.
 @item snapshot=@var{snapshot}
 @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}).
 @item cache=@var{cache}
-@var{cache} is "none", "writeback", "unsafe", or "writethrough" and controls how the host cache is used to access block data.
+@var{cache} is "none", "writeback", "unsafe", "directsync" or "writethrough" and controls how the host cache is used to access block data.
 @item aio=@var{aio}
 @var{aio} is "threads", or "native" and selects between pthread based disk I/O and native Linux AIO.
 @item format=@var{format}
@@ -199,6 +199,10 @@ The host page cache can be avoided entirely with @option{cache=none}.  This will
 attempt to do disk IO directly to the guests memory.  QEMU may still perform
 an internal copy of the data.
 
+The host page cache can be avoided while only sending write notifications to
+the guest when the data has been reported as written by the storage subsystem
+using @option{cache=directsync}.
+
 Some block drivers perform badly with @option{cache=writethrough}, most notably,
 qcow2.  If performance is more important than correctness,
 @option{cache=writeback} should be used with qcow2.
@@ -1273,9 +1277,9 @@ or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000).
 
 Then @file{@var{dir}} can be accessed in @file{\\smbserver\qemu}.
 
-Note that a SAMBA server must be installed on the host OS in
-@file{/usr/sbin/smbd}. QEMU was tested successfully with smbd versions from
-Red Hat 9, Fedora Core 3 and OpenSUSE 11.x.
+Note that a SAMBA server must be installed on the host OS.
+QEMU was tested successfully with smbd versions from Red Hat 9,
+Fedora Core 3 and OpenSUSE 11.x.
 
 @item hostfwd=[tcp|udp]:[@var{hostaddr}]:@var{hostport}-[@var{guestaddr}]:@var{guestport}
 Redirect incoming TCP or UDP connections to the host port @var{hostport} to
@@ -2432,17 +2436,32 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
 @var{sysconfdir}/target-@var{ARCH}.conf on startup.  The @code{-nodefconfig}
 option will prevent QEMU from loading these configuration files at startup.
 ETEXI
-#ifdef CONFIG_SIMPLE_TRACE
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
-    "-trace\n"
-    "                Specify a trace file to log traces to\n",
+    "-trace [events=<file>][,file=<file>]\n"
+    "                specify tracing options\n",
     QEMU_ARCH_ALL)
 STEXI
-@item -trace
+HXCOMM This line is not accurate, as some sub-options are backend-specific but
+HXCOMM HX does not support conditional compilation of text.
+@item -trace [events=@var{file}][,file=@var{file}]
 @findex -trace
-Specify a trace file to log output traces to.
+
+Specify tracing options.
+
+@table @option
+@item events=@var{file}
+Immediately enable events listed in @var{file}.
+The file must contain one event name (as listed in the @var{trace-events} file)
+per line.
+
+This option is only available when using the @var{simple} and @var{stderr}
+tracing backends.
+@item file=@var{file}
+Log output traces to @var{file}.
+
+This option is only available when using the @var{simple} tracing backend.
+@end table
 ETEXI
-#endif
 
 HXCOMM This is the last statement. Insert new options before this line!
 STEXI
index 19313d3b009e954f97c06f50832b209fcdcd526a..46dd483fdd2c1719d62659d01a054578b526c03e 100644 (file)
@@ -101,22 +101,6 @@ static int64_t cpu_get_clock(void)
     }
 }
 
-#ifndef CONFIG_IOTHREAD
-static int64_t qemu_icount_delta(void)
-{
-    if (!use_icount) {
-        return 5000 * (int64_t) 1000000;
-    } else if (use_icount == 1) {
-        /* When not using an adaptive execution frequency
-           we tend to get badly out of sync with real time,
-           so just delay for a reasonable amount of time.  */
-        return 0;
-    } else {
-        return cpu_get_icount() - cpu_get_clock();
-    }
-}
-#endif
-
 /* enable cpu_get_ticks() */
 void cpu_enable_ticks(void)
 {
@@ -688,9 +672,7 @@ void configure_icount(const char *option)
     if (!option)
         return;
 
-#ifdef CONFIG_IOTHREAD
     vm_clock->warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL);
-#endif
 
     if (strcmp(option, "auto") != 0) {
         icount_time_shift = strtol(option, NULL, 0);
@@ -1178,41 +1160,6 @@ void quit_timers(void)
 
 int qemu_calculate_timeout(void)
 {
-#ifndef CONFIG_IOTHREAD
-    int timeout;
-
-    if (!vm_running)
-        timeout = 5000;
-    else {
-     /* XXX: use timeout computed from timers */
-        int64_t add;
-        int64_t delta;
-        /* Advance virtual time to the next event.  */
-       delta = qemu_icount_delta();
-        if (delta > 0) {
-            /* If virtual time is ahead of real time then just
-               wait for IO.  */
-            timeout = (delta + 999999) / 1000000;
-        } else {
-            /* Wait for either IO to occur or the next
-               timer event.  */
-            add = qemu_next_icount_deadline();
-            /* We advance the timer before checking for IO.
-               Limit the amount we advance so that early IO
-               activity won't get the guest too far ahead.  */
-            if (add > 10000000)
-                add = 10000000;
-            delta += add;
-            qemu_icount += qemu_icount_round (add);
-            timeout = delta / 1000000;
-            if (timeout < 0)
-                timeout = 0;
-        }
-    }
-
-    return timeout;
-#else /* CONFIG_IOTHREAD */
     return 1000;
-#endif
 }
 
index 03f67da19826d93835ced726dd89d4885847d287..27cc66ebc95845dc124272f8ba3e72378dbe2aeb 100644 (file)
@@ -1201,6 +1201,10 @@ Each json-object contain the following:
     - "wr_bytes": bytes written (json-int)
     - "rd_operations": read operations (json-int)
     - "wr_operations": write operations (json-int)
+    - "flush_operations": cache flush operations (json-int)
+    - "wr_total_time_ns": total time spend on writes in nano-seconds (json-int)
+    - "rd_total_time_ns": total time spend on reads in nano-seconds (json-int)
+    - "flush_total_time_ns": total time spend on cache flushes in nano-seconds (json-int)
     - "wr_highest_offset": Highest offset of a sector written since the
                            BlockDriverState has been opened (json-int)
 - "parent": Contains recursively the statistics of the underlying
@@ -1222,6 +1226,10 @@ Example:
                   "wr_operations":751,
                   "rd_bytes":122567168,
                   "rd_operations":36772
+                  "wr_total_times_ns":313253456
+                  "rd_total_times_ns":3465673657
+                  "flush_total_times_ns":49653
+                  "flush_operations":61,
                }
             },
             "stats":{
@@ -1230,6 +1238,10 @@ Example:
                "wr_operations":692,
                "rd_bytes":122739200,
                "rd_operations":36604
+               "flush_operations":51,
+               "wr_total_times_ns":313253456
+               "rd_total_times_ns":3465673657
+               "flush_total_times_ns":49653
             }
          },
          {
@@ -1240,6 +1252,10 @@ Example:
                "wr_operations":0,
                "rd_bytes":0,
                "rd_operations":0
+               "flush_operations":0,
+               "wr_total_times_ns":0
+               "rd_total_times_ns":0
+               "flush_total_times_ns":0
             }
          },
          {
@@ -1250,6 +1266,10 @@ Example:
                "wr_operations":0,
                "rd_bytes":0,
                "rd_operations":0
+               "flush_operations":0,
+               "wr_total_times_ns":0
+               "rd_total_times_ns":0
+               "flush_total_times_ns":0
             }
          },
          {
@@ -1260,6 +1280,10 @@ Example:
                "wr_operations":0,
                "rd_bytes":0,
                "rd_operations":0
+               "flush_operations":0,
+               "wr_total_times_ns":0
+               "rd_total_times_ns":0
+               "flush_total_times_ns":0
             }
          }
       ]
index 884d421ae4dc2f8fc4fb9ab9c7173550354f0629..04a91983ec26e6d398f01a2780663c7e2cac729f 100644 (file)
--- a/rules.mak
+++ b/rules.mak
@@ -31,7 +31,7 @@ endif
 %.o: %.m
        $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
 
-LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(LIBS),"  LINK  $(TARGET_DIR)$@")
+LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(sort $(1)) $(LIBS),"  LINK  $(TARGET_DIR)$@")
 
 %$(EXESUF): %.o
        $(call LINK,$^)
diff --git a/rwhandler.c b/rwhandler.c
new file mode 100644 (file)
index 0000000..bb2238f
--- /dev/null
@@ -0,0 +1,87 @@
+#include "rwhandler.h"
+#include "ioport.h"
+#include "cpu-all.h"
+
+#define RWHANDLER_WRITE(name, len, type) \
+static void name(void *opaque, type addr, uint32_t value) \
+{\
+    struct ReadWriteHandler *handler = opaque;\
+    handler->write(handler, addr, value, len);\
+}
+
+#define RWHANDLER_READ(name, len, type) \
+static uint32_t name(void *opaque, type addr) \
+{ \
+    struct ReadWriteHandler *handler = opaque; \
+    return handler->read(handler, addr, len); \
+}
+
+RWHANDLER_WRITE(cpu_io_memory_simple_writeb, 1, target_phys_addr_t);
+RWHANDLER_READ(cpu_io_memory_simple_readb, 1, target_phys_addr_t);
+RWHANDLER_WRITE(cpu_io_memory_simple_writew, 2, target_phys_addr_t);
+RWHANDLER_READ(cpu_io_memory_simple_readw, 2, target_phys_addr_t);
+RWHANDLER_WRITE(cpu_io_memory_simple_writel, 4, target_phys_addr_t);
+RWHANDLER_READ(cpu_io_memory_simple_readl, 4, target_phys_addr_t);
+
+static CPUWriteMemoryFunc * const cpu_io_memory_simple_write[] = {
+    &cpu_io_memory_simple_writeb,
+    &cpu_io_memory_simple_writew,
+    &cpu_io_memory_simple_writel,
+};
+
+static CPUReadMemoryFunc * const cpu_io_memory_simple_read[] = {
+    &cpu_io_memory_simple_readb,
+    &cpu_io_memory_simple_readw,
+    &cpu_io_memory_simple_readl,
+};
+
+int cpu_register_io_memory_simple(struct ReadWriteHandler *handler, int endian)
+{
+    if (!handler->read || !handler->write) {
+        return -1;
+    }
+    return cpu_register_io_memory(cpu_io_memory_simple_read,
+                                  cpu_io_memory_simple_write,
+                                  handler, endian);
+}
+
+RWHANDLER_WRITE(ioport_simple_writeb, 1, uint32_t);
+RWHANDLER_READ(ioport_simple_readb, 1, uint32_t);
+RWHANDLER_WRITE(ioport_simple_writew, 2, uint32_t);
+RWHANDLER_READ(ioport_simple_readw, 2, uint32_t);
+RWHANDLER_WRITE(ioport_simple_writel, 4, uint32_t);
+RWHANDLER_READ(ioport_simple_readl, 4, uint32_t);
+
+int register_ioport_simple(ReadWriteHandler* handler,
+                           pio_addr_t start, int length, int size)
+{
+    IOPortWriteFunc *write;
+    IOPortReadFunc *read;
+    int r;
+    switch (size) {
+    case 1:
+        write = ioport_simple_writeb;
+        read = ioport_simple_readb;
+        break;
+    case 2:
+        write = ioport_simple_writew;
+        read = ioport_simple_readw;
+        break;
+    default:
+        write = ioport_simple_writel;
+        read = ioport_simple_readl;
+    }
+    if (handler->write) {
+        r = register_ioport_write(start, length, size, write, handler);
+        if (r < 0) {
+            return r;
+        }
+    }
+    if (handler->read) {
+        r = register_ioport_read(start, length, size, read, handler);
+        if (r < 0) {
+            return r;
+        }
+    }
+    return 0;
+}
diff --git a/rwhandler.h b/rwhandler.h
new file mode 100644 (file)
index 0000000..b2a5790
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef READ_WRITE_HANDLER_H
+#define READ_WRITE_HANDLER_H
+
+#include "qemu-common.h"
+#include "ioport.h"
+
+typedef struct ReadWriteHandler ReadWriteHandler;
+
+/* len is guaranteed to be one of 1, 2 or 4, addr is guaranteed to fit in an
+ * appropriate type (io/memory/etc). They do not need to be range checked. */
+typedef void WriteHandlerFunc(ReadWriteHandler *, pcibus_t addr,
+                              uint32_t value, int len);
+typedef uint32_t ReadHandlerFunc(ReadWriteHandler *, pcibus_t addr, int len);
+
+struct ReadWriteHandler {
+    WriteHandlerFunc *write;
+    ReadHandlerFunc *read;
+};
+
+/* Helpers for when we want to use a single routine with length. */
+/* CPU memory handler: both read and write must be present. */
+int cpu_register_io_memory_simple(ReadWriteHandler *, int endian);
+/* io port handler: can supply only read or write handlers. */
+int register_ioport_simple(ReadWriteHandler *,
+                           pio_addr_t start, int length, int size);
+
+#endif
index 3498425fff68fe48292df2115177deb97e3bbb3d..0eba357cc2105be70a7738601be552801bc5b5bd 100755 (executable)
@@ -2532,7 +2532,7 @@ sub process {
                                                $allowed = 1;
                                        }
                                }
-                               if (!$seen) {
+                               if ($seen != ($#chunks + 1)) {
                                        WARN("braces {} are necessary for all arms of this statement\n" . $herectx);
                                }
                        }
index 2ad56998ee67ca2e9d43beba3d8b25f1c06dd69b..f55e5e63f9f0c28a65b09ba743adb75eaad617a5 100755 (executable)
@@ -102,10 +102,10 @@ def process(events, log, analyzer):
         fn_argcount = len(inspect.getargspec(fn)[0]) - 1
         if fn_argcount == event_argcount + 1:
             # Include timestamp as first argument
-            return lambda _, rec: fn(*rec[1:2 + fn_argcount])
+            return lambda _, rec: fn(*rec[1:2 + event_argcount])
         else:
             # Just arguments, no timestamp
-            return lambda _, rec: fn(*rec[2:2 + fn_argcount])
+            return lambda _, rec: fn(*rec[2:2 + event_argcount])
 
     analyzer.begin()
     fn_cache = {}
index 2155a57df2a02d3ec58321c544cf658245f25dae..743d2462893c8626bd4b72f4e6bd87544dab61cd 100755 (executable)
@@ -43,7 +43,26 @@ EOF
 # Get the name of a trace event
 get_name()
 {
-    echo ${1%%\(*}
+    local name
+    name=${1%%\(*}
+    echo "${name##* }"
+}
+
+# Get the given property of a trace event
+# 1: trace-events line
+# 2: property name
+# -> return 0 if property is present, or 1 otherwise
+has_property()
+{
+    local props prop
+    props=${1%%\(*}
+    props=${props% *}
+    for prop in $props; do
+        if [ "$prop" = "$2" ]; then
+            return 0
+        fi
+    done
+    return 1
 }
 
 # Get the argument list of a trace event, including types and names
@@ -101,20 +120,6 @@ get_fmt()
     echo "$fmt"
 }
 
-# Get the state of a trace event
-get_state()
-{
-    local str disable state
-    str=$(get_name "$1")
-    disable=${str##disable }
-    if [ "$disable" = "$str" ] ; then
-        state=1
-    else
-        state=0
-    fi
-    echo "$state"
-}
-
 linetoh_begin_nop()
 {
     return
@@ -158,7 +163,7 @@ linetoc_end_nop()
 linetoh_begin_simple()
 {
     cat <<EOF
-#include "simpletrace.h"
+#include "trace/simple.h"
 EOF
 
     simple_event_num=0
@@ -174,14 +179,10 @@ cast_args_to_uint64_t()
 
 linetoh_simple()
 {
-    local name args argc trace_args state
+    local name args argc trace_args
     name=$(get_name "$1")
     args=$(get_args "$1")
     argc=$(get_argc "$1")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ]; then
-        name=${name##disable }
-    fi
 
     trace_args="$simple_event_num"
     if [ "$argc" -gt 0 ]
@@ -220,14 +221,10 @@ EOF
 
 linetoc_simple()
 {
-    local name state
+    local name
     name=$(get_name "$1")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
-    fi
     cat <<EOF
-{.tp_name = "$name", .state=$state},
+{.tp_name = "$name", .state=0},
 EOF
     simple_event_num=$((simple_event_num + 1))
 }
@@ -244,7 +241,12 @@ linetoh_begin_stderr()
 {
     cat <<EOF
 #include <stdio.h>
+#include "trace/stderr.h"
+
+extern TraceEvent trace_list[];
 EOF
+
+    stderr_event_num=0
 }
 
 linetoh_stderr()
@@ -263,29 +265,47 @@ linetoh_stderr()
     cat <<EOF
 static inline void trace_$name($args)
 {
-    fprintf(stderr, "$name $fmt\n" $argnames);
+    if (trace_list[$stderr_event_num].state != 0) {
+        fprintf(stderr, "$name $fmt\n" $argnames);
+    }
 }
 EOF
+    stderr_event_num=$((stderr_event_num + 1))
+
 }
 
 linetoh_end_stderr()
 {
-return
+    cat <<EOF
+#define NR_TRACE_EVENTS $stderr_event_num
+EOF
 }
 
 linetoc_begin_stderr()
 {
-return
+    cat <<EOF
+#include "trace.h"
+
+TraceEvent trace_list[] = {
+EOF
+    stderr_event_num=0
 }
 
 linetoc_stderr()
 {
-return
+    local name
+    name=$(get_name "$1")
+    cat <<EOF
+{.tp_name = "$name", .state=0},
+EOF
+    stderr_event_num=$(($stderr_event_num + 1))
 }
 
 linetoc_end_stderr()
 {
-return
+    cat <<EOF
+};
+EOF
 }
 #END OF STDERR
 
@@ -379,14 +399,10 @@ EOF
 
 linetoh_dtrace()
 {
-    local name args argnames state nameupper
+    local name args argnames nameupper
     name=$(get_name "$1")
     args=$(get_args "$1")
     argnames=$(get_argnames "$1", ",")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
-    fi
 
     nameupper=`echo $name | tr '[:lower:]' '[:upper:]'`
 
@@ -430,13 +446,9 @@ EOF
 
 linetod_dtrace()
 {
-    local name args state
+    local name args
     name=$(get_name "$1")
     args=$(get_args "$1")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
-    fi
 
     # DTrace provider syntax expects foo() for empty
     # params, not foo(void)
@@ -464,14 +476,10 @@ linetostap_begin_dtrace()
 
 linetostap_dtrace()
 {
-    local i arg name args arglist state
+    local i arg name args arglist
     name=$(get_name "$1")
     args=$(get_args "$1")
     arglist=$(get_argnames "$1", "")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
-    fi
 
     # Define prototype for probe arguments
     cat <<EOF
@@ -516,18 +524,10 @@ convert()
         # Skip comments and empty lines
         test -z "${str%%#*}" && continue
 
-        # Process the line.  The nop backend handles disabled lines.
-        disable=${str%%disable *}
         echo
-        if test -z "$disable"; then
-            # Pass the disabled state as an arg for the simple
-            # or DTrace backends which handle it dynamically.
-            # For all other backends, call lineto$1_nop()
-            if [ $backend = "simple" -o "$backend" = "dtrace" ]; then
-                "$process_line" "$str"
-            else
-                "lineto$1_nop" "${str##disable }"
-            fi
+        # Process the line.  The nop backend handles disabled lines.
+        if has_property "$str" "disable"; then
+            "lineto$1_nop" "$str"
         else
             "$process_line" "$str"
         fi
diff --git a/simpletrace.c b/simpletrace.c
deleted file mode 100644 (file)
index de355e9..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Simple trace backend
- *
- * Copyright IBM, Corp. 2010
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <time.h>
-#include <signal.h>
-#include <pthread.h>
-#include "qemu-timer.h"
-#include "trace.h"
-
-/** Trace file header event ID */
-#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
-
-/** Trace file magic number */
-#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL
-
-/** Trace file version number, bump if format changes */
-#define HEADER_VERSION 0
-
-/** Records were dropped event ID */
-#define DROPPED_EVENT_ID (~(uint64_t)0 - 1)
-
-/** Trace record is valid */
-#define TRACE_RECORD_VALID ((uint64_t)1 << 63)
-
-/** Trace buffer entry */
-typedef struct {
-    uint64_t event;
-    uint64_t timestamp_ns;
-    uint64_t x1;
-    uint64_t x2;
-    uint64_t x3;
-    uint64_t x4;
-    uint64_t x5;
-    uint64_t x6;
-} TraceRecord;
-
-enum {
-    TRACE_BUF_LEN = 4096,
-    TRACE_BUF_FLUSH_THRESHOLD = TRACE_BUF_LEN / 4,
-};
-
-/*
- * Trace records are written out by a dedicated thread.  The thread waits for
- * records to become available, writes them out, and then waits again.
- */
-static pthread_mutex_t trace_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t trace_available_cond = PTHREAD_COND_INITIALIZER;
-static pthread_cond_t trace_empty_cond = PTHREAD_COND_INITIALIZER;
-static bool trace_available;
-static bool trace_writeout_enabled;
-
-static TraceRecord trace_buf[TRACE_BUF_LEN];
-static unsigned int trace_idx;
-static FILE *trace_fp;
-static char *trace_file_name = NULL;
-
-/**
- * Read a trace record from the trace buffer
- *
- * @idx         Trace buffer index
- * @record      Trace record to fill
- *
- * Returns false if the record is not valid.
- */
-static bool get_trace_record(unsigned int idx, TraceRecord *record)
-{
-    if (!(trace_buf[idx].event & TRACE_RECORD_VALID)) {
-        return false;
-    }
-
-    __sync_synchronize(); /* read memory barrier before accessing record */
-
-    *record = trace_buf[idx];
-    record->event &= ~TRACE_RECORD_VALID;
-    return true;
-}
-
-/**
- * Kick writeout thread
- *
- * @wait        Whether to wait for writeout thread to complete
- */
-static void flush_trace_file(bool wait)
-{
-    pthread_mutex_lock(&trace_lock);
-    trace_available = true;
-    pthread_cond_signal(&trace_available_cond);
-
-    if (wait) {
-        pthread_cond_wait(&trace_empty_cond, &trace_lock);
-    }
-
-    pthread_mutex_unlock(&trace_lock);
-}
-
-static void wait_for_trace_records_available(void)
-{
-    pthread_mutex_lock(&trace_lock);
-    while (!(trace_available && trace_writeout_enabled)) {
-        pthread_cond_signal(&trace_empty_cond);
-        pthread_cond_wait(&trace_available_cond, &trace_lock);
-    }
-    trace_available = false;
-    pthread_mutex_unlock(&trace_lock);
-}
-
-static void *writeout_thread(void *opaque)
-{
-    TraceRecord record;
-    unsigned int writeout_idx = 0;
-    unsigned int num_available, idx;
-    size_t unused __attribute__ ((unused));
-
-    for (;;) {
-        wait_for_trace_records_available();
-
-        num_available = trace_idx - writeout_idx;
-        if (num_available > TRACE_BUF_LEN) {
-            record = (TraceRecord){
-                .event = DROPPED_EVENT_ID,
-                .x1 = num_available,
-            };
-            unused = fwrite(&record, sizeof(record), 1, trace_fp);
-            writeout_idx += num_available;
-        }
-
-        idx = writeout_idx % TRACE_BUF_LEN;
-        while (get_trace_record(idx, &record)) {
-            trace_buf[idx].event = 0; /* clear valid bit */
-            unused = fwrite(&record, sizeof(record), 1, trace_fp);
-            idx = ++writeout_idx % TRACE_BUF_LEN;
-        }
-
-        fflush(trace_fp);
-    }
-    return NULL;
-}
-
-static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
-                  uint64_t x4, uint64_t x5, uint64_t x6)
-{
-    unsigned int idx;
-    uint64_t timestamp;
-
-    if (!trace_list[event].state) {
-        return;
-    }
-
-    timestamp = get_clock();
-
-    idx = __sync_fetch_and_add(&trace_idx, 1) % TRACE_BUF_LEN;
-    trace_buf[idx] = (TraceRecord){
-        .event = event,
-        .timestamp_ns = timestamp,
-        .x1 = x1,
-        .x2 = x2,
-        .x3 = x3,
-        .x4 = x4,
-        .x5 = x5,
-        .x6 = x6,
-    };
-    __sync_synchronize(); /* write barrier before marking as valid */
-    trace_buf[idx].event |= TRACE_RECORD_VALID;
-
-    if ((idx + 1) % TRACE_BUF_FLUSH_THRESHOLD == 0) {
-        flush_trace_file(false);
-    }
-}
-
-void trace0(TraceEventID event)
-{
-    trace(event, 0, 0, 0, 0, 0, 0);
-}
-
-void trace1(TraceEventID event, uint64_t x1)
-{
-    trace(event, x1, 0, 0, 0, 0, 0);
-}
-
-void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
-{
-    trace(event, x1, x2, 0, 0, 0, 0);
-}
-
-void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
-{
-    trace(event, x1, x2, x3, 0, 0, 0);
-}
-
-void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
-{
-    trace(event, x1, x2, x3, x4, 0, 0);
-}
-
-void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
-{
-    trace(event, x1, x2, x3, x4, x5, 0);
-}
-
-void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
-{
-    trace(event, x1, x2, x3, x4, x5, x6);
-}
-
-void st_set_trace_file_enabled(bool enable)
-{
-    if (enable == !!trace_fp) {
-        return; /* no change */
-    }
-
-    /* Halt trace writeout */
-    flush_trace_file(true);
-    trace_writeout_enabled = false;
-    flush_trace_file(true);
-
-    if (enable) {
-        static const TraceRecord header = {
-            .event = HEADER_EVENT_ID,
-            .timestamp_ns = HEADER_MAGIC,
-            .x1 = HEADER_VERSION,
-        };
-
-        trace_fp = fopen(trace_file_name, "w");
-        if (!trace_fp) {
-            return;
-        }
-
-        if (fwrite(&header, sizeof header, 1, trace_fp) != 1) {
-            fclose(trace_fp);
-            trace_fp = NULL;
-            return;
-        }
-
-        /* Resume trace writeout */
-        trace_writeout_enabled = true;
-        flush_trace_file(false);
-    } else {
-        fclose(trace_fp);
-        trace_fp = NULL;
-    }
-}
-
-/**
- * Set the name of a trace file
- *
- * @file        The trace file name or NULL for the default name-<pid> set at
- *              config time
- */
-bool st_set_trace_file(const char *file)
-{
-    st_set_trace_file_enabled(false);
-
-    free(trace_file_name);
-
-    if (!file) {
-        if (asprintf(&trace_file_name, CONFIG_TRACE_FILE, getpid()) < 0) {
-            trace_file_name = NULL;
-            return false;
-        }
-    } else {
-        if (asprintf(&trace_file_name, "%s", file) < 0) {
-            trace_file_name = NULL;
-            return false;
-        }
-    }
-
-    st_set_trace_file_enabled(true);
-    return true;
-}
-
-void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
-{
-    stream_printf(stream, "Trace file \"%s\" %s.\n",
-                  trace_file_name, trace_fp ? "on" : "off");
-}
-
-void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
-{
-    unsigned int i;
-
-    for (i = 0; i < TRACE_BUF_LEN; i++) {
-        TraceRecord record;
-
-        if (!get_trace_record(i, &record)) {
-            continue;
-        }
-        stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64
-                      " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n",
-                      record.event, record.x1, record.x2,
-                      record.x3, record.x4, record.x5,
-                      record.x6);
-    }
-}
-
-void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
-{
-    unsigned int i;
-
-    for (i = 0; i < NR_TRACE_EVENTS; i++) {
-        stream_printf(stream, "%s [Event ID %u] : state %u\n",
-                      trace_list[i].tp_name, i, trace_list[i].state);
-    }
-}
-
-bool st_change_trace_event_state(const char *name, bool enabled)
-{
-    unsigned int i;
-
-    for (i = 0; i < NR_TRACE_EVENTS; i++) {
-        if (!strcmp(trace_list[i].tp_name, name)) {
-            trace_list[i].state = enabled;
-            return true;
-        }
-    }
-    return false;
-}
-
-void st_flush_trace_buffer(void)
-{
-    flush_trace_file(true);
-}
-
-bool st_init(const char *file)
-{
-    pthread_t thread;
-    pthread_attr_t attr;
-    sigset_t set, oldset;
-    int ret;
-
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-    sigfillset(&set);
-    pthread_sigmask(SIG_SETMASK, &set, &oldset);
-    ret = pthread_create(&thread, &attr, writeout_thread, NULL);
-    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
-
-    if (ret != 0) {
-        return false;
-    }
-
-    atexit(st_flush_trace_buffer);
-    st_set_trace_file(file);
-    return true;
-}
diff --git a/simpletrace.h b/simpletrace.h
deleted file mode 100644 (file)
index 8d893bd..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Simple trace backend
- *
- * Copyright IBM, Corp. 2010
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef SIMPLETRACE_H
-#define SIMPLETRACE_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-#ifdef CONFIG_SIMPLE_TRACE
-typedef uint64_t TraceEventID;
-
-typedef struct {
-    const char *tp_name;
-    bool state;
-} TraceEvent;
-
-void trace0(TraceEventID event);
-void trace1(TraceEventID event, uint64_t x1);
-void trace2(TraceEventID event, uint64_t x1, uint64_t x2);
-void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3);
-void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
-void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
-void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
-void st_print_trace(FILE *stream, fprintf_function stream_printf);
-void st_print_trace_events(FILE *stream, fprintf_function stream_printf);
-bool st_change_trace_event_state(const char *tname, bool tstate);
-void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
-void st_set_trace_file_enabled(bool enable);
-bool st_set_trace_file(const char *file);
-void st_flush_trace_buffer(void);
-bool st_init(const char *file);
-#else
-static inline bool st_init(const char *file)
-{
-    return true;
-}
-#endif /* !CONFIG_SIMPLE_TRACE */
-
-#endif /* SIMPLETRACE_H */
index 72dbe9a5d9653fc71f1c616e72752c6001a91bc8..88c903fccd186e7746a267741c58e28e440407a8 100644 (file)
@@ -91,7 +91,7 @@ struct ip {
        uint8_t ip_p;                   /* protocol */
        uint16_t        ip_sum;                 /* checksum */
        struct  in_addr ip_src,ip_dst;  /* source and dest address */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define        IP_MAXPACKET    65535           /* maximum packet size */
 
@@ -153,7 +153,7 @@ struct      ip_timestamp {
                        n_long ipt_time;
                } ipt_ta[1];
        } ipt_timestamp;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* flag bits for ipt_flg */
 #define        IPOPT_TS_TSONLY         0               /* timestamps only */
@@ -183,11 +183,11 @@ struct    ip_timestamp {
 struct mbuf_ptr {
        struct mbuf *mptr;
        uint32_t dummy;
-} __attribute__((packed));
+} QEMU_PACKED;
 #else
 struct mbuf_ptr {
        struct mbuf *mptr;
-} __attribute__((packed));
+} QEMU_PACKED;
 #endif
 struct qlink {
        void *next, *prev;
@@ -203,7 +203,7 @@ struct ipovly {
        uint16_t        ih_len;                 /* protocol length */
        struct  in_addr ih_src;         /* source internet address */
        struct  in_addr ih_dst;         /* destination internet address */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /*
  * Ip reassembly queue structure.  Each fragment
@@ -219,7 +219,7 @@ struct ipq {
        uint8_t ipq_p;                  /* protocol of this fragment */
        uint16_t        ipq_id;                 /* sequence id for reassembly */
        struct  in_addr ipq_src,ipq_dst;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /*
  * Ip header, when holding a fragment.
@@ -229,7 +229,7 @@ struct ipq {
 struct ipasfrag {
        struct qlink ipf_link;
        struct ip ipf_ip;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define ipf_off      ipf_ip.ip_off
 #define ipf_tos      ipf_ip.ip_tos
@@ -248,6 +248,6 @@ struct      ipasfrag {
 struct ipoption {
        struct  in_addr ipopt_dst;      /* first-hop dst if source routed */
        int8_t  ipopt_list[MAX_IPOPTLEN];       /* options proper */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #endif
index dcf99d5ca4c720fde188b836cc9f97f2fada36b6..28a5c037e6aa4f25f628e63ea0636ab5bd0eb8f4 100644 (file)
@@ -199,7 +199,7 @@ struct arphdr {
     uint32_t      ar_sip;           /* sender IP address       */
     unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
     uint32_t      ar_tip;           /* target IP address       */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define ARP_TABLE_SIZE 16
 
index 31321be5325d90d0628a2e77d424902af3ccc476..56efe34e73e9958cb3b411e7c808f7c3d86e8b39 100644 (file)
--- a/sparc.ld
+++ b/sparc.ld
@@ -67,23 +67,23 @@ SECTIONS
   .tbss    : { *(.tbss) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors         :
   {
index 1d9b20c7066752d40560a64f2c8b229750c6a478..70ef74b80aba7d66c7383671fe607eb44fe562dc 100644 (file)
@@ -348,7 +348,7 @@ int kvm_arch_init_vcpu(CPUState *env)
     struct {
         struct kvm_cpuid2 cpuid;
         struct kvm_cpuid_entry2 entries[100];
-    } __attribute__((packed)) cpuid_data;
+    } QEMU_PACKED cpuid_data;
     KVMState *s = env->kvm_state;
     uint32_t limit, i, j, cpuid_i;
     uint32_t unused;
index a224aead1730c00189c42cc437aea93ac4988162..04193ed60f2b9a31bdf6f4a6a15cf8b1a6681ee3 100644 (file)
 
 #define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
 
-struct __attribute__ ((__packed__)) vmcb_control_area {
+struct QEMU_PACKED vmcb_control_area {
        uint16_t intercept_cr_read;
        uint16_t intercept_cr_write;
        uint16_t intercept_dr_read;
@@ -162,14 +162,14 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
        uint8_t reserved_5[832];
 };
 
-struct __attribute__ ((__packed__)) vmcb_seg {
+struct QEMU_PACKED vmcb_seg {
        uint16_t selector;
        uint16_t attrib;
        uint32_t limit;
        uint64_t base;
 };
 
-struct __attribute__ ((__packed__)) vmcb_save_area {
+struct QEMU_PACKED vmcb_save_area {
        struct vmcb_seg es;
        struct vmcb_seg cs;
        struct vmcb_seg ss;
@@ -214,7 +214,7 @@ struct __attribute__ ((__packed__)) vmcb_save_area {
        uint64_t last_excp_to;
 };
 
-struct __attribute__ ((__packed__)) vmcb {
+struct QEMU_PACKED vmcb {
        struct vmcb_control_area control;
        struct vmcb_save_area save;
 };
index a81da629de6ba1aa0680e4fc1dc5d3706041a5ef..35302863cb95fb210370532cb3e4d7c6c3971361 100644 (file)
@@ -65,6 +65,7 @@ struct CPUMBState;
 #define MSR_DCE (1<<7) /* 0x080 */
 #define MSR_EE  (1<<8) /* 0x100 */
 #define MSR_EIP (1<<9) /* 0x200 */
+#define MSR_PVR (1<<10) /* 0x400 */
 #define MSR_CC  (1<<31)
 
 /* Machine State Register (MSR) Fields */
index 1a862d31e31db19e4f3f2df85dc8abf7daaaa5fc..366fd3e607859ef3740fc097e434345db34c2586 100644 (file)
@@ -424,10 +424,15 @@ static inline void msr_read(DisasContext *dc, TCGv d)
 
 static inline void msr_write(DisasContext *dc, TCGv v)
 {
+    TCGv t;
+
+    t = tcg_temp_new();
     dc->cpustate_changed = 1;
-    tcg_gen_mov_tl(cpu_SR[SR_MSR], v);
-    /* PVR, we have a processor version register.  */
-    tcg_gen_ori_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10));
+    /* PVR bit is not writable.  */
+    tcg_gen_andi_tl(t, v, ~MSR_PVR);
+    tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR);
+    tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], v);
+    tcg_temp_free(t);
 }
 
 static void dec_msr(DisasContext *dc)
index c5f70fa759d6b11edfa34d59b1992af4c3436962..79e25583ff381c115d6e14e50417077eec5ed275 100644 (file)
@@ -537,6 +537,10 @@ static inline int cpu_mips_hw_interrupts_pending(CPUState *env)
     if (!(env->CP0_Status & (1 << CP0St_IE)) ||
         (env->CP0_Status & (1 << CP0St_EXL)) ||
         (env->CP0_Status & (1 << CP0St_ERL)) ||
+        /* Note that the TCStatus IXMT field is initialized to zero,
+           and only MT capable cores can set it to one. So we don't
+           need to check for MT capabilities here.  */
+        (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) ||
         (env->hflags & MIPS_HFLAG_DM)) {
         /* Interrupts are disabled */
         return 0;
@@ -618,6 +622,14 @@ enum {
 /* Dummy exception for conditional stores.  */
 #define EXCP_SC 0x100
 
+/*
+ * This is an interrnally generated WAKE request line.
+ * It is driven by the CPU itself. Raised when the MT
+ * block wants to wake a VPE from an inactive state and
+ * cleared when VPE goes from active to inactive.
+ */
+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
+
 int cpu_mips_exec(CPUMIPSState *s);
 CPUMIPSState *cpu_mips_init(const char *cpu_model);
 //~ uint32_t cpu_mips_get_clock (void);
@@ -658,6 +670,37 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
     env->tls_value = newtls;
 }
 
+static inline int mips_vpe_active(CPUState *env)
+{
+    int active = 1;
+
+    /* Check that the VPE is enabled.  */
+    if (!(env->mvp->CP0_MVPControl & (1 << CP0MVPCo_EVP))) {
+        active = 0;
+    }
+    /* Check that the VPE is actived.  */
+    if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))) {
+        active = 0;
+    }
+
+    /* Now verify that there are active thread contexts in the VPE.
+
+       This assumes the CPU model will internally reschedule threads
+       if the active one goes to sleep. If there are no threads available
+       the active one will be in a sleeping state, and we can turn off
+       the entire VPE.  */
+    if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) {
+        /* TC is not activated.  */
+        active = 0;
+    }
+    if (env->active_tc.CP0_TCHalt & 1) {
+        /* TC is in halt state.  */
+        active = 0;
+    }
+
+    return active;
+}
+
 static inline int cpu_has_work(CPUState *env)
 {
     int has_work = 0;
@@ -670,6 +713,18 @@ static inline int cpu_has_work(CPUState *env)
         has_work = 1;
     }
 
+    /* MIPS-MT has the ability to halt the CPU.  */
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        /* The QEMU model will issue an _WAKE request whenever the CPUs
+           should be woken up.  */
+        if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
+            has_work = 1;
+        }
+
+        if (!mips_vpe_active(env)) {
+            has_work = 0;
+        }
+    }
     return has_work;
 }
 
index 024caa23c13b935f396c880744159653493a8d54..1c58e0cc210088f8275ddcaa3fc0d4916e548e94 100644 (file)
@@ -482,18 +482,18 @@ void do_interrupt (CPUState *env)
             unsigned int vector;
             unsigned int pending = (env->CP0_Cause & CP0Ca_IP_mask) >> 8;
 
+            pending &= env->CP0_Status >> 8;
             /* Compute the Vector Spacing.  */
             spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & ((1 << 6) - 1);
             spacing <<= 5;
 
             if (env->CP0_Config3 & (1 << CP0C3_VInt)) {
                 /* For VInt mode, the MIPS computes the vector internally.  */
-                for (vector = 0; vector < 8; vector++) {
-                    if (pending & 1) {
+                for (vector = 7; vector > 0; vector--) {
+                    if (pending & (1 << vector)) {
                         /* Found it.  */
                         break;
                     }
-                    pending >>= 1;
                 }
             } else {
                 /* For VEIC mode, the external interrupt controller feeds the
index 297ab64bda85576d7a13cf7f317f6a83a30e3e5e..442f684697fd8691d021fe342ec23813d574e220 100644 (file)
@@ -52,6 +52,8 @@ DEF_HELPER_2(msachiu, tl, tl, tl)
 DEF_HELPER_0(mfc0_mvpcontrol, tl)
 DEF_HELPER_0(mfc0_mvpconf0, tl)
 DEF_HELPER_0(mfc0_mvpconf1, tl)
+DEF_HELPER_0(mftc0_vpecontrol, tl)
+DEF_HELPER_0(mftc0_vpeconf0, tl)
 DEF_HELPER_0(mfc0_random, tl)
 DEF_HELPER_0(mfc0_tcstatus, tl)
 DEF_HELPER_0(mftc0_tcstatus, tl)
@@ -70,6 +72,10 @@ DEF_HELPER_0(mftc0_tcschefback, tl)
 DEF_HELPER_0(mfc0_count, tl)
 DEF_HELPER_0(mftc0_entryhi, tl)
 DEF_HELPER_0(mftc0_status, tl)
+DEF_HELPER_0(mftc0_cause, tl)
+DEF_HELPER_0(mftc0_epc, tl)
+DEF_HELPER_0(mftc0_ebase, tl)
+DEF_HELPER_1(mftc0_configx, tl, tl)
 DEF_HELPER_0(mfc0_lladdr, tl)
 DEF_HELPER_1(mfc0_watchlo, tl, i32)
 DEF_HELPER_1(mfc0_watchhi, tl, i32)
@@ -88,7 +94,9 @@ DEF_HELPER_1(dmfc0_watchlo, tl, i32)
 DEF_HELPER_1(mtc0_index, void, tl)
 DEF_HELPER_1(mtc0_mvpcontrol, void, tl)
 DEF_HELPER_1(mtc0_vpecontrol, void, tl)
+DEF_HELPER_1(mttc0_vpecontrol, void, tl)
 DEF_HELPER_1(mtc0_vpeconf0, void, tl)
+DEF_HELPER_1(mttc0_vpeconf0, void, tl)
 DEF_HELPER_1(mtc0_vpeconf1, void, tl)
 DEF_HELPER_1(mtc0_yqmask, void, tl)
 DEF_HELPER_1(mtc0_vpeopt, void, tl)
@@ -127,7 +135,9 @@ DEF_HELPER_1(mttc0_status, void, tl)
 DEF_HELPER_1(mtc0_intctl, void, tl)
 DEF_HELPER_1(mtc0_srsctl, void, tl)
 DEF_HELPER_1(mtc0_cause, void, tl)
+DEF_HELPER_1(mttc0_cause, void, tl)
 DEF_HELPER_1(mtc0_ebase, void, tl)
+DEF_HELPER_1(mttc0_ebase, void, tl)
 DEF_HELPER_1(mtc0_config0, void, tl)
 DEF_HELPER_1(mtc0_config2, void, tl)
 DEF_HELPER_1(mtc0_lladdr, void, tl)
index 056011f1cc31c7b53d21504b2d0e9f4c128809ae..96e40c60186ce2ce98974988454a776cb73691e4 100644 (file)
@@ -749,6 +749,163 @@ void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
 #endif
 
 #ifndef CONFIG_USER_ONLY
+/* SMP helpers.  */
+static int mips_vpe_is_wfi(CPUState *c)
+{
+    /* If the VPE is halted but otherwise active, it means it's waiting for
+       an interrupt.  */
+    return c->halted && mips_vpe_active(c);
+}
+
+static inline void mips_vpe_wake(CPUState *c)
+{
+    /* Dont set ->halted = 0 directly, let it be done via cpu_has_work
+       because there might be other conditions that state that c should
+       be sleeping.  */
+    cpu_interrupt(c, CPU_INTERRUPT_WAKE);
+}
+
+static inline void mips_vpe_sleep(CPUState *c)
+{
+    /* The VPE was shut off, really go to bed.
+       Reset any old _WAKE requests.  */
+    c->halted = 1;
+    cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE);
+}
+
+static inline void mips_tc_wake(CPUState *c, int tc)
+{
+    /* FIXME: TC reschedule.  */
+    if (mips_vpe_active(c) && !mips_vpe_is_wfi(c)) {
+        mips_vpe_wake(c);
+    }
+}
+
+static inline void mips_tc_sleep(CPUState *c, int tc)
+{
+    /* FIXME: TC reschedule.  */
+    if (!mips_vpe_active(c)) {
+        mips_vpe_sleep(c);
+    }
+}
+
+/* tc should point to an int with the value of the global TC index.
+   This function will transform it into a local index within the
+   returned CPUState.
+
+   FIXME: This code assumes that all VPEs have the same number of TCs,
+          which depends on runtime setup. Can probably be fixed by
+          walking the list of CPUStates.  */
+static CPUState *mips_cpu_map_tc(int *tc)
+{
+    CPUState *other;
+    int vpe_idx, nr_threads = env->nr_threads;
+    int tc_idx = *tc;
+
+    if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) {
+        /* Not allowed to address other CPUs.  */
+        *tc = env->current_tc;
+        return env;
+    }
+
+    vpe_idx = tc_idx / nr_threads;
+    *tc = tc_idx % nr_threads;
+    other = qemu_get_cpu(vpe_idx);
+    return other ? other : env;
+}
+
+/* The per VPE CP0_Status register shares some fields with the per TC
+   CP0_TCStatus registers. These fields are wired to the same registers,
+   so changes to either of them should be reflected on both registers.
+
+   Also, EntryHi shares the bottom 8 bit ASID with TCStauts.
+
+   These helper call synchronizes the regs for a given cpu.  */
+
+/* Called for updates to CP0_Status.  */
+static void sync_c0_status(CPUState *cpu, int tc)
+{
+    int32_t tcstatus, *tcst;
+    uint32_t v = cpu->CP0_Status;
+    uint32_t cu, mx, asid, ksu;
+    uint32_t mask = ((1 << CP0TCSt_TCU3)
+                       | (1 << CP0TCSt_TCU2)
+                       | (1 << CP0TCSt_TCU1)
+                       | (1 << CP0TCSt_TCU0)
+                       | (1 << CP0TCSt_TMX)
+                       | (3 << CP0TCSt_TKSU)
+                       | (0xff << CP0TCSt_TASID));
+
+    cu = (v >> CP0St_CU0) & 0xf;
+    mx = (v >> CP0St_MX) & 0x1;
+    ksu = (v >> CP0St_KSU) & 0x3;
+    asid = env->CP0_EntryHi & 0xff;
+
+    tcstatus = cu << CP0TCSt_TCU0;
+    tcstatus |= mx << CP0TCSt_TMX;
+    tcstatus |= ksu << CP0TCSt_TKSU;
+    tcstatus |= asid;
+
+    if (tc == cpu->current_tc) {
+        tcst = &cpu->active_tc.CP0_TCStatus;
+    } else {
+        tcst = &cpu->tcs[tc].CP0_TCStatus;
+    }
+
+    *tcst &= ~mask;
+    *tcst |= tcstatus;
+    compute_hflags(cpu);
+}
+
+/* Called for updates to CP0_TCStatus.  */
+static void sync_c0_tcstatus(CPUState *cpu, int tc, target_ulong v)
+{
+    uint32_t status;
+    uint32_t tcu, tmx, tasid, tksu;
+    uint32_t mask = ((1 << CP0St_CU3)
+                       | (1 << CP0St_CU2)
+                       | (1 << CP0St_CU1)
+                       | (1 << CP0St_CU0)
+                       | (1 << CP0St_MX)
+                       | (3 << CP0St_KSU));
+
+    tcu = (v >> CP0TCSt_TCU0) & 0xf;
+    tmx = (v >> CP0TCSt_TMX) & 0x1;
+    tasid = v & 0xff;
+    tksu = (v >> CP0TCSt_TKSU) & 0x3;
+
+    status = tcu << CP0St_CU0;
+    status |= tmx << CP0St_MX;
+    status |= tksu << CP0St_KSU;
+
+    cpu->CP0_Status &= ~mask;
+    cpu->CP0_Status |= status;
+
+    /* Sync the TASID with EntryHi.  */
+    cpu->CP0_EntryHi &= ~0xff;
+    cpu->CP0_EntryHi = tasid;
+
+    compute_hflags(cpu);
+}
+
+/* Called for updates to CP0_EntryHi.  */
+static void sync_c0_entryhi(CPUState *cpu, int tc)
+{
+    int32_t *tcst;
+    uint32_t asid, v = cpu->CP0_EntryHi;
+
+    asid = v & 0xff;
+
+    if (tc == cpu->current_tc) {
+        tcst = &cpu->active_tc.CP0_TCStatus;
+    } else {
+        tcst = &cpu->tcs[tc].CP0_TCStatus;
+    }
+
+    *tcst &= ~0xff;
+    *tcst |= asid;
+}
+
 /* CP0 helpers */
 target_ulong helper_mfc0_mvpcontrol (void)
 {
@@ -778,11 +935,12 @@ target_ulong helper_mfc0_tcstatus (void)
 target_ulong helper_mftc0_tcstatus(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCStatus;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCStatus;
     else
-        return env->tcs[other_tc].CP0_TCStatus;
+        return other->tcs[other_tc].CP0_TCStatus;
 }
 
 target_ulong helper_mfc0_tcbind (void)
@@ -793,11 +951,12 @@ target_ulong helper_mfc0_tcbind (void)
 target_ulong helper_mftc0_tcbind(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCBind;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCBind;
     else
-        return env->tcs[other_tc].CP0_TCBind;
+        return other->tcs[other_tc].CP0_TCBind;
 }
 
 target_ulong helper_mfc0_tcrestart (void)
@@ -808,11 +967,12 @@ target_ulong helper_mfc0_tcrestart (void)
 target_ulong helper_mftc0_tcrestart(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.PC;
+    if (other_tc == other->current_tc)
+        return other->active_tc.PC;
     else
-        return env->tcs[other_tc].PC;
+        return other->tcs[other_tc].PC;
 }
 
 target_ulong helper_mfc0_tchalt (void)
@@ -823,11 +983,12 @@ target_ulong helper_mfc0_tchalt (void)
 target_ulong helper_mftc0_tchalt(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCHalt;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCHalt;
     else
-        return env->tcs[other_tc].CP0_TCHalt;
+        return other->tcs[other_tc].CP0_TCHalt;
 }
 
 target_ulong helper_mfc0_tccontext (void)
@@ -838,11 +999,12 @@ target_ulong helper_mfc0_tccontext (void)
 target_ulong helper_mftc0_tccontext(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCContext;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCContext;
     else
-        return env->tcs[other_tc].CP0_TCContext;
+        return other->tcs[other_tc].CP0_TCContext;
 }
 
 target_ulong helper_mfc0_tcschedule (void)
@@ -853,11 +1015,12 @@ target_ulong helper_mfc0_tcschedule (void)
 target_ulong helper_mftc0_tcschedule(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCSchedule;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCSchedule;
     else
-        return env->tcs[other_tc].CP0_TCSchedule;
+        return other->tcs[other_tc].CP0_TCSchedule;
 }
 
 target_ulong helper_mfc0_tcschefback (void)
@@ -868,11 +1031,12 @@ target_ulong helper_mfc0_tcschefback (void)
 target_ulong helper_mftc0_tcschefback(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCScheFBack;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCScheFBack;
     else
-        return env->tcs[other_tc].CP0_TCScheFBack;
+        return other->tcs[other_tc].CP0_TCScheFBack;
 }
 
 target_ulong helper_mfc0_count (void)
@@ -883,33 +1047,32 @@ target_ulong helper_mfc0_count (void)
 target_ulong helper_mftc0_entryhi(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
-    int32_t tcstatus;
-
-    if (other_tc == env->current_tc)
-        tcstatus = env->active_tc.CP0_TCStatus;
-    else
-        tcstatus = env->tcs[other_tc].CP0_TCStatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    return (env->CP0_EntryHi & ~0xff) | (tcstatus & 0xff);
+    return other->CP0_EntryHi;
 }
 
-target_ulong helper_mftc0_status(void)
+target_ulong helper_mftc0_cause(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
-    target_ulong t0;
-    int32_t tcstatus;
+    int32_t tccause;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        tcstatus = env->active_tc.CP0_TCStatus;
-    else
-        tcstatus = env->tcs[other_tc].CP0_TCStatus;
+    if (other_tc == other->current_tc) {
+        tccause = other->CP0_Cause;
+    } else {
+        tccause = other->CP0_Cause;
+    }
 
-    t0 = env->CP0_Status & ~0xf1000018;
-    t0 |= tcstatus & (0xf << CP0TCSt_TCU0);
-    t0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
-    t0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
+    return tccause;
+}
 
-    return t0;
+target_ulong helper_mftc0_status(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    return other->CP0_Status;
 }
 
 target_ulong helper_mfc0_lladdr (void)
@@ -940,14 +1103,15 @@ target_ulong helper_mftc0_debug(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     int32_t tcstatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        tcstatus = env->active_tc.CP0_Debug_tcstatus;
+    if (other_tc == other->current_tc)
+        tcstatus = other->active_tc.CP0_Debug_tcstatus;
     else
-        tcstatus = env->tcs[other_tc].CP0_Debug_tcstatus;
+        tcstatus = other->tcs[other_tc].CP0_Debug_tcstatus;
 
     /* XXX: Might be wrong, check with EJTAG spec. */
-    return (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
+    return (other->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
             (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
 }
 
@@ -1034,6 +1198,38 @@ void helper_mtc0_vpecontrol (target_ulong arg1)
     env->CP0_VPEControl = newval;
 }
 
+void helper_mttc0_vpecontrol(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    uint32_t mask;
+    uint32_t newval;
+
+    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
+           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
+    newval = (other->CP0_VPEControl & ~mask) | (arg1 & mask);
+
+    /* TODO: Enable/disable TCs.  */
+
+    other->CP0_VPEControl = newval;
+}
+
+target_ulong helper_mftc0_vpecontrol(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    /* FIXME: Mask away return zero on read bits.  */
+    return other->CP0_VPEControl;
+}
+
+target_ulong helper_mftc0_vpeconf0(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    return other->CP0_VPEConf0;
+}
+
 void helper_mtc0_vpeconf0 (target_ulong arg1)
 {
     uint32_t mask = 0;
@@ -1051,6 +1247,20 @@ void helper_mtc0_vpeconf0 (target_ulong arg1)
     env->CP0_VPEConf0 = newval;
 }
 
+void helper_mttc0_vpeconf0(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    uint32_t mask = 0;
+    uint32_t newval;
+
+    mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
+    newval = (other->CP0_VPEConf0 & ~mask) | (arg1 & mask);
+
+    /* TODO: TC exclusive handling due to ERL/EXL.  */
+    other->CP0_VPEConf0 = newval;
+}
+
 void helper_mtc0_vpeconf1 (target_ulong arg1)
 {
     uint32_t mask = 0;
@@ -1094,21 +1304,20 @@ void helper_mtc0_tcstatus (target_ulong arg1)
 
     newval = (env->active_tc.CP0_TCStatus & ~mask) | (arg1 & mask);
 
-    // TODO: Sync with CP0_Status.
-
     env->active_tc.CP0_TCStatus = newval;
+    sync_c0_tcstatus(env, env->current_tc, newval);
 }
 
 void helper_mttc0_tcstatus (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    // TODO: Sync with CP0_Status.
-
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCStatus = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCStatus = arg1;
     else
-        env->tcs[other_tc].CP0_TCStatus = arg1;
+        other->tcs[other_tc].CP0_TCStatus = arg1;
+    sync_c0_tcstatus(other, other_tc, arg1);
 }
 
 void helper_mtc0_tcbind (target_ulong arg1)
@@ -1127,15 +1336,16 @@ void helper_mttc0_tcbind (target_ulong arg1)
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     uint32_t mask = (1 << CP0TCBd_TBE);
     uint32_t newval;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
+    if (other->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
         mask |= (1 << CP0TCBd_CurVPE);
-    if (other_tc == env->current_tc) {
-        newval = (env->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
-        env->active_tc.CP0_TCBind = newval;
+    if (other_tc == other->current_tc) {
+        newval = (other->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
+        other->active_tc.CP0_TCBind = newval;
     } else {
-        newval = (env->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask);
-        env->tcs[other_tc].CP0_TCBind = newval;
+        newval = (other->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask);
+        other->tcs[other_tc].CP0_TCBind = newval;
     }
 }
 
@@ -1150,16 +1360,17 @@ void helper_mtc0_tcrestart (target_ulong arg1)
 void helper_mttc0_tcrestart (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc) {
-        env->active_tc.PC = arg1;
-        env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
-        env->lladdr = 0ULL;
+    if (other_tc == other->current_tc) {
+        other->active_tc.PC = arg1;
+        other->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+        other->lladdr = 0ULL;
         /* MIPS16 not implemented. */
     } else {
-        env->tcs[other_tc].PC = arg1;
-        env->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
-        env->lladdr = 0ULL;
+        other->tcs[other_tc].PC = arg1;
+        other->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+        other->lladdr = 0ULL;
         /* MIPS16 not implemented. */
     }
 }
@@ -1169,18 +1380,30 @@ void helper_mtc0_tchalt (target_ulong arg1)
     env->active_tc.CP0_TCHalt = arg1 & 0x1;
 
     // TODO: Halt TC / Restart (if allocated+active) TC.
+    if (env->active_tc.CP0_TCHalt & 1) {
+        mips_tc_sleep(env, env->current_tc);
+    } else {
+        mips_tc_wake(env, env->current_tc);
+    }
 }
 
 void helper_mttc0_tchalt (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
     // TODO: Halt TC / Restart (if allocated+active) TC.
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCHalt = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCHalt = arg1;
     else
-        env->tcs[other_tc].CP0_TCHalt = arg1;
+        other->tcs[other_tc].CP0_TCHalt = arg1;
+
+    if (arg1 & 1) {
+        mips_tc_sleep(other, other_tc);
+    } else {
+        mips_tc_wake(other, other_tc);
+    }
 }
 
 void helper_mtc0_tccontext (target_ulong arg1)
@@ -1191,11 +1414,12 @@ void helper_mtc0_tccontext (target_ulong arg1)
 void helper_mttc0_tccontext (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCContext = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCContext = arg1;
     else
-        env->tcs[other_tc].CP0_TCContext = arg1;
+        other->tcs[other_tc].CP0_TCContext = arg1;
 }
 
 void helper_mtc0_tcschedule (target_ulong arg1)
@@ -1206,11 +1430,12 @@ void helper_mtc0_tcschedule (target_ulong arg1)
 void helper_mttc0_tcschedule (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCSchedule = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCSchedule = arg1;
     else
-        env->tcs[other_tc].CP0_TCSchedule = arg1;
+        other->tcs[other_tc].CP0_TCSchedule = arg1;
 }
 
 void helper_mtc0_tcschefback (target_ulong arg1)
@@ -1221,11 +1446,12 @@ void helper_mtc0_tcschefback (target_ulong arg1)
 void helper_mttc0_tcschefback (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCScheFBack = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCScheFBack = arg1;
     else
-        env->tcs[other_tc].CP0_TCScheFBack = arg1;
+        other->tcs[other_tc].CP0_TCScheFBack = arg1;
 }
 
 void helper_mtc0_entrylo1 (target_ulong arg1)
@@ -1306,8 +1532,7 @@ void helper_mtc0_entryhi (target_ulong arg1)
     old = env->CP0_EntryHi;
     env->CP0_EntryHi = val;
     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
-        uint32_t tcst = env->active_tc.CP0_TCStatus & ~0xff;
-        env->active_tc.CP0_TCStatus = tcst | (val & 0xff);
+        sync_c0_entryhi(env, env->current_tc);
     }
     /* If the ASID changes, flush qemu's TLB.  */
     if ((old & 0xFF) != (val & 0xFF))
@@ -1317,16 +1542,10 @@ void helper_mtc0_entryhi (target_ulong arg1)
 void helper_mttc0_entryhi(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
-    int32_t tcstatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (arg1 & ~0xff);
-    if (other_tc == env->current_tc) {
-        tcstatus = (env->active_tc.CP0_TCStatus & ~0xff) | (arg1 & 0xff);
-        env->active_tc.CP0_TCStatus = tcstatus;
-    } else {
-        tcstatus = (env->tcs[other_tc].CP0_TCStatus & ~0xff) | (arg1 & 0xff);
-        env->tcs[other_tc].CP0_TCStatus = tcstatus;
-    }
+    other->CP0_EntryHi = arg1;
+    sync_c0_entryhi(other, other_tc);
 }
 
 void helper_mtc0_compare (target_ulong arg1)
@@ -1342,7 +1561,12 @@ void helper_mtc0_status (target_ulong arg1)
     val = arg1 & mask;
     old = env->CP0_Status;
     env->CP0_Status = (env->CP0_Status & ~mask) | val;
-    compute_hflags(env);
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        sync_c0_status(env, env->current_tc);
+    } else {
+        compute_hflags(env);
+    }
+
     if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
         qemu_log("Status %08x (%08x) => %08x (%08x) Cause %08x",
                 old, old & env->CP0_Cause & CP0Ca_IP_mask,
@@ -1360,22 +1584,16 @@ void helper_mtc0_status (target_ulong arg1)
 void helper_mttc0_status(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
-    int32_t tcstatus = env->tcs[other_tc].CP0_TCStatus;
-
-    env->CP0_Status = arg1 & ~0xf1000018;
-    tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (arg1 & (0xf << CP0St_CU0));
-    tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((arg1 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
-    tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((arg1 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCStatus = tcstatus;
-    else
-        env->tcs[other_tc].CP0_TCStatus = tcstatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    other->CP0_Status = arg1 & ~0xf1000018;
+    sync_c0_status(other, other_tc);
 }
 
 void helper_mtc0_intctl (target_ulong arg1)
 {
     /* vectored interrupts not implemented, no performance counters. */
-    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (arg1 & 0x000002e0);
+    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
 }
 
 void helper_mtc0_srsctl (target_ulong arg1)
@@ -1384,38 +1602,95 @@ void helper_mtc0_srsctl (target_ulong arg1)
     env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (arg1 & mask);
 }
 
-void helper_mtc0_cause (target_ulong arg1)
+static void mtc0_cause(CPUState *cpu, target_ulong arg1)
 {
     uint32_t mask = 0x00C00300;
-    uint32_t old = env->CP0_Cause;
+    uint32_t old = cpu->CP0_Cause;
     int i;
 
-    if (env->insn_flags & ISA_MIPS32R2)
+    if (cpu->insn_flags & ISA_MIPS32R2) {
         mask |= 1 << CP0Ca_DC;
+    }
 
-    env->CP0_Cause = (env->CP0_Cause & ~mask) | (arg1 & mask);
+    cpu->CP0_Cause = (cpu->CP0_Cause & ~mask) | (arg1 & mask);
 
-    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
-        if (env->CP0_Cause & (1 << CP0Ca_DC))
-            cpu_mips_stop_count(env);
-        else
-            cpu_mips_start_count(env);
+    if ((old ^ cpu->CP0_Cause) & (1 << CP0Ca_DC)) {
+        if (cpu->CP0_Cause & (1 << CP0Ca_DC)) {
+            cpu_mips_stop_count(cpu);
+        } else {
+            cpu_mips_start_count(cpu);
+        }
     }
 
     /* Set/reset software interrupts */
     for (i = 0 ; i < 2 ; i++) {
-        if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
-            cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
+        if ((old ^ cpu->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
+            cpu_mips_soft_irq(cpu, i, cpu->CP0_Cause & (1 << (CP0Ca_IP + i)));
         }
     }
 }
 
+void helper_mtc0_cause(target_ulong arg1)
+{
+    mtc0_cause(env, arg1);
+}
+
+void helper_mttc0_cause(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    mtc0_cause(other, arg1);
+}
+
+target_ulong helper_mftc0_epc(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    return other->CP0_EPC;
+}
+
+target_ulong helper_mftc0_ebase(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    return other->CP0_EBase;
+}
+
 void helper_mtc0_ebase (target_ulong arg1)
 {
     /* vectored interrupts not implemented */
     env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
 }
 
+void helper_mttc0_ebase(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    other->CP0_EBase = (other->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
+}
+
+target_ulong helper_mftc0_configx(target_ulong idx)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    switch (idx) {
+    case 0: return other->CP0_Config0;
+    case 1: return other->CP0_Config1;
+    case 2: return other->CP0_Config2;
+    case 3: return other->CP0_Config3;
+    /* 4 and 5 are reserved.  */
+    case 6: return other->CP0_Config6;
+    case 7: return other->CP0_Config7;
+    default:
+        break;
+    }
+    return 0;
+}
+
 void helper_mtc0_config0 (target_ulong arg1)
 {
     env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (arg1 & 0x00000007);
@@ -1471,13 +1746,15 @@ void helper_mttc0_debug(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     uint32_t val = arg1 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
     /* XXX: Might be wrong, check with EJTAG spec. */
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_Debug_tcstatus = val;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_Debug_tcstatus = val;
     else
-        env->tcs[other_tc].CP0_Debug_tcstatus = val;
-    env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
+        other->tcs[other_tc].CP0_Debug_tcstatus = val;
+    other->CP0_Debug = (other->CP0_Debug &
+                     ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
                      (arg1 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
 }
 
@@ -1510,101 +1787,111 @@ void helper_mtc0_datahi (target_ulong arg1)
 target_ulong helper_mftgpr(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.gpr[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.gpr[sel];
     else
-        return env->tcs[other_tc].gpr[sel];
+        return other->tcs[other_tc].gpr[sel];
 }
 
 target_ulong helper_mftlo(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.LO[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.LO[sel];
     else
-        return env->tcs[other_tc].LO[sel];
+        return other->tcs[other_tc].LO[sel];
 }
 
 target_ulong helper_mfthi(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.HI[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.HI[sel];
     else
-        return env->tcs[other_tc].HI[sel];
+        return other->tcs[other_tc].HI[sel];
 }
 
 target_ulong helper_mftacx(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.ACX[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.ACX[sel];
     else
-        return env->tcs[other_tc].ACX[sel];
+        return other->tcs[other_tc].ACX[sel];
 }
 
 target_ulong helper_mftdsp(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.DSPControl;
+    if (other_tc == other->current_tc)
+        return other->active_tc.DSPControl;
     else
-        return env->tcs[other_tc].DSPControl;
+        return other->tcs[other_tc].DSPControl;
 }
 
 void helper_mttgpr(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.gpr[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.gpr[sel] = arg1;
     else
-        env->tcs[other_tc].gpr[sel] = arg1;
+        other->tcs[other_tc].gpr[sel] = arg1;
 }
 
 void helper_mttlo(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.LO[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.LO[sel] = arg1;
     else
-        env->tcs[other_tc].LO[sel] = arg1;
+        other->tcs[other_tc].LO[sel] = arg1;
 }
 
 void helper_mtthi(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.HI[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.HI[sel] = arg1;
     else
-        env->tcs[other_tc].HI[sel] = arg1;
+        other->tcs[other_tc].HI[sel] = arg1;
 }
 
 void helper_mttacx(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.ACX[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.ACX[sel] = arg1;
     else
-        env->tcs[other_tc].ACX[sel] = arg1;
+        other->tcs[other_tc].ACX[sel] = arg1;
 }
 
 void helper_mttdsp(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.DSPControl = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.DSPControl = arg1;
     else
-        env->tcs[other_tc].DSPControl = arg1;
+        other->tcs[other_tc].DSPControl = arg1;
 }
 
 /* MIPS MT functions */
@@ -1622,14 +1909,36 @@ target_ulong helper_emt(void)
 
 target_ulong helper_dvpe(void)
 {
-    // TODO
-    return 0;
+    CPUState *other_cpu = first_cpu;
+    target_ulong prev = env->mvp->CP0_MVPControl;
+
+    do {
+        /* Turn off all VPEs except the one executing the dvpe.  */
+        if (other_cpu != env) {
+            other_cpu->mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
+            mips_vpe_sleep(other_cpu);
+        }
+        other_cpu = other_cpu->next_cpu;
+    } while (other_cpu);
+    return prev;
 }
 
 target_ulong helper_evpe(void)
 {
-    // TODO
-    return 0;
+    CPUState *other_cpu = first_cpu;
+    target_ulong prev = env->mvp->CP0_MVPControl;
+
+    do {
+        if (other_cpu != env
+           /* If the VPE is WFI, dont distrub it's sleep.  */
+           && !mips_vpe_is_wfi(other_cpu)) {
+            /* Enable the VPE.  */
+            other_cpu->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+            mips_vpe_wake(other_cpu); /* And wake it up.  */
+        }
+        other_cpu = other_cpu->next_cpu;
+    } while (other_cpu);
+    return prev;
 }
 #endif /* !CONFIG_USER_ONLY */
 
@@ -1977,6 +2286,7 @@ void helper_pmon (int function)
 void helper_wait (void)
 {
     env->halted = 1;
+    cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE);
     helper_raise_exception(EXCP_HLT);
 }
 
index 6c4e0d7675025d8432491a308580eaf35cf1cb9e..d5b1c765fb9d701662baa7b178afb1fa95e198d3 100644 (file)
@@ -5537,6 +5537,19 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
         tcg_gen_movi_tl(t0, -1);
     else if (u == 0) {
         switch (rt) {
+        case 1:
+            switch (sel) {
+            case 1:
+                gen_helper_mftc0_vpecontrol(t0);
+                break;
+            case 2:
+                gen_helper_mftc0_vpeconf0(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 2:
             switch (sel) {
             case 1:
@@ -5583,6 +5596,46 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
                 gen_mfc0(env, ctx, t0, rt, sel);
                 break;
             }
+        case 13:
+            switch (sel) {
+            case 0:
+                gen_helper_mftc0_cause(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 14:
+            switch (sel) {
+            case 0:
+                gen_helper_mftc0_epc(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 15:
+            switch (sel) {
+            case 1:
+                gen_helper_mftc0_ebase(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 16:
+            switch (sel) {
+            case 0 ... 7:
+                gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 23:
             switch (sel) {
             case 0:
@@ -5702,6 +5755,19 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
         /* NOP */ ;
     else if (u == 0) {
         switch (rd) {
+        case 1:
+            switch (sel) {
+            case 1:
+                gen_helper_mttc0_vpecontrol(t0);
+                break;
+            case 2:
+                gen_helper_mttc0_vpeconf0(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 2:
             switch (sel) {
             case 1:
@@ -5748,6 +5814,26 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
                 gen_mtc0(env, ctx, t0, rd, sel);
                 break;
             }
+        case 13:
+            switch (sel) {
+            case 0:
+                gen_helper_mttc0_cause(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 15:
+            switch (sel) {
+            case 1:
+                gen_helper_mttc0_ebase(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 23:
             switch (sel) {
             case 0:
@@ -12727,6 +12813,32 @@ void cpu_reset (CPUMIPSState *env)
     /* Count register increments in debug mode, EJTAG version 1 */
     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
     env->hflags = MIPS_HFLAG_CP0;
+
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        int i;
+
+        /* Only TC0 on VPE 0 starts as active.  */
+        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
+            env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
+            env->tcs[i].CP0_TCHalt = 1;
+        }
+        env->active_tc.CP0_TCHalt = 1;
+        env->halted = 1;
+
+        if (!env->cpu_index) {
+            /* VPE0 starts up enabled.  */
+            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
+
+            /* TC0 starts up unhalted.  */
+            env->halted = 0;
+            env->active_tc.CP0_TCHalt = 0;
+            env->tcs[0].CP0_TCHalt = 0;
+            /* With thread 0 active.  */
+            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
+            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
+        }
+    }
 #endif
 #if defined(TARGET_MIPS64)
     if (env->cpu_model->insn_flags & ISA_MIPS3) {
index 5bb421562a96e0164460f489d3e45d89cdc9884b..c39138f3c53467156f9bb8716b6ae47cc81f340e 100644 (file)
@@ -274,7 +274,7 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
                        (1 << CP0C1_CA),
         .CP0_Config2 = MIPS_CONFIG2,
-        .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT),
+        .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT),
         .CP0_LLAddr_rw_bitmask = 0,
         .CP0_LLAddr_shift = 0,
         .SYNCI_Step = 32,
@@ -580,7 +580,7 @@ static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
 //                             (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) |
 //                             (0x04 << CP0MVPC0_PTC);
                              (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
-                             (0x04 << CP0MVPC0_PTC);
+                             (0x00 << CP0MVPC0_PTC);
 #if !defined(CONFIG_USER_ONLY)
     /* Usermode has no TLB support */
     env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE);
index f8f0c82c6f126c9f85c537920d70264db50bae78..e192b50c7385d29f09cff166558a9dcee84d6a00 100644 (file)
@@ -698,7 +698,7 @@ typedef struct LowCore
     /* align to the top of the prefix area */
 
     uint8_t         pad18[0x2000-0x1400];      /* 0x1400 */
-} __attribute__((packed)) LowCore;
+} QEMU_PACKED LowCore;
 
 /* STSI */
 #define STSI_LEVEL_MASK         0x00000000f0000000ULL
index 7e7f2b20204636e8cab7533ddd8bd909bf17f2a0..9c65474a8c77962d4e1eddb78959c37b4cf25fca 100644 (file)
@@ -87,13 +87,13 @@ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
     }
 }
 
-static int op_bits(enum TCGOpcode op)
+static int op_bits(TCGOpcode op)
 {
     const TCGOpDef *def = &tcg_op_defs[op];
     return def->flags & TCG_OPF_64BIT ? 64 : 32;
 }
 
-static int op_to_movi(int op)
+static TCGOpcode op_to_movi(TCGOpcode op)
 {
     switch (op_bits(op)) {
     case 32:
@@ -143,7 +143,7 @@ static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val,
         gen_args[1] = val;
 }
 
-static int op_to_mov(int op)
+static TCGOpcode op_to_mov(TCGOpcode op)
 {
     switch (op_bits(op)) {
     case 32:
@@ -157,7 +157,7 @@ static int op_to_mov(int op)
     }
 }
 
-static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
+static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
 {
     switch (op) {
     CASE_OP_32_64(add):
@@ -258,7 +258,7 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
     }
 }
 
-static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y)
+static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
 {
     TCGArg res = do_constant_folding_2(op, x, y);
     if (op_bits(op) == 32) {
@@ -271,7 +271,8 @@ static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y)
 static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                                     TCGArg *args, TCGOpDef *tcg_op_defs)
 {
-    int i, nb_ops, op_index, op, nb_temps, nb_globals, nb_call_args;
+    int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
+    TCGOpcode op;
     const TCGOpDef *def;
     TCGArg *gen_args;
     TCGArg tmp;
@@ -377,6 +378,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                 continue;
             }
             break;
+        default:
+            break;
         }
 
         /* Propagate constants through copy operations and do constant
index 4462647ef177930a5a09a8a72dec852907d73ba1..87cc1177f6c1c800a61ec038e63312eb54a6fba1 100644 (file)
@@ -525,13 +525,13 @@ static void *qemu_st_helpers[4] = {
 
 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;
+    int addr_reg, data_reg, data_reg2, r0, r1, rbase, bswap;
 #ifdef CONFIG_SOFTMMU
-    int r2;
+    int mem_index, s_bits, r2;
     void *label1_ptr, *label2_ptr;
-#endif
 #if TARGET_LONG_BITS == 64
     int addr_reg2;
+#endif
 #endif
 
     data_reg = *args++;
@@ -540,13 +540,13 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
     else
         data_reg2 = 0;
     addr_reg = *args++;
+
+#ifdef CONFIG_SOFTMMU
 #if TARGET_LONG_BITS == 64
     addr_reg2 = *args++;
 #endif
     mem_index = *args;
     s_bits = opc & 3;
-
-#ifdef CONFIG_SOFTMMU
     r0 = 3;
     r1 = 4;
     r2 = 0;
@@ -722,13 +722,13 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 
 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase;
+    int addr_reg, r0, r1, data_reg, data_reg2, bswap, rbase;
 #ifdef CONFIG_SOFTMMU
-    int r2, ir;
+    int mem_index, r2, ir;
     void *label1_ptr, *label2_ptr;
-#endif
 #if TARGET_LONG_BITS == 64
     int addr_reg2;
+#endif
 #endif
 
     data_reg = *args++;
@@ -737,12 +737,12 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
     else
         data_reg2 = 0;
     addr_reg = *args++;
+
+#ifdef CONFIG_SOFTMMU
 #if TARGET_LONG_BITS == 64
     addr_reg2 = *args++;
 #endif
     mem_index = *args;
-
-#ifdef CONFIG_SOFTMMU
     r0 = 3;
     r1 = 4;
     r2 = 0;
index 56ff1103fa8c3782d139b44991d17780e3e37f14..9cb5b51b762a65d1df53350392745a9e20b80cbd 100644 (file)
@@ -773,7 +773,7 @@ void test_fops(double a, double b)
 
 void fpu_clear_exceptions(void)
 {
-    struct __attribute__((packed)) {
+    struct QEMU_PACKED {
         uint16_t fpuc;
         uint16_t dummy1;
         uint16_t fpus;
@@ -924,7 +924,7 @@ void test_fbcd(double a)
 
 void test_fenv(void)
 {
-    struct __attribute__((packed)) {
+    struct QEMU_PACKED {
         uint16_t fpuc;
         uint16_t dummy1;
         uint16_t fpus;
@@ -934,7 +934,7 @@ void test_fenv(void)
         uint32_t ignored[4];
         long double fpregs[8];
     } float_env32;
-    struct __attribute__((packed)) {
+    struct QEMU_PACKED {
         uint16_t fpuc;
         uint16_t fpus;
         uint16_t fptag;
@@ -1279,7 +1279,7 @@ void test_segs(void)
     struct {
         uint32_t offset;
         uint16_t seg;
-    } __attribute__((packed)) segoff;
+    } QEMU_PACKED segoff;
 
     ldt.entry_number = 1;
     ldt.base_addr = (unsigned long)&seg_data1;
@@ -1441,7 +1441,7 @@ void test_misc(void)
         /* XXX: see if Intel Core2 and AMD64 behavior really
            differ. Here we implemented the Intel way which is not
            compatible yet with QEMU. */
-        static struct __attribute__((packed)) {
+        static struct QEMU_PACKED {
             uint64_t offset;
             uint16_t seg;
         } desc;
index 234ed97088d308eaa947cc970a10f0a33eef07a5..7265a9445d0f8e0c3b0c281180fb5701656c5af1 100644 (file)
@@ -4,7 +4,7 @@
 #include "../cutils.c"
 #include "../path.c"
 #include "../trace.c"
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 #include "../simpletrace.c"
 #endif
 
index dc300a29b198f34bc970f500f90fbdb6e007c169..08ffedfdd1a94a8f6f88cb9d2ddea1344661a831 100644 (file)
 #
 # [disable] <name>(<type1> <arg1>[, <type2> <arg2>] ...) "<format-string>"
 #
-# Example: qemu_malloc(size_t size) "size %zu"
+# Example: g_malloc(size_t size) "size %zu"
 #
 # The "disable" keyword will build without the trace event.
-# In case of 'simple' trace backend, it will allow the trace event to be
-# compiled, but this would be turned off by default. It can be toggled on via
-# the monitor.
 #
 # The <name> must be a valid as a C function name.
 #
 # The <format-string> should be a sprintf()-compatible format string.
 
 # qemu-malloc.c
-disable qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
-disable qemu_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
-disable qemu_free(void *ptr) "ptr %p"
+g_malloc(size_t size, void *ptr) "size %zu ptr %p"
+g_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
+g_free(void *ptr) "ptr %p"
 
 # osdep.c
-disable qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
-disable qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
-disable qemu_vfree(void *ptr) "ptr %p"
+qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
+qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
+qemu_vfree(void *ptr) "ptr %p"
 
 # hw/virtio.c
-disable virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
-disable virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
-disable virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
-disable virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
-disable virtio_irq(void *vq) "vq %p"
-disable virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
+virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
+virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
+virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
+virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
+virtio_irq(void *vq) "vq %p"
+virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
 
 # hw/virtio-serial-bus.c
-disable virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
-disable virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
-disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
-disable virtio_serial_handle_control_message_port(unsigned int port) "port %u"
+virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
+virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
+virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
+virtio_serial_handle_control_message_port(unsigned int port) "port %u"
 
 # hw/virtio-console.c
-disable virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
-disable virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
-disable virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
+virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
+virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
+virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
 
 # block.c
-disable multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
-disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
-disable bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
-disable bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
-disable bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
-disable bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
-disable bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
-disable bdrv_set_locked(void *bs, int locked) "bs %p locked %d"
-disable bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
-disable bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
-disable bdrv_co_io(int is_write, void *acb) "is_write %d acb %p"
+multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
+bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
+bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
+bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
+bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
+bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_set_locked(void *bs, int locked) "bs %p locked %d"
+bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_io(int is_write, void *acb) "is_write %d acb %p"
 
 # hw/virtio-blk.c
-disable virtio_blk_req_complete(void *req, int status) "req %p status %d"
-disable virtio_blk_rw_complete(void *req, int ret) "req %p ret %d"
-disable virtio_blk_handle_write(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
+virtio_blk_req_complete(void *req, int status) "req %p status %d"
+virtio_blk_rw_complete(void *req, int ret) "req %p ret %d"
+virtio_blk_handle_write(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
 
 # posix-aio-compat.c
-disable paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d"
-disable paio_complete(void *acb, void *opaque, int ret) "acb %p opaque %p ret %d"
-disable paio_cancel(void *acb, void *opaque) "acb %p opaque %p"
+paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d"
+paio_complete(void *acb, void *opaque, int ret) "acb %p opaque %p ret %d"
+paio_cancel(void *acb, void *opaque) "acb %p opaque %p"
 
 # ioport.c
-disable cpu_in(unsigned int addr, unsigned int val) "addr %#x value %u"
-disable cpu_out(unsigned int addr, unsigned int val) "addr %#x value %u"
+cpu_in(unsigned int addr, unsigned int val) "addr %#x value %u"
+cpu_out(unsigned int addr, unsigned int val) "addr %#x value %u"
 
 # balloon.c
 # Since requests are raised via monitor, not many tracepoints are needed.
-disable balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu"
+balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu"
 
 # hw/apic.c
-disable apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
-disable apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d trigger_mode %d"
-disable cpu_set_apic_base(uint64_t val) "%016"PRIx64""
-disable cpu_get_apic_base(uint64_t val) "%016"PRIx64""
-disable apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
-disable apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
+apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
+apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d trigger_mode %d"
+cpu_set_apic_base(uint64_t val) "%016"PRIx64""
+cpu_get_apic_base(uint64_t val) "%016"PRIx64""
+apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
+apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
 # coalescing
-disable apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
-disable apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
-disable apic_set_irq(int apic_irq_delivered) "coalescing %d"
+apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
+apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
+apic_set_irq(int apic_irq_delivered) "coalescing %d"
 
 # hw/cs4231.c
-disable cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) "read dreg %d: 0x%02x"
-disable cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
-disable cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
-disable cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
+cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) "read dreg %d: 0x%02x"
+cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
+cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
+cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
 
 # hw/ds1225y.c
-disable nvram_read(uint32_t addr, uint32_t ret) "read addr %d: 0x%02x"
-disable nvram_write(uint32_t addr, uint32_t old, uint32_t val) "write addr %d: 0x%02x -> 0x%02x"
+nvram_read(uint32_t addr, uint32_t ret) "read addr %d: 0x%02x"
+nvram_write(uint32_t addr, uint32_t old, uint32_t val) "write addr %d: 0x%02x -> 0x%02x"
 
 # hw/eccmemctl.c
-disable ecc_mem_writel_mer(uint32_t val) "Write memory enable %08x"
-disable ecc_mem_writel_mdr(uint32_t val) "Write memory delay %08x"
-disable ecc_mem_writel_mfsr(uint32_t val) "Write memory fault status %08x"
-disable ecc_mem_writel_vcr(uint32_t val) "Write slot configuration %08x"
-disable ecc_mem_writel_dr(uint32_t val) "Write diagnostic %08x"
-disable ecc_mem_writel_ecr0(uint32_t val) "Write event count 1 %08x"
-disable ecc_mem_writel_ecr1(uint32_t val) "Write event count 2 %08x"
-disable ecc_mem_readl_mer(uint32_t ret) "Read memory enable %08x"
-disable ecc_mem_readl_mdr(uint32_t ret) "Read memory delay %08x"
-disable ecc_mem_readl_mfsr(uint32_t ret) "Read memory fault status %08x"
-disable ecc_mem_readl_vcr(uint32_t ret) "Read slot configuration %08x"
-disable ecc_mem_readl_mfar0(uint32_t ret) "Read memory fault address 0 %08x"
-disable ecc_mem_readl_mfar1(uint32_t ret) "Read memory fault address 1 %08x"
-disable ecc_mem_readl_dr(uint32_t ret) "Read diagnostic %08x"
-disable ecc_mem_readl_ecr0(uint32_t ret) "Read event count 1 %08x"
-disable ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
-disable ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
-disable ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
+ecc_mem_writel_mer(uint32_t val) "Write memory enable %08x"
+ecc_mem_writel_mdr(uint32_t val) "Write memory delay %08x"
+ecc_mem_writel_mfsr(uint32_t val) "Write memory fault status %08x"
+ecc_mem_writel_vcr(uint32_t val) "Write slot configuration %08x"
+ecc_mem_writel_dr(uint32_t val) "Write diagnostic %08x"
+ecc_mem_writel_ecr0(uint32_t val) "Write event count 1 %08x"
+ecc_mem_writel_ecr1(uint32_t val) "Write event count 2 %08x"
+ecc_mem_readl_mer(uint32_t ret) "Read memory enable %08x"
+ecc_mem_readl_mdr(uint32_t ret) "Read memory delay %08x"
+ecc_mem_readl_mfsr(uint32_t ret) "Read memory fault status %08x"
+ecc_mem_readl_vcr(uint32_t ret) "Read slot configuration %08x"
+ecc_mem_readl_mfar0(uint32_t ret) "Read memory fault address 0 %08x"
+ecc_mem_readl_mfar1(uint32_t ret) "Read memory fault address 1 %08x"
+ecc_mem_readl_dr(uint32_t ret) "Read diagnostic %08x"
+ecc_mem_readl_ecr0(uint32_t ret) "Read event count 1 %08x"
+ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
+ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
+ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
 
 # hw/lance.c
-disable lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
-disable lance_mem_writew(uint64_t addr, uint32_t val) "addr=%"PRIx64"val=0x%04x"
+lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
+lance_mem_writew(uint64_t addr, uint32_t val) "addr=%"PRIx64"val=0x%04x"
 
 # hw/slavio_intctl.c
-disable slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = %x"
-disable slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = %x"
-disable slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Cleared cpu %d irq mask %x, curmask %x"
-disable slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Set cpu %d irq mask %x, curmask %x"
-disable slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) "read system reg 0x%"PRIx64" = %x"
-disable slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) "write system reg 0x%"PRIx64" = %x"
-disable slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) "Enabled master irq mask %x, curmask %x"
-disable slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) "Disabled master irq mask %x, curmask %x"
-disable slavio_intctlm_mem_writel_target(uint32_t cpu) "Set master irq cpu %d"
-disable slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) "pending %x disabled %x"
-disable slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) "Set cpu %d irq %d -> pil %d level %d"
-disable slavio_set_timer_irq_cpu(int cpu, int level) "Set cpu %d local timer level %d"
+slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = %x"
+slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = %x"
+slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Cleared cpu %d irq mask %x, curmask %x"
+slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Set cpu %d irq mask %x, curmask %x"
+slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) "read system reg 0x%"PRIx64" = %x"
+slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) "write system reg 0x%"PRIx64" = %x"
+slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) "Enabled master irq mask %x, curmask %x"
+slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) "Disabled master irq mask %x, curmask %x"
+slavio_intctlm_mem_writel_target(uint32_t cpu) "Set master irq cpu %d"
+slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) "pending %x disabled %x"
+slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) "Set cpu %d irq %d -> pil %d level %d"
+slavio_set_timer_irq_cpu(int cpu, int level) "Set cpu %d local timer level %d"
 
 # hw/slavio_misc.c
-disable slavio_misc_update_irq_raise(void) "Raise IRQ"
-disable slavio_misc_update_irq_lower(void) "Lower IRQ"
-disable slavio_set_power_fail(int power_failing, uint8_t config) "Power fail: %d, config: %d"
-disable slavio_cfg_mem_writeb(uint32_t val) "Write config %02x"
-disable slavio_cfg_mem_readb(uint32_t ret) "Read config %02x"
-disable slavio_diag_mem_writeb(uint32_t val) "Write diag %02x"
-disable slavio_diag_mem_readb(uint32_t ret) "Read diag %02x"
-disable slavio_mdm_mem_writeb(uint32_t val) "Write modem control %02x"
-disable slavio_mdm_mem_readb(uint32_t ret) "Read modem control %02x"
-disable slavio_aux1_mem_writeb(uint32_t val) "Write aux1 %02x"
-disable slavio_aux1_mem_readb(uint32_t ret) "Read aux1 %02x"
-disable slavio_aux2_mem_writeb(uint32_t val) "Write aux2 %02x"
-disable slavio_aux2_mem_readb(uint32_t ret) "Read aux2 %02x"
-disable apc_mem_writeb(uint32_t val) "Write power management %02x"
-disable apc_mem_readb(uint32_t ret) "Read power management %02x"
-disable slavio_sysctrl_mem_writel(uint32_t val) "Write system control %08x"
-disable slavio_sysctrl_mem_readl(uint32_t ret) "Read system control %08x"
-disable slavio_led_mem_writew(uint32_t val) "Write diagnostic LED %04x"
-disable slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED %04x"
+slavio_misc_update_irq_raise(void) "Raise IRQ"
+slavio_misc_update_irq_lower(void) "Lower IRQ"
+slavio_set_power_fail(int power_failing, uint8_t config) "Power fail: %d, config: %d"
+slavio_cfg_mem_writeb(uint32_t val) "Write config %02x"
+slavio_cfg_mem_readb(uint32_t ret) "Read config %02x"
+slavio_diag_mem_writeb(uint32_t val) "Write diag %02x"
+slavio_diag_mem_readb(uint32_t ret) "Read diag %02x"
+slavio_mdm_mem_writeb(uint32_t val) "Write modem control %02x"
+slavio_mdm_mem_readb(uint32_t ret) "Read modem control %02x"
+slavio_aux1_mem_writeb(uint32_t val) "Write aux1 %02x"
+slavio_aux1_mem_readb(uint32_t ret) "Read aux1 %02x"
+slavio_aux2_mem_writeb(uint32_t val) "Write aux2 %02x"
+slavio_aux2_mem_readb(uint32_t ret) "Read aux2 %02x"
+apc_mem_writeb(uint32_t val) "Write power management %02x"
+apc_mem_readb(uint32_t ret) "Read power management %02x"
+slavio_sysctrl_mem_writel(uint32_t val) "Write system control %08x"
+slavio_sysctrl_mem_readl(uint32_t ret) "Read system control %08x"
+slavio_led_mem_writew(uint32_t val) "Write diagnostic LED %04x"
+slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED %04x"
 
 # hw/slavio_timer.c
-disable slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) "limit %"PRIx64" count %x%08x"
-disable slavio_timer_irq(uint32_t counthigh, uint32_t count) "callback: count %x%08x"
-disable slavio_timer_mem_readl_invalid(uint64_t addr) "invalid read address %"PRIx64""
-disable slavio_timer_mem_readl(uint64_t addr, uint32_t ret) "read %"PRIx64" = %08x"
-disable slavio_timer_mem_writel(uint64_t addr, uint32_t val) "write %"PRIx64" = %08x"
-disable slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) "processor %d user timer set to %016"PRIx64""
-disable slavio_timer_mem_writel_counter_invalid(void) "not user timer"
-disable slavio_timer_mem_writel_status_start(unsigned int timer_index) "processor %d user timer started"
-disable slavio_timer_mem_writel_status_stop(unsigned int timer_index) "processor %d user timer stopped"
-disable slavio_timer_mem_writel_mode_user(unsigned int timer_index) "processor %d changed from counter to user timer"
-disable slavio_timer_mem_writel_mode_counter(unsigned int timer_index) "processor %d changed from user timer to counter"
-disable slavio_timer_mem_writel_mode_invalid(void) "not system timer"
-disable slavio_timer_mem_writel_invalid(uint64_t addr) "invalid write address %"PRIx64""
+slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) "limit %"PRIx64" count %x%08x"
+slavio_timer_irq(uint32_t counthigh, uint32_t count) "callback: count %x%08x"
+slavio_timer_mem_readl_invalid(uint64_t addr) "invalid read address %"PRIx64""
+slavio_timer_mem_readl(uint64_t addr, uint32_t ret) "read %"PRIx64" = %08x"
+slavio_timer_mem_writel(uint64_t addr, uint32_t val) "write %"PRIx64" = %08x"
+slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) "processor %d user timer set to %016"PRIx64""
+slavio_timer_mem_writel_counter_invalid(void) "not user timer"
+slavio_timer_mem_writel_status_start(unsigned int timer_index) "processor %d user timer started"
+slavio_timer_mem_writel_status_stop(unsigned int timer_index) "processor %d user timer stopped"
+slavio_timer_mem_writel_mode_user(unsigned int timer_index) "processor %d changed from counter to user timer"
+slavio_timer_mem_writel_mode_counter(unsigned int timer_index) "processor %d changed from user timer to counter"
+slavio_timer_mem_writel_mode_invalid(void) "not system timer"
+slavio_timer_mem_writel_invalid(uint64_t addr) "invalid write address %"PRIx64""
 
 # hw/sparc32_dma.c
-disable ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64""
-disable ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64""
-disable sparc32_dma_set_irq_raise(void) "Raise IRQ"
-disable sparc32_dma_set_irq_lower(void) "Lower IRQ"
-disable espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
-disable espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
-disable sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg %"PRIx64": 0x%08x"
-disable sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write dmareg %"PRIx64": 0x%08x -> 0x%08x"
-disable sparc32_dma_enable_raise(void) "Raise DMA enable"
-disable sparc32_dma_enable_lower(void) "Lower DMA enable"
+ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64""
+ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64""
+sparc32_dma_set_irq_raise(void) "Raise IRQ"
+sparc32_dma_set_irq_lower(void) "Lower IRQ"
+espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
+espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
+sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg %"PRIx64": 0x%08x"
+sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write dmareg %"PRIx64": 0x%08x -> 0x%08x"
+sparc32_dma_enable_raise(void) "Raise DMA enable"
+sparc32_dma_enable_lower(void) "Lower DMA enable"
 
 # hw/sun4m.c
-disable sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
-disable sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
-disable sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
-disable sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"
+sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
+sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
+sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
+sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"
 
 # hw/sun4m_iommu.c
-disable sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) "read reg[%"PRIx64"] = %x"
-disable sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) "write reg[%"PRIx64"] = %x"
-disable sun4m_iommu_mem_writel_ctrl(uint64_t iostart) "iostart = %"PRIx64""
-disable sun4m_iommu_mem_writel_tlbflush(uint32_t val) "tlb flush %x"
-disable sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
-disable sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
-disable sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
-disable sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64""
+sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) "read reg[%"PRIx64"] = %x"
+sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) "write reg[%"PRIx64"] = %x"
+sun4m_iommu_mem_writel_ctrl(uint64_t iostart) "iostart = %"PRIx64""
+sun4m_iommu_mem_writel_tlbflush(uint32_t val) "tlb flush %x"
+sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
+sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
+sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
+sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64""
 
 # hw/usb-ehci.c
-disable usb_ehci_reset(void) "=== RESET ==="
-disable usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
-disable usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
-disable usb_ehci_mmio_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
-disable usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
-disable usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
-disable usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
-disable usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr) "QH @ %08x - rl %d, mplen %d, eps %d, ep %d, dev %d"
-disable usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i) "QH @ %08x - c %d, h %d, dtc %d, i %d"
-disable usb_ehci_qtd_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t altnext) "q %p - QTD @ %08x: next %08x altnext %08x"
-disable usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid) "QTD @ %08x - tbytes %d, cpage %d, cerr %d, pid %d"
-disable usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr) "QTD @ %08x - ioc %d, active %d, halt %d, babble %d, xacterr %d"
-disable usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr) "ITD @ %08x: next %08x - mplen %d, mult %d, ep %d, dev %d"
-disable usb_ehci_port_attach(uint32_t port, const char *device) "attach port #%d - %s"
-disable usb_ehci_port_detach(uint32_t port) "detach port #%d"
-disable usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
-disable usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos) "write %d, cpage %d, offset 0x%03x, addr 0x%08x, len %d, bufpos %d"
-disable usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
+usb_ehci_reset(void) "=== RESET ==="
+usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
+usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
+usb_ehci_mmio_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
+usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
+usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
+usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
+usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr) "QH @ %08x - rl %d, mplen %d, eps %d, ep %d, dev %d"
+usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i) "QH @ %08x - c %d, h %d, dtc %d, i %d"
+usb_ehci_qtd_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t altnext) "q %p - QTD @ %08x: next %08x altnext %08x"
+usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid) "QTD @ %08x - tbytes %d, cpage %d, cerr %d, pid %d"
+usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr) "QTD @ %08x - ioc %d, active %d, halt %d, babble %d, xacterr %d"
+usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr) "ITD @ %08x: next %08x - mplen %d, mult %d, ep %d, dev %d"
+usb_ehci_port_attach(uint32_t port, const char *device) "attach port #%d - %s"
+usb_ehci_port_detach(uint32_t port) "detach port #%d"
+usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
+usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos) "write %d, cpage %d, offset 0x%03x, addr 0x%08x, len %d, bufpos %d"
+usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
 
 # hw/usb-desc.c
-disable usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
-disable usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
-disable usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
-disable usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
-disable usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
-disable usb_set_addr(int addr) "dev %d"
-disable usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
-disable usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
-disable usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
+usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
+usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
+usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
+usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
+usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
+usb_set_addr(int addr) "dev %d"
+usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
+usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
+usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
 
 # hw/scsi-bus.c
-disable scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
-disable scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
-disable scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64""
-disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
-disable scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
-disable scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target %d lun %d tag %d page %#02x/%#02x"
-disable scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
+scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
+scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64""
+scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
+scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
+scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target %d lun %d tag %d page %#02x/%#02x"
+scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
 
 # vl.c
-disable vm_state_notify(int running, int reason) "running %d reason %d"
+vm_state_notify(int running, int reason) "running %d reason %d"
 
 # block/qed-l2-cache.c
-disable qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
-disable qed_unref_l2_cache_entry(void *entry, int ref) "entry %p ref %d"
-disable qed_find_l2_cache_entry(void *l2_cache, void *entry, uint64_t offset, int ref) "l2_cache %p entry %p offset %"PRIu64" ref %d"
+qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
+qed_unref_l2_cache_entry(void *entry, int ref) "entry %p ref %d"
+qed_find_l2_cache_entry(void *l2_cache, void *entry, uint64_t offset, int ref) "l2_cache %p entry %p offset %"PRIu64" ref %d"
 
 # block/qed-table.c
-disable qed_read_table(void *s, uint64_t offset, void *table) "s %p offset %"PRIu64" table %p"
-disable qed_read_table_cb(void *s, void *table, int ret) "s %p table %p ret %d"
-disable qed_write_table(void *s, uint64_t offset, void *table, unsigned int index, unsigned int n) "s %p offset %"PRIu64" table %p index %u n %u"
-disable qed_write_table_cb(void *s, void *table, int flush, int ret) "s %p table %p flush %d ret %d"
+qed_read_table(void *s, uint64_t offset, void *table) "s %p offset %"PRIu64" table %p"
+qed_read_table_cb(void *s, void *table, int ret) "s %p table %p ret %d"
+qed_write_table(void *s, uint64_t offset, void *table, unsigned int index, unsigned int n) "s %p offset %"PRIu64" table %p index %u n %u"
+qed_write_table_cb(void *s, void *table, int flush, int ret) "s %p table %p flush %d ret %d"
 
 # block/qed.c
-disable qed_need_check_timer_cb(void *s) "s %p"
-disable qed_start_need_check_timer(void *s) "s %p"
-disable qed_cancel_need_check_timer(void *s) "s %p"
-disable qed_aio_complete(void *s, void *acb, int ret) "s %p acb %p ret %d"
-disable qed_aio_setup(void *s, void *acb, int64_t sector_num, int nb_sectors, void *opaque, int is_write) "s %p acb %p sector_num %"PRId64" nb_sectors %d opaque %p is_write %d"
-disable qed_aio_next_io(void *s, void *acb, int ret, uint64_t cur_pos) "s %p acb %p ret %d cur_pos %"PRIu64""
-disable qed_aio_read_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
-disable qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
-disable qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
-disable qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
-disable qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_need_check_timer_cb(void *s) "s %p"
+qed_start_need_check_timer(void *s) "s %p"
+qed_cancel_need_check_timer(void *s) "s %p"
+qed_aio_complete(void *s, void *acb, int ret) "s %p acb %p ret %d"
+qed_aio_setup(void *s, void *acb, int64_t sector_num, int nb_sectors, void *opaque, int is_write) "s %p acb %p sector_num %"PRId64" nb_sectors %d opaque %p is_write %d"
+qed_aio_next_io(void *s, void *acb, int ret, uint64_t cur_pos) "s %p acb %p ret %d cur_pos %"PRIu64""
+qed_aio_read_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
+qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
+qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+
+# hw/g364fb.c
+g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
+g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
 
 # hw/grlib_gptimer.c
-disable grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
-disable grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x"
-disable grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
-disable grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
-disable grlib_gptimer_hit(int id) "timer:%d HIT"
-disable grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
-disable grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
+grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
+grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x"
+grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
+grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
+grlib_gptimer_hit(int id) "timer:%d HIT"
+grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
+grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
 
 # hw/grlib_irqmp.c
-disable grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x\n"
-disable grlib_irqmp_ack(int intno) "interrupt:%d"
-disable grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
-disable grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64""
-disable grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
+grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x\n"
+grlib_irqmp_ack(int intno) "interrupt:%d"
+grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
+grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64""
+grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
 
 # hw/grlib_apbuart.c
-disable grlib_apbuart_event(int event) "event:%d"
-disable grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
+grlib_apbuart_event(int event) "event:%d"
+grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
 
 # hw/leon3.c
-disable leon3_set_irq(int intno) "Set CPU IRQ %d"
-disable leon3_reset_irq(int intno) "Reset CPU IRQ %d"
+leon3_set_irq(int intno) "Set CPU IRQ %d"
+leon3_reset_irq(int intno) "Reset CPU IRQ %d"
 
 # spice-qemu-char.c
-disable spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
-disable spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
-disable spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
-disable spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
+spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
+spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
+spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
+spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
 
 # hw/lm32_pic.c
-disable lm32_pic_raise_irq(void) "Raise CPU interrupt"
-disable lm32_pic_lower_irq(void) "Lower CPU interrupt"
-disable lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d"
-disable lm32_pic_set_im(uint32_t im) "im 0x%08x"
-disable lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
-disable lm32_pic_get_im(uint32_t im) "im 0x%08x"
-disable lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
+lm32_pic_raise_irq(void) "Raise CPU interrupt"
+lm32_pic_lower_irq(void) "Lower CPU interrupt"
+lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d"
+lm32_pic_set_im(uint32_t im) "im 0x%08x"
+lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
+lm32_pic_get_im(uint32_t im) "im 0x%08x"
+lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
 
 # hw/lm32_juart.c
-disable lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
-disable lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
-disable lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
-disable lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
+lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
+lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
+lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
+lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
 
 # hw/lm32_timer.c
-disable lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_timer_hit(void) "timer hit"
-disable lm32_timer_irq_state(int level) "irq state %d"
+lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_timer_hit(void) "timer hit"
+lm32_timer_irq_state(int level) "irq state %d"
 
 # hw/lm32_uart.c
-disable lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_uart_irq_state(int level) "irq state %d"
+lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_uart_irq_state(int level) "irq state %d"
 
 # hw/lm32_sys.c
-disable lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
 
 # hw/milkymist-ac97.c
-disable milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
-disable milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
-disable milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
-disable milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
-disable milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
-disable milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
-disable milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
-disable milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
+milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
+milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
+milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
+milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
+milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
+milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
+milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
+milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
 
 # hw/milkymist-hpdmc.c
-disable milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
-disable milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
 
 # hw/milkymist-memcard.c
-disable milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 
 # hw/milkymist-minimac2.c
-disable milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-disable milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-disable milkymist_minimac2_tx_frame(uint32_t length) "length %u"
-disable milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
-disable milkymist_minimac2_drop_rx_frame(const void *buf) "buf %p"
-disable milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
-disable milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
-disable milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
-disable milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
+milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+milkymist_minimac2_tx_frame(uint32_t length) "length %u"
+milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
+milkymist_minimac2_drop_rx_frame(const void *buf) "buf %p"
+milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
+milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
+milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
+milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
 
 # hw/milkymist-pfpu.c
-disable milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
-disable milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
+milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
+milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
 
 # hw/milkymist-softusb.c
-disable milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_softusb_mevt(uint8_t m) "m %d"
-disable milkymist_softusb_kevt(uint8_t m) "m %d"
-disable milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs) "dx %d dy %d dz %d bs %02x"
-disable milkymist_softusb_pulse_irq(void) "Pulse IRQ"
+milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_softusb_mevt(uint8_t m) "m %d"
+milkymist_softusb_kevt(uint8_t m) "m %d"
+milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs) "dx %d dy %d dz %d bs %02x"
+milkymist_softusb_pulse_irq(void) "Pulse IRQ"
 
 # hw/milkymist-sysctl.c
-disable milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_sysctl_icap_write(uint32_t value) "value %08x"
-disable milkymist_sysctl_start_timer0(void) "Start timer0"
-disable milkymist_sysctl_stop_timer0(void) "Stop timer0"
-disable milkymist_sysctl_start_timer1(void) "Start timer1"
-disable milkymist_sysctl_stop_timer1(void) "Stop timer1"
-disable milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
-disable milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
+milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_sysctl_icap_write(uint32_t value) "value %08x"
+milkymist_sysctl_start_timer0(void) "Start timer0"
+milkymist_sysctl_stop_timer0(void) "Stop timer0"
+milkymist_sysctl_start_timer1(void) "Start timer1"
+milkymist_sysctl_stop_timer1(void) "Stop timer1"
+milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
+milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
 
 # hw/milkymist-tmu2.c
-disable milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_tmu2_start(void) "Start TMU"
-disable milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
+milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_tmu2_start(void) "Start TMU"
+milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
 
 # hw/milkymist-uart.c
-disable milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_uart_pulse_irq_rx(void) "Pulse IRQ RX"
-disable milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX"
+milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_uart_pulse_irq_rx(void) "Pulse IRQ RX"
+milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX"
 
 # hw/milkymist-vgafb.c
-disable milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 
 # xen-all.c
-disable xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
-disable xen_client_set_memory(uint64_t start_addr, unsigned long size, unsigned long phys_offset, bool log_dirty) "%#"PRIx64" size %#lx, offset %#lx, log_dirty %i"
+xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
+xen_client_set_memory(uint64_t start_addr, unsigned long size, unsigned long phys_offset, bool log_dirty) "%#"PRIx64" size %#lx, offset %#lx, log_dirty %i"
 
 # xen-mapcache.c
-disable xen_map_cache(uint64_t phys_addr) "want %#"PRIx64""
-disable xen_remap_bucket(uint64_t index) "index %#"PRIx64""
-disable xen_map_cache_return(void* ptr) "%p"
-disable xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64""
-disable xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
+xen_map_cache(uint64_t phys_addr) "want %#"PRIx64""
+xen_remap_bucket(uint64_t index) "index %#"PRIx64""
+xen_map_cache_return(void* ptr) "%p"
+xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64""
+xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
 
 # exec.c
-disable qemu_put_ram_ptr(void* addr) "%p"
+qemu_put_ram_ptr(void* addr) "%p"
 
 # hw/xen_platform.c
-disable xen_platform_log(char *s) "xen platform: %s"
+xen_platform_log(char *s) "xen platform: %s"
 
 # qemu-coroutine.c
-disable qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p opaque %p"
-disable qemu_coroutine_yield(void *from, void *to) "from %p to %p"
-disable qemu_coroutine_terminate(void *co) "self %p"
+qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p opaque %p"
+qemu_coroutine_yield(void *from, void *to) "from %p to %p"
+qemu_coroutine_terminate(void *co) "self %p"
 
 # qemu-coroutine-lock.c
-disable qemu_co_queue_next_bh(void) ""
-disable qemu_co_queue_next(void *next) "next %p"
-disable qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
-disable qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
-disable qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
-disable qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
+qemu_co_queue_next_bh(void) ""
+qemu_co_queue_next(void *next) "next %p"
+qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
 
 # hw/escc.c
-disable escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
-disable escc_get_queue(char channel, int val) "channel %c get 0x%02x"
-disable escc_update_irq(int irq) "IRQ = %d"
-disable escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) "channel %c: speed=%d parity=%c data=%d stop=%d"
-disable escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) "Write channel %c, reg[%d] = %2.2x"
-disable escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
-disable escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
-disable escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
-disable escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
-disable escc_sunkbd_event_in(int ch) "Untranslated keycode %2.2x"
-disable escc_sunkbd_event_out(int ch) "Translated keycode %2.2x"
-disable escc_kbd_command(int val) "Command %d"
-disable escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
+escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
+escc_get_queue(char channel, int val) "channel %c get 0x%02x"
+escc_update_irq(int irq) "IRQ = %d"
+escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) "channel %c: speed=%d parity=%c data=%d stop=%d"
+escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) "Write channel %c, reg[%d] = %2.2x"
+escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
+escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
+escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
+escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
+escc_sunkbd_event_in(int ch) "Untranslated keycode %2.2x"
+escc_sunkbd_event_out(int ch) "Translated keycode %2.2x"
+escc_kbd_command(int val) "Command %d"
+escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
diff --git a/trace/control.c b/trace/control.c
new file mode 100644 (file)
index 0000000..4c5527d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "trace/control.h"
+
+
+void trace_backend_init_events(const char *fname)
+{
+    if (fname == NULL) {
+        return;
+    }
+
+    FILE *fp = fopen(fname, "r");
+    if (!fp) {
+        fprintf(stderr, "error: could not open trace events file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+    char line_buf[1024];
+    while (fgets(line_buf, sizeof(line_buf), fp)) {
+        size_t len = strlen(line_buf);
+        if (len > 1) {              /* skip empty lines */
+            line_buf[len - 1] = '\0';
+            if (!trace_event_set_state(line_buf, true)) {
+                fprintf(stderr,
+                        "error: trace event '%s' does not exist\n", line_buf);
+                exit(1);
+            }
+        }
+    }
+    if (fclose(fp) != 0) {
+        fprintf(stderr, "error: closing file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+}
diff --git a/trace/control.h b/trace/control.h
new file mode 100644 (file)
index 0000000..2acaa42
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef TRACE_CONTROL_H
+#define TRACE_CONTROL_H
+
+#include "qemu-common.h"
+
+
+/** Print the state of all events. */
+void trace_print_events(FILE *stream, fprintf_function stream_printf);
+/** Set the state of an event.
+ *
+ * @return Whether the state changed.
+ */
+bool trace_event_set_state(const char *name, bool state);
+
+
+/** Initialize the tracing backend.
+ *
+ * @events Name of file with events to be enabled at startup; may be NULL.
+ *         Corresponds to commandline option "-trace events=...".
+ * @file   Name of trace output file; may be NULL.
+ *         Corresponds to commandline option "-trace file=...".
+ * @return Whether the backend could be successfully initialized.
+ */
+bool trace_backend_init(const char *events, const char *file);
+
+/** Generic function to initialize the state of events.
+ *
+ * @fname Name of file with events to enable; may be NULL.
+ */
+void trace_backend_init_events(const char *fname);
+
+#endif  /* TRACE_CONTROL_H */
diff --git a/trace/default.c b/trace/default.c
new file mode 100644 (file)
index 0000000..c9b27a2
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Default implementation for backend initialization from commandline.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "trace/control.h"
+
+
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
+{
+    fprintf(stderr, "warning: "
+            "cannot print the trace events with the current backend\n");
+    stream_printf(stream, "error: "
+                  "operation not supported with the current backend\n");
+}
+
+bool trace_event_set_state(const char *name, bool state)
+{
+    fprintf(stderr, "warning: "
+            "cannot set the state of a trace event with the current backend\n");
+    return false;
+}
+
+bool trace_backend_init(const char *events, const char *file)
+{
+    if (events) {
+        fprintf(stderr, "error: -trace events=...: "
+                "option not supported by the selected tracing backend\n");
+        return false;
+    }
+    if (file) {
+        fprintf(stderr, "error: -trace file=...: "
+                "option not supported by the selected tracing backend\n");
+        return false;
+    }
+    return true;
+}
diff --git a/trace/simple.c b/trace/simple.c
new file mode 100644 (file)
index 0000000..a609368
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+#include <signal.h>
+#include <pthread.h>
+#include "qemu-timer.h"
+#include "trace.h"
+#include "trace/control.h"
+
+/** Trace file header event ID */
+#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
+
+/** Trace file magic number */
+#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL
+
+/** Trace file version number, bump if format changes */
+#define HEADER_VERSION 0
+
+/** Records were dropped event ID */
+#define DROPPED_EVENT_ID (~(uint64_t)0 - 1)
+
+/** Trace record is valid */
+#define TRACE_RECORD_VALID ((uint64_t)1 << 63)
+
+/** Trace buffer entry */
+typedef struct {
+    uint64_t event;
+    uint64_t timestamp_ns;
+    uint64_t x1;
+    uint64_t x2;
+    uint64_t x3;
+    uint64_t x4;
+    uint64_t x5;
+    uint64_t x6;
+} TraceRecord;
+
+enum {
+    TRACE_BUF_LEN = 4096,
+    TRACE_BUF_FLUSH_THRESHOLD = TRACE_BUF_LEN / 4,
+};
+
+/*
+ * Trace records are written out by a dedicated thread.  The thread waits for
+ * records to become available, writes them out, and then waits again.
+ */
+static pthread_mutex_t trace_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t trace_available_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t trace_empty_cond = PTHREAD_COND_INITIALIZER;
+static bool trace_available;
+static bool trace_writeout_enabled;
+
+static TraceRecord trace_buf[TRACE_BUF_LEN];
+static unsigned int trace_idx;
+static FILE *trace_fp;
+static char *trace_file_name = NULL;
+
+/**
+ * Read a trace record from the trace buffer
+ *
+ * @idx         Trace buffer index
+ * @record      Trace record to fill
+ *
+ * Returns false if the record is not valid.
+ */
+static bool get_trace_record(unsigned int idx, TraceRecord *record)
+{
+    if (!(trace_buf[idx].event & TRACE_RECORD_VALID)) {
+        return false;
+    }
+
+    __sync_synchronize(); /* read memory barrier before accessing record */
+
+    *record = trace_buf[idx];
+    record->event &= ~TRACE_RECORD_VALID;
+    return true;
+}
+
+/**
+ * Kick writeout thread
+ *
+ * @wait        Whether to wait for writeout thread to complete
+ */
+static void flush_trace_file(bool wait)
+{
+    pthread_mutex_lock(&trace_lock);
+    trace_available = true;
+    pthread_cond_signal(&trace_available_cond);
+
+    if (wait) {
+        pthread_cond_wait(&trace_empty_cond, &trace_lock);
+    }
+
+    pthread_mutex_unlock(&trace_lock);
+}
+
+static void wait_for_trace_records_available(void)
+{
+    pthread_mutex_lock(&trace_lock);
+    while (!(trace_available && trace_writeout_enabled)) {
+        pthread_cond_signal(&trace_empty_cond);
+        pthread_cond_wait(&trace_available_cond, &trace_lock);
+    }
+    trace_available = false;
+    pthread_mutex_unlock(&trace_lock);
+}
+
+static void *writeout_thread(void *opaque)
+{
+    TraceRecord record;
+    unsigned int writeout_idx = 0;
+    unsigned int num_available, idx;
+    size_t unused __attribute__ ((unused));
+
+    for (;;) {
+        wait_for_trace_records_available();
+
+        num_available = trace_idx - writeout_idx;
+        if (num_available > TRACE_BUF_LEN) {
+            record = (TraceRecord){
+                .event = DROPPED_EVENT_ID,
+                .x1 = num_available,
+            };
+            unused = fwrite(&record, sizeof(record), 1, trace_fp);
+            writeout_idx += num_available;
+        }
+
+        idx = writeout_idx % TRACE_BUF_LEN;
+        while (get_trace_record(idx, &record)) {
+            trace_buf[idx].event = 0; /* clear valid bit */
+            unused = fwrite(&record, sizeof(record), 1, trace_fp);
+            idx = ++writeout_idx % TRACE_BUF_LEN;
+        }
+
+        fflush(trace_fp);
+    }
+    return NULL;
+}
+
+static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
+                  uint64_t x4, uint64_t x5, uint64_t x6)
+{
+    unsigned int idx;
+    uint64_t timestamp;
+
+    if (!trace_list[event].state) {
+        return;
+    }
+
+    timestamp = get_clock();
+
+    idx = __sync_fetch_and_add(&trace_idx, 1) % TRACE_BUF_LEN;
+    trace_buf[idx] = (TraceRecord){
+        .event = event,
+        .timestamp_ns = timestamp,
+        .x1 = x1,
+        .x2 = x2,
+        .x3 = x3,
+        .x4 = x4,
+        .x5 = x5,
+        .x6 = x6,
+    };
+    __sync_synchronize(); /* write barrier before marking as valid */
+    trace_buf[idx].event |= TRACE_RECORD_VALID;
+
+    if ((idx + 1) % TRACE_BUF_FLUSH_THRESHOLD == 0) {
+        flush_trace_file(false);
+    }
+}
+
+void trace0(TraceEventID event)
+{
+    trace(event, 0, 0, 0, 0, 0, 0);
+}
+
+void trace1(TraceEventID event, uint64_t x1)
+{
+    trace(event, x1, 0, 0, 0, 0, 0);
+}
+
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
+{
+    trace(event, x1, x2, 0, 0, 0, 0);
+}
+
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
+{
+    trace(event, x1, x2, x3, 0, 0, 0);
+}
+
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
+{
+    trace(event, x1, x2, x3, x4, 0, 0);
+}
+
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
+{
+    trace(event, x1, x2, x3, x4, x5, 0);
+}
+
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
+{
+    trace(event, x1, x2, x3, x4, x5, x6);
+}
+
+void st_set_trace_file_enabled(bool enable)
+{
+    if (enable == !!trace_fp) {
+        return; /* no change */
+    }
+
+    /* Halt trace writeout */
+    flush_trace_file(true);
+    trace_writeout_enabled = false;
+    flush_trace_file(true);
+
+    if (enable) {
+        static const TraceRecord header = {
+            .event = HEADER_EVENT_ID,
+            .timestamp_ns = HEADER_MAGIC,
+            .x1 = HEADER_VERSION,
+        };
+
+        trace_fp = fopen(trace_file_name, "w");
+        if (!trace_fp) {
+            return;
+        }
+
+        if (fwrite(&header, sizeof header, 1, trace_fp) != 1) {
+            fclose(trace_fp);
+            trace_fp = NULL;
+            return;
+        }
+
+        /* Resume trace writeout */
+        trace_writeout_enabled = true;
+        flush_trace_file(false);
+    } else {
+        fclose(trace_fp);
+        trace_fp = NULL;
+    }
+}
+
+/**
+ * Set the name of a trace file
+ *
+ * @file        The trace file name or NULL for the default name-<pid> set at
+ *              config time
+ */
+bool st_set_trace_file(const char *file)
+{
+    st_set_trace_file_enabled(false);
+
+    free(trace_file_name);
+
+    if (!file) {
+        if (asprintf(&trace_file_name, CONFIG_TRACE_FILE, getpid()) < 0) {
+            trace_file_name = NULL;
+            return false;
+        }
+    } else {
+        if (asprintf(&trace_file_name, "%s", file) < 0) {
+            trace_file_name = NULL;
+            return false;
+        }
+    }
+
+    st_set_trace_file_enabled(true);
+    return true;
+}
+
+void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+{
+    stream_printf(stream, "Trace file \"%s\" %s.\n",
+                  trace_file_name, trace_fp ? "on" : "off");
+}
+
+void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+{
+    unsigned int i;
+
+    for (i = 0; i < TRACE_BUF_LEN; i++) {
+        TraceRecord record;
+
+        if (!get_trace_record(i, &record)) {
+            continue;
+        }
+        stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64
+                      " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n",
+                      record.event, record.x1, record.x2,
+                      record.x3, record.x4, record.x5,
+                      record.x6);
+    }
+}
+
+void st_flush_trace_buffer(void)
+{
+    flush_trace_file(true);
+}
+
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        stream_printf(stream, "%s [Event ID %u] : state %u\n",
+                      trace_list[i].tp_name, i, trace_list[i].state);
+    }
+}
+
+bool trace_event_set_state(const char *name, bool state)
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        if (!strcmp(trace_list[i].tp_name, name)) {
+            trace_list[i].state = state;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool trace_backend_init(const char *events, const char *file)
+{
+    pthread_t thread;
+    pthread_attr_t attr;
+    sigset_t set, oldset;
+    int ret;
+
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    sigfillset(&set);
+    pthread_sigmask(SIG_SETMASK, &set, &oldset);
+    ret = pthread_create(&thread, &attr, writeout_thread, NULL);
+    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+
+    if (ret != 0) {
+        fprintf(stderr, "warning: unable to initialize simple trace backend\n");
+    } else {
+        atexit(st_flush_trace_buffer);
+        trace_backend_init_events(events);
+        st_set_trace_file(file);
+    }
+
+    return true;
+}
diff --git a/trace/simple.h b/trace/simple.h
new file mode 100644 (file)
index 0000000..466e75b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef TRACE_SIMPLE_H
+#define TRACE_SIMPLE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+typedef uint64_t TraceEventID;
+
+typedef struct {
+    const char *tp_name;
+    bool state;
+} TraceEvent;
+
+void trace0(TraceEventID event);
+void trace1(TraceEventID event, uint64_t x1);
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2);
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3);
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
+void st_print_trace(FILE *stream, fprintf_function stream_printf);
+void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
+void st_set_trace_file_enabled(bool enable);
+bool st_set_trace_file(const char *file);
+void st_flush_trace_buffer(void);
+
+#endif /* TRACE_SIMPLE_H */
diff --git a/trace/stderr.c b/trace/stderr.c
new file mode 100644 (file)
index 0000000..7107c4a
--- /dev/null
@@ -0,0 +1,37 @@
+#include "trace.h"
+#include "trace/control.h"
+
+
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        stream_printf(stream, "%s [Event ID %u] : state %u\n",
+                      trace_list[i].tp_name, i, trace_list[i].state);
+    }
+}
+
+bool trace_event_set_state(const char *name, bool state)
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        if (!strcmp(trace_list[i].tp_name, name)) {
+            trace_list[i].state = state;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool trace_backend_init(const char *events, const char *file)
+{
+    if (file) {
+        fprintf(stderr, "error: -trace file=...: "
+                "option not supported by the selected tracing backend\n");
+        return false;
+    }
+    trace_backend_init_events(events);
+    return true;
+}
diff --git a/trace/stderr.h b/trace/stderr.h
new file mode 100644 (file)
index 0000000..d575b61
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef TRACE_STDERR_H
+#define TRACE_STDERR_H
+
+typedef uint64_t TraceEventID;
+
+typedef struct {
+    const char *tp_name;
+    bool state;
+} TraceEvent;
+
+#endif /* ! TRACE_STDERR_H */
diff --git a/vl.c b/vl.c
index 9cd67a37465a685f5501577a7a87b64ce3445065..5ba9b358606b03cd9fa17d662407c81787cae6a7 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -111,6 +111,8 @@ int main(int argc, char **argv)
 #define main qemu_main
 #endif /* CONFIG_COCOA */
 
+#include <glib.h>
+
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "hw/usb.h"
@@ -156,7 +158,7 @@ int main(int argc, char **argv)
 #include "slirp/libslirp.h"
 
 #include "trace.h"
-#include "simpletrace.h"
+#include "trace/control.h"
 #include "qemu-queue.h"
 #include "cpus.h"
 #include "arch_init.h"
@@ -1321,6 +1323,75 @@ void qemu_system_vmstop_request(int reason)
     qemu_notify_event();
 }
 
+static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
+static int n_poll_fds;
+static int max_priority;
+
+static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
+                             fd_set *xfds, struct timeval *tv)
+{
+    GMainContext *context = g_main_context_default();
+    int i;
+    int timeout = 0, cur_timeout;
+
+    g_main_context_prepare(context, &max_priority);
+
+    n_poll_fds = g_main_context_query(context, max_priority, &timeout,
+                                      poll_fds, ARRAY_SIZE(poll_fds));
+    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
+
+    for (i = 0; i < n_poll_fds; i++) {
+        GPollFD *p = &poll_fds[i];
+
+        if ((p->events & G_IO_IN)) {
+            FD_SET(p->fd, rfds);
+            *max_fd = MAX(*max_fd, p->fd);
+        }
+        if ((p->events & G_IO_OUT)) {
+            FD_SET(p->fd, wfds);
+            *max_fd = MAX(*max_fd, p->fd);
+        }
+        if ((p->events & G_IO_ERR)) {
+            FD_SET(p->fd, xfds);
+            *max_fd = MAX(*max_fd, p->fd);
+        }
+    }
+
+    cur_timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 500) / 1000);
+    if (timeout >= 0 && timeout < cur_timeout) {
+        tv->tv_sec = timeout / 1000;
+        tv->tv_usec = (timeout % 1000) * 1000;
+    }
+}
+
+static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
+                             bool err)
+{
+    GMainContext *context = g_main_context_default();
+
+    if (!err) {
+        int i;
+
+        for (i = 0; i < n_poll_fds; i++) {
+            GPollFD *p = &poll_fds[i];
+
+            if ((p->events & G_IO_IN) && FD_ISSET(p->fd, rfds)) {
+                p->revents |= G_IO_IN;
+            }
+            if ((p->events & G_IO_OUT) && FD_ISSET(p->fd, wfds)) {
+                p->revents |= G_IO_OUT;
+            }
+            if ((p->events & G_IO_ERR) && FD_ISSET(p->fd, xfds)) {
+                p->revents |= G_IO_ERR;
+            }
+        }
+    }
+
+    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
+        g_main_context_dispatch(context);
+    }
+}
+
 int main_loop_wait(int nonblocking)
 {
     fd_set rfds, wfds, xfds;
@@ -1346,8 +1417,10 @@ int main_loop_wait(int nonblocking)
     FD_ZERO(&rfds);
     FD_ZERO(&wfds);
     FD_ZERO(&xfds);
+
     qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &tv);
 
     if (timeout > 0) {
         qemu_mutex_unlock_iothread();
@@ -1361,6 +1434,7 @@ int main_loop_wait(int nonblocking)
 
     qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
     slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
 
     qemu_run_all_timers();
 
@@ -1371,17 +1445,6 @@ int main_loop_wait(int nonblocking)
     return ret;
 }
 
-#ifndef CONFIG_IOTHREAD
-static int vm_request_pending(void)
-{
-    return powerdown_requested ||
-           reset_requested ||
-           shutdown_requested ||
-           debug_requested ||
-           vmstop_requested;
-}
-#endif
-
 qemu_irq qemu_system_powerdown;
 
 static void main_loop(void)
@@ -1396,14 +1459,7 @@ static void main_loop(void)
     qemu_main_loop_start();
 
     for (;;) {
-#ifdef CONFIG_IOTHREAD
         nonblocking = !kvm_enabled() && last_io > 0;
-#else
-        nonblocking = cpu_exec_all();
-        if (vm_request_pending()) {
-            nonblocking = true;
-        }
-#endif
 #ifdef CONFIG_PROFILER
         ti = profile_getclock();
 #endif
@@ -2088,20 +2144,20 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
 static gpointer malloc_and_trace(gsize n_bytes)
 {
     void *ptr = malloc(n_bytes);
-    trace_qemu_malloc(n_bytes, ptr);
+    trace_g_malloc(n_bytes, ptr);
     return ptr;
 }
 
 static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
 {
     void *ptr = realloc(mem, n_bytes);
-    trace_qemu_realloc(mem, n_bytes, ptr);
+    trace_g_realloc(mem, n_bytes, ptr);
     return ptr;
 }
 
 static void free_and_trace(gpointer mem)
 {
-    trace_qemu_free(mem);
+    trace_g_free(mem);
     free(mem);
 }
 
@@ -2130,7 +2186,6 @@ int main(int argc, char **argv, char **envp)
     int show_vnc_port = 0;
 #endif
     int defconfig = 1;
-    const char *trace_file = NULL;
     const char *log_mask = NULL;
     const char *log_file = NULL;
     GMemVTable mem_trace = {
@@ -2138,6 +2193,8 @@ int main(int argc, char **argv, char **envp)
         .realloc = realloc_and_trace,
         .free = free_and_trace,
     };
+    const char *trace_events = NULL;
+    const char *trace_file = NULL;
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
@@ -2928,14 +2985,16 @@ int main(int argc, char **argv, char **envp)
                 }
                 xen_mode = XEN_ATTACH;
                 break;
-#ifdef CONFIG_SIMPLE_TRACE
             case QEMU_OPTION_trace:
+            {
                 opts = qemu_opts_parse(qemu_find_opts("trace"), optarg, 0);
-                if (opts) {
-                    trace_file = qemu_opt_get(opts, "file");
+                if (!opts) {
+                    exit(1);
                 }
+                trace_events = qemu_opt_get(opts, "events");
+                trace_file = qemu_opt_get(opts, "file");
                 break;
-#endif
+            }
             case QEMU_OPTION_readconfig:
                 {
                     int ret = qemu_read_config_file(optarg);
@@ -2993,8 +3052,8 @@ int main(int argc, char **argv, char **envp)
         set_cpu_log(log_mask);
     }
 
-    if (!st_init(trace_file)) {
-        fprintf(stderr, "warning: unable to initialize simple trace backend\n");
+    if (!trace_backend_init(trace_events, trace_file)) {
+        exit(1);
     }
 
     /* If no data_dir is specified then try to find it relative to the
index 46d8d4d9ddf24d1eca5b1c8120f4b1eea6425e15..b7a9f4eb369c30f8de842807c04157eb3d5cd4a4 100644 (file)
--- a/x86_64.ld
+++ b/x86_64.ld
@@ -38,16 +38,16 @@ SECTIONS
   .rel.plt      :
   {
     *(.rel.plt)
-    PROVIDE_HIDDEN (__rel_iplt_start = .);
+    PROVIDE (__rel_iplt_start = .);
     *(.rel.iplt)
-    PROVIDE_HIDDEN (__rel_iplt_end = .);
+    PROVIDE (__rel_iplt_end = .);
   }
   .rela.plt       :
   {
     *(.rela.plt)
-    PROVIDE_HIDDEN (__rela_iplt_start = .);
+    PROVIDE (__rela_iplt_start = .);
     *(.rela.iplt)
-    PROVIDE_HIDDEN (__rela_iplt_end = .);
+    PROVIDE (__rela_iplt_end = .);
   }
   .init           :
   {
@@ -70,8 +70,6 @@ SECTIONS
   .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
   .rodata1        : { *(.rodata1) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
@@ -97,8 +95,8 @@ SECTIONS
   .data1          : { *(.data1) }
   .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table) }
   .dynamic        : { *(.dynamic) }
   .ctors          :
   {