summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--Makefile.hw1
-rw-r--r--Makefile.objs22
-rw-r--r--Makefile.target17
-rw-r--r--a.out.h2
-rw-r--r--arm.ld12
-rw-r--r--block.c99
-rw-r--r--block.h19
-rw-r--r--block/curl.c20
-rw-r--r--block/parallels.c2
-rw-r--r--block/qcow.c380
-rw-r--r--block/qcow2-cluster.c6
-rw-r--r--block/qcow2-refcount.c22
-rw-r--r--block/qcow2-snapshot.c17
-rw-r--r--block/qcow2.c418
-rw-r--r--block/qcow2.h2
-rw-r--r--block/sheepdog.c150
-rw-r--r--block/vmdk.c2
-rw-r--r--block/vvfat.c14
-rw-r--r--block_int.h8
-rw-r--r--blockdev.c15
-rw-r--r--compiler.h6
-rwxr-xr-xconfigure57
-rw-r--r--cpus.c143
-rw-r--r--docs/qapi-code-gen.txt2
-rw-r--r--docs/tracing.txt73
-rw-r--r--dyngen-exec.h14
-rw-r--r--fpu/softfloat.c28
-rw-r--r--fpu/softfloat.h8
-rw-r--r--hmp-commands.hx11
-rw-r--r--hppa.ld18
-rw-r--r--hw/9pfs/virtio-9p.h2
-rw-r--r--hw/acpi.c2
-rw-r--r--hw/an5206.c12
-rw-r--r--hw/apb_pci.c13
-rw-r--r--hw/arm-misc.h5
-rw-r--r--hw/armv7m.c22
-rw-r--r--hw/axis_dev88.c16
-rw-r--r--hw/bt.h332
-rw-r--r--hw/cirrus_vga.c2
-rw-r--r--hw/collie.c16
-rw-r--r--hw/dec_pci.c13
-rw-r--r--hw/dummy_m68k.c7
-rw-r--r--hw/flash.h23
-rw-r--r--hw/fw_cfg.c3
-rw-r--r--hw/g364fb.c361
-rw-r--r--hw/grackle_pci.c13
-rw-r--r--hw/gumstix.c28
-rw-r--r--hw/hpet_emul.h4
-rw-r--r--hw/ide/ahci.c9
-rw-r--r--hw/ide/ahci.h7
-rw-r--r--hw/ide/atapi.c33
-rw-r--r--hw/ide/core.c27
-rw-r--r--hw/ide/internal.h1
-rw-r--r--hw/ide/macio.c40
-rw-r--r--hw/integratorcp.c28
-rw-r--r--hw/leon3.c15
-rw-r--r--hw/lm32_boards.c29
-rw-r--r--hw/mainstone.c33
-rw-r--r--hw/mcf5208.c72
-rw-r--r--hw/milkymist-minimac2.c43
-rw-r--r--hw/milkymist-softusb.c48
-rw-r--r--hw/milkymist-tmu2.c2
-rw-r--r--hw/milkymist.c16
-rw-r--r--hw/mips.h7
-rw-r--r--hw/mips_jazz.c16
-rw-r--r--hw/mips_malta.c71
-rw-r--r--hw/mips_r4k.c20
-rw-r--r--hw/musicpal.c15
-rw-r--r--hw/nseries.c52
-rw-r--r--hw/omap.h14
-rw-r--r--hw/omap2.c3
-rw-r--r--hw/omap_gpmc.c713
-rw-r--r--hw/omap_sx1.c21
-rw-r--r--hw/onenand.c164
-rw-r--r--hw/pc.c4
-rw-r--r--hw/pci-stub.c2
-rw-r--r--hw/pci.c38
-rw-r--r--hw/pci_host.c86
-rw-r--r--hw/pci_host.h16
-rw-r--r--hw/pcie.c12
-rw-r--r--hw/pcie_aer.c9
-rw-r--r--hw/petalogix_ml605_mmu.c7
-rw-r--r--hw/petalogix_s3adsp1800_mmu.c8
-rw-r--r--hw/pflash_cfi01.c67
-rw-r--r--hw/pflash_cfi02.c93
-rw-r--r--hw/piix_pci.c13
-rw-r--r--hw/ppc405_boards.c63
-rw-r--r--hw/ppc4xx_pci.c10
-rw-r--r--hw/ppce500_pci.c21
-rw-r--r--hw/prep_pci.c12
-rw-r--r--hw/pxa2xx_lcd.c2
-rw-r--r--hw/qxl.c4
-rw-r--r--hw/r2d.c9
-rw-r--r--hw/rc4030.c2
-rw-r--r--hw/scsi-disk.c17
-rw-r--r--hw/sh_pci.c2
-rw-r--r--hw/smbios.c6
-rw-r--r--hw/smbios.h22
-rw-r--r--hw/srp.h10
-rw-r--r--hw/stellaris.c5
-rw-r--r--hw/stellaris_enet.c29
-rw-r--r--hw/sun4u.c8
-rw-r--r--hw/sysbus.c34
-rw-r--r--hw/sysbus.h9
-rw-r--r--hw/tusb6010.c115
-rw-r--r--hw/tusb6010.h28
-rw-r--r--hw/unin_pci.c82
-rw-r--r--hw/usb-ccid.c18
-rw-r--r--hw/vga.c1
-rw-r--r--hw/vhost.c74
-rw-r--r--hw/vhost.h2
-rw-r--r--hw/vhost_net.c16
-rw-r--r--hw/virtex_ml507.c7
-rw-r--r--hw/virtio-balloon.h2
-rw-r--r--hw/virtio-blk.c20
-rw-r--r--hw/virtio-blk.h2
-rw-r--r--hw/virtio-net.h2
-rw-r--r--hw/virtio-serial.h2
-rw-r--r--hw/vmware_vga.c2
-rw-r--r--hw/xen_disk.c5
-rw-r--r--hw/xilinx_ethlite.c27
-rw-r--r--hw/xilinx_intc.c29
-rw-r--r--hw/xilinx_timer.c31
-rw-r--r--hw/xilinx_uartlite.c32
-rw-r--r--hw/z2.c15
-rw-r--r--hw/zaurus.c2
-rw-r--r--i386.ld8
-rw-r--r--iohandler.c54
-rw-r--r--kvm-all.c2
-rw-r--r--libcacard/Makefile4
-rw-r--r--libcacard/vscclient.c2
-rw-r--r--linux-user/signal.c29
-rw-r--r--linux-user/syscall_defs.h16
-rw-r--r--m68k-semi.c4
-rw-r--r--memory.c7
-rw-r--r--memory.h1
-rw-r--r--mips.ld18
-rw-r--r--monitor.c28
-rw-r--r--nbd.h4
-rw-r--r--net.h5
-rw-r--r--net/slirp.c2
-rw-r--r--posix-aio-compat.c44
-rw-r--r--ppc.ld18
-rw-r--r--ppc64.ld6
-rw-r--r--qemu-config.c10
-rw-r--r--qemu-coroutine-lock.c44
-rw-r--r--qemu-coroutine.h32
-rw-r--r--qemu-ga.c2
-rw-r--r--qemu-img-cmds.hx4
-rw-r--r--qemu-img.c116
-rw-r--r--qemu-img.texi7
-rw-r--r--qemu-options.hx41
-rw-r--r--qemu-timer.c53
-rw-r--r--qmp-commands.hx24
-rw-r--r--rules.mak2
-rw-r--r--rwhandler.c87
-rw-r--r--rwhandler.h27
-rwxr-xr-xscripts/checkpatch.pl2
-rwxr-xr-xscripts/simpletrace.py4
-rwxr-xr-xscripts/tracetool116
-rw-r--r--slirp/ip.h16
-rw-r--r--slirp/slirp.h2
-rw-r--r--sparc.ld12
-rw-r--r--target-i386/kvm.c2
-rw-r--r--target-i386/svm.h8
-rw-r--r--target-microblaze/cpu.h1
-rw-r--r--target-microblaze/translate.c11
-rw-r--r--target-mips/cpu.h55
-rw-r--r--target-mips/helper.c6
-rw-r--r--target-mips/helper.h10
-rw-r--r--target-mips/op_helper.c606
-rw-r--r--target-mips/translate.c112
-rw-r--r--target-mips/translate_init.c4
-rw-r--r--target-s390x/cpu.h2
-rw-r--r--tcg/optimize.c15
-rw-r--r--tcg/ppc/tcg-target.c20
-rw-r--r--tests/test-i386.c10
-rw-r--r--tests/test_path.c2
-rw-r--r--trace-events653
-rw-r--r--trace/control.c42
-rw-r--r--trace/control.h41
-rw-r--r--trace/default.c41
-rw-r--r--trace/simple.c (renamed from simpletrace.c)27
-rw-r--r--trace/simple.h (renamed from simpletrace.h)16
-rw-r--r--trace/stderr.c37
-rw-r--r--trace/stderr.h11
-rw-r--r--vl.c117
-rw-r--r--x86_64.ld14
189 files changed, 4640 insertions, 3177 deletions
diff --git a/Makefile b/Makefile
index 86068498e9..e0cf51a8bf 100644
--- 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-%, \
diff --git a/Makefile.hw b/Makefile.hw
index 63eb7e40be..659e441992 100644
--- a/Makefile.hw
+++ b/Makefile.hw
@@ -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
diff --git a/Makefile.objs b/Makefile.objs
index d1f3e5dae5..26b885bfeb 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -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
diff --git a/Makefile.target b/Makefile.target
index c9957ae63a..0787758ad6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -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 dfc104e606..33ca7f77ea 100644
--- 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 12b3edb5bb..7f13da9ebb 100644
--- 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 a8a013a6d2..43742b73c0 100644
--- 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 a3bfaafef0..3ac0b944eb 100644
--- 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
+
diff --git a/block/curl.c b/block/curl.c
index 5c157bc609..f3f61cc8a1 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -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
diff --git a/block/parallels.c b/block/parallels.c
index 37d151dcb5..c64103ddbb 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -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 {
diff --git a/block/qcow.c b/block/qcow.c
index e155d3c002..c8bfecc1cb 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -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;
}
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 9269ddaefd..e06be64876 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -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.
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 2a915be57a..9605367777 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -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)
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 3bd2a30d35..bdc33ba94c 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -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;
}
diff --git a/block/qcow2.c b/block/qcow2.c
index bfff6cd963..b725d68b1d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -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;
}
diff --git a/block/qcow2.h b/block/qcow2.h
index de23abe1a4..c8ca3bc574 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -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);
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 57b6e1aad7..c1f6e07ec1 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -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,
diff --git a/block/vmdk.c b/block/vmdk.c
index 8da87acef0..5f673e9e25 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -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
diff --git a/block/vvfat.c b/block/vvfat.c
index d6a07efcc9..187ac96f25 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -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 */
diff --git a/block_int.h b/block_int.h
index f6d02b38a7..8a72b804b2 100644
--- a/block_int.h
+++ b/block_int.h
@@ -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 */
diff --git a/blockdev.c b/blockdev.c
index d272659ab2..2602591bf6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -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;
}
}
diff --git a/compiler.h b/compiler.h
index 9af5dc6c91..a2d5959e4b 100644
--- a/compiler.h
+++ b/compiler.h
@@ -12,6 +12,12 @@
#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];
diff --git a/configure b/configure
index 1340c33ef8..c3044c7435 100755
--- 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 b163efe4a8..54c188cf5c 100644
--- 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);
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index b7befb5e48..f345866f57 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -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
diff --git a/docs/tracing.txt b/docs/tracing.txt
index c99a0f27cf..4b27ab0c2a 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -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
diff --git a/dyngen-exec.h b/dyngen-exec.h
index cc1e4fb09d..8beb7f3344 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -19,15 +19,6 @@
#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__)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7951a0e869..2b2008502c 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -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) {
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 3bb7d8fa6d..618ddee569 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -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 );
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 0ccfb2867f..9e1cca8e3d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -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 9a4b22c022..3555b3e8e8 100644
--- 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 :
{
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 28fe1ff3a3..9d1b508e16 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -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;
diff --git a/hw/acpi.c b/hw/acpi.c
index d04b965977..1cf35e116a 100644
--- 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 */
diff --git a/hw/an5206.c b/hw/an5206.c
index 481ae60449..04ca420a90 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -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);
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 6ee2068128..c232946280 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -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]);
diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index af403a159a..f8a747289b 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -11,16 +11,13 @@
#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 */
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 28d41b82a6..a932f16a44 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -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;
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 73eb39d43b..06200e257a 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -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 3797254691..a48b8d4b13 100644
--- 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 */
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index ec7ea8207b..4d0ef0d54c 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -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();
}
diff --git a/hw/collie.c b/hw/collie.c
index 0b955e04f1..156404d9f3 100644
--- a/hw/collie.c
+++ b/hw/collie.c
@@ -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);
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 1aec06611c..a35f382052 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -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;
}
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 30146b9c9d..eed9e3843c 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -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) {
diff --git a/hw/flash.h b/hw/flash.h
index 7fb012bb06..270be5e127 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -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 {
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 663ad80116..8df265c61d 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -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);
diff --git a/hw/g364fb.c b/hw/g364fb.c
index a7731ecfb5..5e7bcfa278 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -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
@@ -18,27 +18,18 @@
*/
#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);
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 9d3ff7d555..9a823e1c06 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -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;
diff --git a/hw/gumstix.c b/hw/gumstix.c
index d3a4bb4c67..853f7e1ee8 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -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);
}
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index 8bf312ab21..6128702533 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -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
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 29521babf7..f4fa1545bd 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -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);
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index e456193b2b..3c29d93b47 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -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);
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index fe2fb0b806..f38d2896ae 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -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,
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d145b19b0c..40abc1edd2 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -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);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 02e805f070..7f5ef8de1d 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -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;
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 44fb3fef60..fdf5d75082 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -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);
}
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 3c8982ea29..281410899f 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -13,13 +13,11 @@
#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);
diff --git a/hw/leon3.c b/hw/leon3.c
index 607ec852fe..a62a9419f3 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -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) {
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index a84007b0ed..d18aad7435 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -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);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 82e957149d..4792f0e3ed 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -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);
}
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 1c2c0c48aa..8fe507f82f 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -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");
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index fb48e37187..cd360264c1 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -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,
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index ef4d9ee2ce..fe4eedb2cb 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -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);
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
index 790cdcb41c..953d42f16b 100644
--- a/hw/milkymist-tmu2.c
+++ b/hw/milkymist-tmu2.c
@@ -73,7 +73,7 @@ enum {
struct vertex {
int x;
int y;
-} __attribute__((packed));
+} QEMU_PACKED;
struct MilkymistTMU2State {
SysBusDevice busdev;
diff --git a/hw/milkymist.c b/hw/milkymist.c
index ef21ccaba1..93288c8401 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -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);
diff --git a/hw/mips.h b/hw/mips.h
index 97d7b9e5ad..8ce41fc4be 100644
--- 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);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index a74108646c..f3c9f93204 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -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());
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index b5c9bcfa51..a0adb566ab 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -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,
};
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 51dc8684be..9d90568e4e 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -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");
}
}
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 5e74ee7fd7..63dd391176 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -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
}
diff --git a/hw/nseries.c b/hw/nseries.c
index f7aae7a59e..af287dd6dc 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -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
diff --git a/hw/omap.h b/hw/omap.h
index db101c61f3..d9ab006ae0 100644
--- 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;
diff --git a/hw/omap2.c b/hw/omap2.c
index 7e5820a97b..ca088d9f53 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -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) {
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 673dddd237..02f0c52107 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -27,82 +27,410 @@
/* 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);
}
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 70364f4c72..a7b687bc41 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -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);
}
diff --git a/hw/onenand.c b/hw/onenand.c
index 00276a03cb..6f68f70698 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -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 263fb1a773..5bc845aaea 100644
--- 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};
diff --git a/hw/pci-stub.c b/hw/pci-stub.c
index c5a0aa8979..1fb105d51c 100644
--- a/hw/pci-stub.c
+++ b/hw/pci-stub.c
@@ -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.
diff --git a/hw/pci.c b/hw/pci.c
index 6124790f01..57ff7b1098 100644
--- 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;
diff --git a/hw/pci_host.c b/hw/pci_host.c
index 44c6c207a9..2e8a29f1e3 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -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);
+}
diff --git a/hw/pci_host.h b/hw/pci_host.h
index 0211086d70..7f551143bb 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -29,11 +29,12 @@
#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 */
diff --git a/hw/pcie.c b/hw/pcie.c
index 39607bf31a..5c9eb2f0ac 100644
--- 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;
}
diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index 2ae65ec807..62c06eafd6 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -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")) {
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 257fccaa88..e3ca310efd 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -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);
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 14817452c6..a43fb4c95c 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -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);
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 2144c6a3fd..90e1301c5e 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -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;
}
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index e7e0408fc4..ac5115e4c8 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -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).
*/
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 8f6ea42e2c..c563c6e1a3 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -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;
}
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 1eb807c4c1..dec165e40f 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -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 */
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 339b38ec7a..52e2663a01 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -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,
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 2db365d0b6..4390aeb559 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -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);
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 55e4e25099..c36232a808 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -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,
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 97f90153b7..b73290cb3f 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -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;
diff --git a/hw/qxl.c b/hw/qxl.c
index 1d9077db68..45e24016fc 100644
--- 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());
diff --git a/hw/r2d.c b/hw/r2d.c
index 41aa2c2bd2..771f3d0733 100644
--- 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++)
diff --git a/hw/rc4030.c b/hw/rc4030.c
index a2a20996a2..33e10709c6 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -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
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index d94b1eb53c..3cc830ff95 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -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
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 76061bb756..36f39300d5 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -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);
diff --git a/hw/smbios.c b/hw/smbios.c
index 8f2e965387..c9ba43e8d0 100644
--- a/hw/smbios.c
+++ b/hw/smbios.c
@@ -21,19 +21,19 @@
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
diff --git a/hw/smbios.h b/hw/smbios.h
index 3a5169dbd3..94e3641f9a 100644
--- a/hw/smbios.h
+++ b/hw/smbios.h
@@ -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 */
diff --git a/hw/srp.h b/hw/srp.h
index afcd135c8f..3009bd56ce 100644
--- 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 */
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 2bf1c235dc..9b0db7f511 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -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,
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index d5613ffffd..f9bd3da209 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -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);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 1b60e4ef59..32e6ab9beb 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -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);
}
}
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 6e89f065b4..c365d39d24 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -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);
-}
diff --git a/hw/sysbus.h b/hw/sysbus.h
index b3e1f99db5..aa3d383277 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -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,
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index b2bf35934d..de6ffc6133 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -23,9 +23,11 @@
#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
index b85ee86215..0000000000
--- a/hw/tusb6010.h
+++ /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
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 600cd1e5bd..f896f8c76b 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -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;
}
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 66aeb211af..c2f9241014 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -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;
diff --git a/hw/vga.c b/hw/vga.c
index 851fd689b3..125fb293f2 100644
--- 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;
diff --git a/hw/vhost.c b/hw/vhost.c
index 18860678ba..0870cb7d85 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -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;
diff --git a/hw/vhost.h b/hw/vhost.h
index c8c595a147..c9452f0732 100644
--- a/hw/vhost.h
+++ b/hw/vhost.h
@@ -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
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index a55981200d..950a6b8d99 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -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)
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index aa9e51222f..333050cdac 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -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);
diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h
index e20cf6bc0d..73300ddc86 100644
--- a/hw/virtio-balloon.h
+++ b/hw/virtio-balloon.h
@@ -50,6 +50,6 @@ struct virtio_balloon_config
typedef struct VirtIOBalloonStat {
uint16_t tag;
uint64_t val;
-} __attribute__((packed)) VirtIOBalloonStat;
+} QEMU_PACKED VirtIOBalloonStat;
#endif
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index dad8c0a6a2..2a8ccd0aa9 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -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);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 5645d2bf3c..244dce45aa 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -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
diff --git a/hw/virtio-net.h b/hw/virtio-net.h
index 8af9a1ce55..44687414c9 100644
--- a/hw/virtio-net.h
+++ b/hw/virtio-net.h
@@ -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. */
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index 36e9d222e5..ab138038c0 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -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 */
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 52d2d26f1b..aa682376ad 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -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;
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 31f91514f2..bd5c66916b 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -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,
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index f35ba8461a..6f44c8466e 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -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,
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index cb72d5a14e..58b73d95cc 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -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;
}
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index f1c7abc99e..8779c56f0b 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -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;
}
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 467a26cc9e..ceb7b4d9ed 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -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 d7b8d5327b..f93a1bf0fe 100644
--- 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);
}
diff --git a/hw/zaurus.c b/hw/zaurus.c
index c24aeb5763..0eeacf7cb3 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -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 f8df7bf8dd..cc3f160af0 100644
--- 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 :
diff --git a/iohandler.c b/iohandler.c
index 4deae1e6ab..4cc1c5ade6 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -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)
diff --git a/kvm-all.c b/kvm-all.c
index 0ae2e2697e..fbb9ff3bef 100644
--- 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++) {
diff --git a/libcacard/Makefile b/libcacard/Makefile
index b3f5e6c011..bf052bcc12 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -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)|' \
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index a7b38340dc..2191f6038c 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -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);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 07ad07a58f..89276eb6a5 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -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:
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index a117407d84..15c44d45a8 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -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 */
diff --git a/m68k-semi.c b/m68k-semi.c
index 7fde10e8f3..bab01ee863 100644
--- a/m68k-semi.c
+++ b/m68k-semi.c
@@ -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
diff --git a/memory.c b/memory.c
index 8e9ac460e8..57f0fa44ff 100644
--- 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)
diff --git a/memory.h b/memory.h
index 0553cc7526..06b83ae76b 100644
--- 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 4294761c19..7b610ceed4 100644
--- 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 :
{
diff --git a/monitor.c b/monitor.c
index ada51d0c23..df0f622067 100644
--- a/monitor.c
+++ b/monitor.c
@@ -57,9 +57,11 @@
#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 b38d0d08de..96f77fe2d1 100644
--- 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 5a7881cf67..9f633f8432 100644
--- 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);
diff --git a/net/slirp.c b/net/slirp.c
index 3b39d21183..c6cda5dcb2 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -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);
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index babb0940dd..3193dbf83c 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -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 5248ef15a5..69aa3f228d 100644
--- 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 :
{
diff --git a/ppc64.ld b/ppc64.ld
index dea0dbda21..0059ee53ac 100644
--- 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) }
diff --git a/qemu-config.c b/qemu-config.c
index 1eb6b9a709..7a7854fd06 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -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,
diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c
index a80f437c59..2a385a3bb8 100644
--- a/qemu-coroutine-lock.c
+++ b/qemu-coroutine-lock.c
@@ -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;
+}
diff --git a/qemu-coroutine.h b/qemu-coroutine.h
index 2f2fd95552..b8fc4f4332 100644
--- a/qemu-coroutine.h
+++ b/qemu-coroutine.h
@@ -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 */
diff --git a/qemu-ga.c b/qemu-ga.c
index 858d75a361..49320133c6 100644
--- 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);
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 1299e83ef2..4be00a5edd 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -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,
diff --git a/qemu-img.c b/qemu-img.c
index 95f3219571..6a3973163f 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -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;
@@ -591,6 +573,48 @@ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
}
/*
+ * 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);
}
/*
diff --git a/qemu-img.texi b/qemu-img.texi
index 495a1b6695..70fa321dff 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -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}
diff --git a/qemu-options.hx b/qemu-options.hx
index d86815dc04..659ecb2db7 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -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
diff --git a/qemu-timer.c b/qemu-timer.c
index 19313d3b00..46dd483fdd 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -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
}
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 03f67da198..27cc66ebc9 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -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
}
}
]
diff --git a/rules.mak b/rules.mak
index 884d421ae4..04a91983ec 100644
--- 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
index 0000000000..bb2238ff1e
--- /dev/null
+++ b/rwhandler.c
@@ -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
index 0000000000..b2a5790548
--- /dev/null
+++ b/rwhandler.h
@@ -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
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3498425fff..0eba357cc2 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -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);
}
}
diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py
index 2ad56998ee..f55e5e63f9 100755
--- a/scripts/simpletrace.py
+++ b/scripts/simpletrace.py
@@ -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 = {}
diff --git a/scripts/tracetool b/scripts/tracetool
index 2155a57df2..743d246289 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -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/slirp/ip.h b/slirp/ip.h
index 72dbe9a5d9..88c903fccd 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -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
diff --git a/slirp/slirp.h b/slirp/slirp.h
index dcf99d5ca4..28a5c037e6 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -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
diff --git a/sparc.ld b/sparc.ld
index 31321be532..56efe34e73 100644
--- 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 :
{
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 1d9b20c706..70ef74b80a 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -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;
diff --git a/target-i386/svm.h b/target-i386/svm.h
index a224aead17..04193ed60f 100644
--- a/target-i386/svm.h
+++ b/target-i386/svm.h
@@ -130,7 +130,7 @@
#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;
};
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index a81da629de..35302863cb 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -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 */
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 1a862d31e3..366fd3e607 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -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)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c5f70fa759..79e25583ff 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -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;
}
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 024caa23c1..1c58e0cc21 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -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
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 297ab64bda..442f684697 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -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)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 056011f1cc..96e40c6018 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -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);
}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6c4e0d7675..d5b1c765fb 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -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) {
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 5bb421562a..c39138f3c5 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -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);
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index f8f0c82c6f..e192b50c73 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -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
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 7e7f2b2020..9c65474a8c 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -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
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 4462647ef1..87cc1177f6 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -525,14 +525,14 @@ 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++;
if (opc == 3)
@@ -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,14 +722,14 @@ 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++;
if (opc == 3)
@@ -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;
diff --git a/tests/test-i386.c b/tests/test-i386.c
index 56ff1103fa..9cb5b51b76 100644
--- a/tests/test-i386.c
+++ b/tests/test-i386.c
@@ -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;
diff --git a/tests/test_path.c b/tests/test_path.c
index 234ed97088..7265a9445d 100644
--- a/tests/test_path.c
+++ b/tests/test_path.c
@@ -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
diff --git a/trace-events b/trace-events
index dc300a29b1..08ffedfdd1 100644
--- a/trace-events
+++ b/trace-events
@@ -14,12 +14,9 @@
#
# [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.
#
@@ -29,435 +26,439 @@
# 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
index 0000000000..4c5527d20a
--- /dev/null
+++ b/trace/control.c
@@ -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
index 0000000000..2acaa4290e
--- /dev/null
+++ b/trace/control.h
@@ -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
index 0000000000..c9b27a289b
--- /dev/null
+++ b/trace/default.c
@@ -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/simpletrace.c b/trace/simple.c
index de355e9675..a6093682dd 100644
--- a/simpletrace.c
+++ b/trace/simple.c
@@ -16,6 +16,7 @@
#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 */
@@ -302,7 +303,12 @@ void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char
}
}
-void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+void st_flush_trace_buffer(void)
+{
+ flush_trace_file(true);
+}
+
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
{
unsigned int i;
@@ -312,25 +318,20 @@ void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, cons
}
}
-bool st_change_trace_event_state(const char *name, bool enabled)
+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 = enabled;
+ trace_list[i].state = state;
return true;
}
}
return false;
}
-void st_flush_trace_buffer(void)
-{
- flush_trace_file(true);
-}
-
-bool st_init(const char *file)
+bool trace_backend_init(const char *events, const char *file)
{
pthread_t thread;
pthread_attr_t attr;
@@ -346,10 +347,12 @@ bool st_init(const char *file)
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
if (ret != 0) {
- return false;
+ 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);
}
- atexit(st_flush_trace_buffer);
- st_set_trace_file(file);
return true;
}
diff --git a/simpletrace.h b/trace/simple.h
index 8d893bd849..466e75b4ff 100644
--- a/simpletrace.h
+++ b/trace/simple.h
@@ -8,14 +8,13 @@
*
*/
-#ifndef SIMPLETRACE_H
-#define SIMPLETRACE_H
+#ifndef TRACE_SIMPLE_H
+#define TRACE_SIMPLE_H
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
-#ifdef CONFIG_SIMPLE_TRACE
typedef uint64_t TraceEventID;
typedef struct {
@@ -31,18 +30,9 @@ void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t
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 */
+#endif /* TRACE_SIMPLE_H */
diff --git a/trace/stderr.c b/trace/stderr.c
new file mode 100644
index 0000000000..7107c4a131
--- /dev/null
+++ b/trace/stderr.c
@@ -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
index 0000000000..d575b613e3
--- /dev/null
+++ b/trace/stderr.h
@@ -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 9cd67a3746..5ba9b35860 100644
--- 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
diff --git a/x86_64.ld b/x86_64.ld
index 46d8d4d9dd..b7a9f4eb36 100644
--- 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 :
{