aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS6
-rw-r--r--audio/audio.c2
-rw-r--r--audio/wavaudio.c46
-rw-r--r--audio/wavcapture.c79
-rw-r--r--block/nbd.c4
-rw-r--r--block/raw-posix.c9
-rw-r--r--block/rbd.c83
-rw-r--r--block/vmdk.c14
-rw-r--r--cmd.c2
-rwxr-xr-xconfigure5
-rw-r--r--cpu-all.h1
-rw-r--r--cpus.c25
-rw-r--r--cpus.h1
-rw-r--r--dma-helpers.c58
-rw-r--r--dma.h10
-rw-r--r--docs/tracing.txt24
-rw-r--r--exec.c4
-rw-r--r--gdbstub.c34
-rw-r--r--hw/ac97.c1
-rw-r--r--hw/e1000.c3
-rw-r--r--hw/es1370.c1
-rw-r--r--hw/etraxfs_dma.c2
-rw-r--r--hw/ide/ahci.c10
-rw-r--r--hw/ide/core.c6
-rw-r--r--hw/ide/internal.h3
-rw-r--r--hw/ide/macio.c2
-rw-r--r--hw/ide/pci.c2
-rw-r--r--hw/kvmclock.c5
-rw-r--r--hw/lsi53c895a.c3
-rw-r--r--hw/mips_jazz.c90
-rw-r--r--hw/mips_malta.c53
-rw-r--r--hw/mips_mipssim.c15
-rw-r--r--hw/mips_r4k.c39
-rw-r--r--hw/musicpal.c243
-rw-r--r--hw/ne2000.c3
-rw-r--r--hw/omap.h32
-rw-r--r--hw/omap1.c859
-rw-r--r--hw/omap2.c6
-rw-r--r--hw/omap_lcdc.c7
-rw-r--r--hw/omap_sx1.c4
-rw-r--r--hw/palm.c4
-rw-r--r--hw/pci.c76
-rw-r--r--hw/pci.h4
-rw-r--r--hw/pci_bridge.c85
-rw-r--r--hw/pci_internals.h19
-rw-r--r--hw/pcnet-pci.c2
-rw-r--r--hw/qxl.c5
-rw-r--r--hw/rtl8139.c2
-rw-r--r--hw/scsi-bus.c22
-rw-r--r--hw/scsi-disk.c88
-rw-r--r--hw/scsi-generic.c6
-rw-r--r--hw/soc_dma.h8
-rw-r--r--hw/sun4u.c1
-rw-r--r--hw/usb-ehci.c2
-rw-r--r--hw/usb-ohci.c3
-rw-r--r--hw/usb-uhci.c2
-rw-r--r--hw/virtio-blk.c5
-rw-r--r--hw/virtio.c4
-rw-r--r--hw/watchdog.c2
-rw-r--r--hw/xen_nic.c1
-rw-r--r--hw/xics.c2
-rw-r--r--kvm-all.c2
-rw-r--r--libcacard/Makefile2
-rw-r--r--linux-aio.c11
-rw-r--r--migration.c14
-rw-r--r--monitor.c22
-rw-r--r--nbd.c42
-rw-r--r--nbd.h20
-rw-r--r--posix-aio-compat.c38
-rw-r--r--qemu-nbd.c13
-rw-r--r--qemu-thread-posix.c2
-rw-r--r--qemu-thread-win32.c2
-rw-r--r--qemu-timer.c9
-rw-r--r--qerror.c4
-rw-r--r--qerror.h3
-rw-r--r--qmp-commands.hx19
-rw-r--r--savevm.c8
-rw-r--r--slirp/tcp_input.c1
-rw-r--r--sysemu.h42
-rw-r--r--target-i386/cpu.h5
-rw-r--r--target-i386/kvm.c4
-rw-r--r--target-i386/translate.c5
-rw-r--r--trace-events2
-rw-r--r--trace/simple.c76
-rw-r--r--ui/keymaps.c2
-rw-r--r--ui/sdl.c6
-rw-r--r--ui/spice-display.c5
-rw-r--r--ui/spice-display.h4
-rw-r--r--vl.c156
-rw-r--r--xen-all.c12
90 files changed, 1531 insertions, 1139 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 72b2099d3e..7c5ea873a8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -459,6 +459,12 @@ S: Maintained
F: slirp/
T: git://git.kiszka.org/qemu.git queues/slirp
+Tracing
+M: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+S: Maintained
+F: trace/
+T: git://repo.or.cz/qemu/stefanha.git tracing
+
Usermode Emulation
------------------
BSD user
diff --git a/audio/audio.c b/audio/audio.c
index 5649075b01..50d0d7183f 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1743,7 +1743,7 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv)
}
static void audio_vm_change_state_handler (void *opaque, int running,
- int reason)
+ RunState state)
{
AudioState *s = opaque;
HWVoiceOut *hwo = NULL;
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index aed18176ee..a449b5127e 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -30,7 +30,7 @@
typedef struct WAVVoiceOut {
HWVoiceOut hw;
- QEMUFile *f;
+ FILE *f;
int64_t old_ticks;
void *pcm_buf;
int total_samples;
@@ -76,7 +76,10 @@ static int wav_run_out (HWVoiceOut *hw, int live)
dst = advance (wav->pcm_buf, rpos << hw->info.shift);
hw->clip (dst, src, convert_samples);
- qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift);
+ if (fwrite (dst, convert_samples << hw->info.shift, 1, wav->f) != 1) {
+ dolog ("wav_run_out: fwrite of %d bytes failed\nReaons: %s\n",
+ convert_samples << hw->info.shift, strerror (errno));
+ }
rpos = (rpos + convert_samples) % hw->samples;
samples -= convert_samples;
@@ -152,7 +155,7 @@ static int wav_init_out (HWVoiceOut *hw, struct audsettings *as)
le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
le_store (hdr + 32, 1 << (bits16 + stereo), 2);
- wav->f = qemu_fopen (conf.wav_path, "wb");
+ wav->f = fopen (conf.wav_path, "wb");
if (!wav->f) {
dolog ("Failed to open wave file `%s'\nReason: %s\n",
conf.wav_path, strerror (errno));
@@ -161,7 +164,11 @@ static int wav_init_out (HWVoiceOut *hw, struct audsettings *as)
return -1;
}
- qemu_put_buffer (wav->f, hdr, sizeof (hdr));
+ if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) {
+ dolog ("wav_init_out: failed to write header\nReason: %s\n",
+ strerror(errno));
+ return -1;
+ }
return 0;
}
@@ -180,13 +187,32 @@ static void wav_fini_out (HWVoiceOut *hw)
le_store (rlen, rifflen, 4);
le_store (dlen, datalen, 4);
- qemu_fseek (wav->f, 4, SEEK_SET);
- qemu_put_buffer (wav->f, rlen, 4);
-
- qemu_fseek (wav->f, 32, SEEK_CUR);
- qemu_put_buffer (wav->f, dlen, 4);
+ if (fseek (wav->f, 4, SEEK_SET)) {
+ dolog ("wav_fini_out: fseek to rlen failed\nReason: %s\n",
+ strerror(errno));
+ goto doclose;
+ }
+ if (fwrite (rlen, 4, 1, wav->f) != 1) {
+ dolog ("wav_fini_out: failed to write rlen\nReason: %s\n",
+ strerror (errno));
+ goto doclose;
+ }
+ if (fseek (wav->f, 32, SEEK_CUR)) {
+ dolog ("wav_fini_out: fseek to dlen failed\nReason: %s\n",
+ strerror (errno));
+ goto doclose;
+ }
+ if (fwrite (dlen, 4, 1, wav->f) != 1) {
+ dolog ("wav_fini_out: failed to write dlen\nReaons: %s\n",
+ strerror (errno));
+ goto doclose;
+ }
- qemu_fclose (wav->f);
+ doclose:
+ if (fclose (wav->f)) {
+ dolog ("wav_fini_out: fclose %p failed\nReason: %s\n",
+ wav->f, strerror (errno));
+ }
wav->f = NULL;
g_free (wav->pcm_buf);
diff --git a/audio/wavcapture.c b/audio/wavcapture.c
index c64f0ef075..4f785f5f49 100644
--- a/audio/wavcapture.c
+++ b/audio/wavcapture.c
@@ -3,7 +3,7 @@
#include "audio.h"
typedef struct {
- QEMUFile *f;
+ FILE *f;
int bytes;
char *path;
int freq;
@@ -35,17 +35,37 @@ static void wav_destroy (void *opaque)
uint8_t dlen[4];
uint32_t datalen = wav->bytes;
uint32_t rifflen = datalen + 36;
+ Monitor *mon = cur_mon;
if (wav->f) {
le_store (rlen, rifflen, 4);
le_store (dlen, datalen, 4);
- qemu_fseek (wav->f, 4, SEEK_SET);
- qemu_put_buffer (wav->f, rlen, 4);
-
- qemu_fseek (wav->f, 32, SEEK_CUR);
- qemu_put_buffer (wav->f, dlen, 4);
- qemu_fclose (wav->f);
+ if (fseek (wav->f, 4, SEEK_SET)) {
+ monitor_printf (mon, "wav_destroy: rlen fseek failed\nReason: %s\n",
+ strerror (errno));
+ goto doclose;
+ }
+ if (fwrite (rlen, 4, 1, wav->f) != 1) {
+ monitor_printf (mon, "wav_destroy: rlen fwrite failed\nReason %s\n",
+ strerror (errno));
+ goto doclose;
+ }
+ if (fseek (wav->f, 32, SEEK_CUR)) {
+ monitor_printf (mon, "wav_destroy: dlen fseek failed\nReason %s\n",
+ strerror (errno));
+ goto doclose;
+ }
+ if (fwrite (dlen, 1, 4, wav->f) != 4) {
+ monitor_printf (mon, "wav_destroy: dlen fwrite failed\nReason %s\n",
+ strerror (errno));
+ goto doclose;
+ }
+ doclose:
+ if (fclose (wav->f)) {
+ fprintf (stderr, "wav_destroy: fclose failed: %s",
+ strerror (errno));
+ }
}
g_free (wav->path);
@@ -55,7 +75,10 @@ static void wav_capture (void *opaque, void *buf, int size)
{
WAVState *wav = opaque;
- qemu_put_buffer (wav->f, buf, size);
+ if (fwrite (buf, size, 1, wav->f) != 1) {
+ monitor_printf (cur_mon, "wav_capture: fwrite error\nReason: %s",
+ strerror (errno));
+ }
wav->bytes += size;
}
@@ -71,9 +94,9 @@ static void wav_capture_info (void *opaque)
WAVState *wav = opaque;
char *path = wav->path;
- monitor_printf(cur_mon, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
- wav->freq, wav->bits, wav->nchannels,
- path ? path : "<not available>", wav->bytes);
+ monitor_printf (cur_mon, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
+ wav->freq, wav->bits, wav->nchannels,
+ path ? path : "<not available>", wav->bytes);
}
static struct capture_ops wav_capture_ops = {
@@ -98,13 +121,13 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
CaptureVoiceOut *cap;
if (bits != 8 && bits != 16) {
- monitor_printf(mon, "incorrect bit count %d, must be 8 or 16\n", bits);
+ monitor_printf (mon, "incorrect bit count %d, must be 8 or 16\n", bits);
return -1;
}
if (nchannels != 1 && nchannels != 2) {
- monitor_printf(mon, "incorrect channel count %d, must be 1 or 2\n",
- nchannels);
+ monitor_printf (mon, "incorrect channel count %d, must be 1 or 2\n",
+ nchannels);
return -1;
}
@@ -130,10 +153,10 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
le_store (hdr + 28, freq << shift, 4);
le_store (hdr + 32, 1 << shift, 2);
- wav->f = qemu_fopen (path, "wb");
+ wav->f = fopen (path, "wb");
if (!wav->f) {
- monitor_printf(mon, "Failed to open wave file `%s'\nReason: %s\n",
- path, strerror (errno));
+ monitor_printf (mon, "Failed to open wave file `%s'\nReason: %s\n",
+ path, strerror (errno));
g_free (wav);
return -1;
}
@@ -143,19 +166,29 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
wav->nchannels = nchannels;
wav->freq = freq;
- qemu_put_buffer (wav->f, hdr, sizeof (hdr));
+ if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) {
+ monitor_printf (mon, "Failed to write header\nReason: %s\n",
+ strerror (errno));
+ goto error_free;
+ }
cap = AUD_add_capture (&as, &ops, wav);
if (!cap) {
- monitor_printf(mon, "Failed to add audio capture\n");
- g_free (wav->path);
- qemu_fclose (wav->f);
- g_free (wav);
- return -1;
+ monitor_printf (mon, "Failed to add audio capture\n");
+ goto error_free;
}
wav->cap = cap;
s->opaque = wav;
s->ops = wav_capture_ops;
return 0;
+
+error_free:
+ g_free (wav->path);
+ if (fclose (wav->f)) {
+ monitor_printf (mon, "Failed to close wave file\nReason: %s\n",
+ strerror (errno));
+ }
+ g_free (wav);
+ return -1;
}
diff --git a/block/nbd.c b/block/nbd.c
index 70edd81bd6..76f04d863c 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -48,6 +48,7 @@
typedef struct BDRVNBDState {
int sock;
+ uint32_t nbdflags;
off_t size;
size_t blocksize;
char *export_name; /* An NBD server may export several devices */
@@ -111,7 +112,6 @@ static int nbd_establish_connection(BlockDriverState *bs)
int ret;
off_t size;
size_t blocksize;
- uint32_t nbdflags;
if (s->host_spec[0] == '/') {
sock = unix_socket_outgoing(s->host_spec);
@@ -126,7 +126,7 @@ static int nbd_establish_connection(BlockDriverState *bs)
}
/* NBD handshake */
- ret = nbd_receive_negotiate(sock, s->export_name, &nbdflags, &size,
+ ret = nbd_receive_negotiate(sock, s->export_name, &s->nbdflags, &size,
&blocksize);
if (ret == -1) {
logout("Failed to negotiate with the NBD server\n");
diff --git a/block/raw-posix.c b/block/raw-posix.c
index a624f56f86..305998ddb3 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -839,7 +839,14 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
static int raw_flush(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
- return qemu_fdatasync(s->fd);
+ int ret;
+
+ ret = qemu_fdatasync(s->fd);
+ if (ret < 0) {
+ return -errno;
+ }
+
+ return 0;
}
#ifdef CONFIG_XFS
diff --git a/block/rbd.c b/block/rbd.c
index 1b78d51398..3068c829fe 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -13,35 +13,33 @@
#include "qemu-common.h"
#include "qemu-error.h"
-
#include "block_int.h"
#include <rbd/librbd.h>
-
-
/*
* When specifying the image filename use:
*
* rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]]
*
- * poolname must be the name of an existing rados pool
+ * poolname must be the name of an existing rados pool.
*
- * devicename is the basename for all objects used to
- * emulate the raw device.
+ * devicename is the name of the rbd image.
*
- * Each option given is used to configure rados, and may be
- * any Ceph option, or "conf". The "conf" option specifies
- * a Ceph configuration file to read.
+ * Each option given is used to configure rados, and may be any valid
+ * Ceph option, "id", or "conf".
*
- * Metadata information (image size, ...) is stored in an
- * object with the name "devicename.rbd".
+ * The "id" option indicates what user we should authenticate as to
+ * the Ceph cluster. If it is excluded we will use the Ceph default
+ * (normally 'admin').
*
- * The raw device is split into 4MB sized objects by default.
- * The sequencenumber is encoded in a 12 byte long hex-string,
- * and is attached to the devicename, separated by a dot.
- * e.g. "devicename.1234567890ab"
+ * The "conf" option specifies a Ceph configuration file to read. If
+ * it is not specified, we will read from the default Ceph locations
+ * (e.g., /etc/ceph/ceph.conf). To avoid reading _any_ configuration
+ * file, specify conf=/dev/null.
*
+ * Configuration values containing :, @, or = can be escaped with a
+ * leading "\".
*/
#define OBJ_MAX_SIZE (1UL << OBJ_DEFAULT_OBJ_ORDER)
@@ -104,8 +102,15 @@ static int qemu_rbd_next_tok(char *dst, int dst_len,
*p = NULL;
if (delim != '\0') {
- end = strchr(src, delim);
- if (end) {
+ for (end = src; *end; ++end) {
+ if (*end == delim) {
+ break;
+ }
+ if (*end == '\\' && end[1] != '\0') {
+ end++;
+ }
+ }
+ if (*end == delim) {
*p = end + 1;
*end = '\0';
}
@@ -124,6 +129,19 @@ static int qemu_rbd_next_tok(char *dst, int dst_len,
return 0;
}
+static void qemu_rbd_unescape(char *src)
+{
+ char *p;
+
+ for (p = src; *src; ++src, ++p) {
+ if (*src == '\\' && src[1] != '\0') {
+ src++;
+ }
+ *p = *src;
+ }
+ *p = '\0';
+}
+
static int qemu_rbd_parsename(const char *filename,
char *pool, int pool_len,
char *snap, int snap_len,
@@ -148,6 +166,7 @@ static int qemu_rbd_parsename(const char *filename,
ret = -EINVAL;
goto done;
}
+ qemu_rbd_unescape(pool);
if (strchr(p, '@')) {
ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p);
@@ -155,9 +174,11 @@ static int qemu_rbd_parsename(const char *filename,
goto done;
}
ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p);
+ qemu_rbd_unescape(snap);
} else {
ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p);
}
+ qemu_rbd_unescape(name);
if (ret < 0 || !p) {
goto done;
}
@@ -213,6 +234,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
if (ret < 0) {
break;
}
+ qemu_rbd_unescape(name);
if (!p) {
error_report("conf option %s has no value", name);
@@ -225,6 +247,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
if (ret < 0) {
break;
}
+ qemu_rbd_unescape(value);
if (strcmp(name, "conf") == 0) {
ret = rados_conf_read_file(cluster, value);
@@ -298,11 +321,8 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options)
}
if (strstr(conf, "conf=") == NULL) {
- if (rados_conf_read_file(cluster, NULL) < 0) {
- error_report("error reading config file");
- rados_shutdown(cluster);
- return -EIO;
- }
+ /* try default location, but ignore failure */
+ rados_conf_read_file(cluster, NULL);
}
if (conf[0] != '\0' &&
@@ -441,11 +461,8 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)
}
if (strstr(conf, "conf=") == NULL) {
- r = rados_conf_read_file(s->cluster, NULL);
- if (r < 0) {
- error_report("error reading config file");
- goto failed_shutdown;
- }
+ /* try default location, but ignore failure */
+ rados_conf_read_file(s->cluster, NULL);
}
if (conf[0] != '\0') {
@@ -688,6 +705,17 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
}
+static int qemu_rbd_flush(BlockDriverState *bs)
+{
+#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
+ /* rbd_flush added in 0.1.1 */
+ BDRVRBDState *s = bs->opaque;
+ return rbd_flush(s->image);
+#else
+ return 0;
+#endif
+}
+
static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
{
BDRVRBDState *s = bs->opaque;
@@ -823,6 +851,7 @@ static BlockDriver bdrv_rbd = {
.bdrv_file_open = qemu_rbd_open,
.bdrv_close = qemu_rbd_close,
.bdrv_create = qemu_rbd_create,
+ .bdrv_flush = qemu_rbd_flush,
.bdrv_get_info = qemu_rbd_getinfo,
.create_options = qemu_rbd_create_options,
.bdrv_getlength = qemu_rbd_getlength,
diff --git a/block/vmdk.c b/block/vmdk.c
index 6c8edfc190..5d16ec49bc 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -179,11 +179,16 @@ static void vmdk_free_extents(BlockDriverState *bs)
{
int i;
BDRVVmdkState *s = bs->opaque;
+ VmdkExtent *e;
for (i = 0; i < s->num_extents; i++) {
- g_free(s->extents[i].l1_table);
- g_free(s->extents[i].l2_cache);
- g_free(s->extents[i].l1_backup_table);
+ e = &s->extents[i];
+ g_free(e->l1_table);
+ g_free(e->l2_cache);
+ g_free(e->l1_backup_table);
+ if (e->file != bs->file) {
+ bdrv_delete(e->file);
+ }
}
g_free(s->extents);
}
@@ -619,12 +624,13 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
s->desc_offset = 0;
ret = vmdk_parse_extents(buf, bs, bs->file->filename);
if (ret) {
+ vmdk_free_extents(bs);
return ret;
}
/* try to open parent images, if exist */
if (vmdk_parent_open(bs)) {
- g_free(s->extents);
+ vmdk_free_extents(bs);
return -EINVAL;
}
s->parent_cid = vmdk_read_cid(bs, 1);
diff --git a/cmd.c b/cmd.c
index ecca167399..f77897e00a 100644
--- a/cmd.c
+++ b/cmd.c
@@ -389,7 +389,7 @@ cvtnum(
if (sp[1] != '\0')
return -1LL;
- c = tolower(*sp);
+ c = qemu_tolower(*sp);
switch (c) {
default:
return i;
diff --git a/configure b/configure
index ad924c40a1..9ab3ab4eb0 100755
--- a/configure
+++ b/configure
@@ -855,6 +855,7 @@ if [ "$softmmu" = "yes" ] ; then
default_target_list="\
i386-softmmu \
x86_64-softmmu \
+alpha-softmmu \
arm-softmmu \
cris-softmmu \
lm32-softmmu \
@@ -1339,8 +1340,8 @@ fi
# pkg-config probe
if ! has $pkg_config; then
- echo warning: proceeding without "$pkg_config" >&2
- pkg_config=/bin/false
+ echo "Error: pkg-config binary '$pkg_config' not found"
+ exit 1
fi
##########################################
diff --git a/cpu-all.h b/cpu-all.h
index f5c82cdebd..42a5fa0a7c 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -290,7 +290,6 @@ extern unsigned long reserved_va;
/* ??? These should be the larger of unsigned long and target_ulong. */
extern unsigned long qemu_real_host_page_size;
-extern unsigned long qemu_host_page_bits;
extern unsigned long qemu_host_page_size;
extern unsigned long qemu_host_page_mask;
diff --git a/cpus.c b/cpus.c
index 54c188cf5c..89787794e8 100644
--- a/cpus.c
+++ b/cpus.c
@@ -115,16 +115,16 @@ void cpu_synchronize_all_post_init(void)
int cpu_is_stopped(CPUState *env)
{
- return !vm_running || env->stopped;
+ return !runstate_is_running() || env->stopped;
}
-static void do_vm_stop(int reason)
+static void do_vm_stop(RunState state)
{
- if (vm_running) {
+ if (runstate_is_running()) {
cpu_disable_ticks();
- vm_running = 0;
pause_all_vcpus();
- vm_state_notify(0, reason);
+ runstate_set(state);
+ vm_state_notify(0, state);
qemu_aio_flush();
bdrv_flush_all();
monitor_protocol_event(QEVENT_STOP, NULL);
@@ -136,7 +136,7 @@ static int cpu_can_run(CPUState *env)
if (env->stop) {
return 0;
}
- if (env->stopped || !vm_running) {
+ if (env->stopped || !runstate_is_running()) {
return 0;
}
return 1;
@@ -147,7 +147,7 @@ static bool cpu_thread_is_idle(CPUState *env)
if (env->stop || env->queued_work_first) {
return false;
}
- if (env->stopped || !vm_running) {
+ if (env->stopped || !runstate_is_running()) {
return true;
}
if (!env->halted || qemu_cpu_has_work(env) ||
@@ -380,11 +380,6 @@ static int qemu_signal_init(void)
int sigfd;
sigset_t set;
- /* SIGUSR2 used by posix-aio-compat.c */
- sigemptyset(&set);
- sigaddset(&set, SIGUSR2);
- pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-
/*
* SIG_IPI must be blocked in the main thread and must not be caught
* by sigwait() in the signal thread. Otherwise, the cpu thread will
@@ -878,10 +873,10 @@ void cpu_stop_current(void)
}
}
-void vm_stop(int reason)
+void vm_stop(RunState state)
{
if (!qemu_thread_is_self(&io_thread)) {
- qemu_system_vmstop_request(reason);
+ qemu_system_vmstop_request(state);
/*
* FIXME: should not return to device code in case
* vm_stop() has been requested.
@@ -889,7 +884,7 @@ void vm_stop(int reason)
cpu_stop_current();
return;
}
- do_vm_stop(reason);
+ do_vm_stop(state);
}
static int tcg_cpu_exec(CPUState *env)
diff --git a/cpus.h b/cpus.h
index f42b54e39c..58858855ff 100644
--- a/cpus.h
+++ b/cpus.h
@@ -15,7 +15,6 @@ void cpu_synchronize_all_post_init(void);
/* vl.c */
extern int smp_cores;
extern int smp_threads;
-void vm_state_notify(int running, int reason);
bool cpu_exec_all(void);
void set_numa_modes(void);
void set_cpu_log(const char *optarg);
diff --git a/dma-helpers.c b/dma-helpers.c
index 4610ea0420..86d2d0a997 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -42,7 +42,8 @@ typedef struct {
BlockDriverAIOCB *acb;
QEMUSGList *sg;
uint64_t sector_num;
- int is_write;
+ bool to_dev;
+ bool in_cancel;
int sg_cur_index;
target_phys_addr_t sg_cur_byte;
QEMUIOVector iov;
@@ -58,7 +59,7 @@ static void reschedule_dma(void *opaque)
qemu_bh_delete(dbs->bh);
dbs->bh = NULL;
- dma_bdrv_cb(opaque, 0);
+ dma_bdrv_cb(dbs, 0);
}
static void continue_after_map_failure(void *opaque)
@@ -75,9 +76,29 @@ static void dma_bdrv_unmap(DMAAIOCB *dbs)
for (i = 0; i < dbs->iov.niov; ++i) {
cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
- dbs->iov.iov[i].iov_len, !dbs->is_write,
+ dbs->iov.iov[i].iov_len, !dbs->to_dev,
dbs->iov.iov[i].iov_len);
}
+ qemu_iovec_reset(&dbs->iov);
+}
+
+static void dma_complete(DMAAIOCB *dbs, int ret)
+{
+ dma_bdrv_unmap(dbs);
+ if (dbs->common.cb) {
+ dbs->common.cb(dbs->common.opaque, ret);
+ }
+ qemu_iovec_destroy(&dbs->iov);
+ if (dbs->bh) {
+ qemu_bh_delete(dbs->bh);
+ dbs->bh = NULL;
+ }
+ if (!dbs->in_cancel) {
+ /* Requests may complete while dma_aio_cancel is in progress. In
+ * this case, the AIOCB should not be released because it is still
+ * referenced by dma_aio_cancel. */
+ qemu_aio_release(dbs);
+ }
}
static void dma_bdrv_cb(void *opaque, int ret)
@@ -89,19 +110,16 @@ static void dma_bdrv_cb(void *opaque, int ret)
dbs->acb = NULL;
dbs->sector_num += dbs->iov.size / 512;
dma_bdrv_unmap(dbs);
- qemu_iovec_reset(&dbs->iov);
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
- dbs->common.cb(dbs->common.opaque, ret);
- qemu_iovec_destroy(&dbs->iov);
- qemu_aio_release(dbs);
+ dma_complete(dbs, ret);
return;
}
while (dbs->sg_cur_index < dbs->sg->nsg) {
cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;
cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte;
- mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->is_write);
+ mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->to_dev);
if (!mem)
break;
qemu_iovec_add(&dbs->iov, mem, cur_len);
@@ -120,9 +138,7 @@ static void dma_bdrv_cb(void *opaque, int ret)
dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov,
dbs->iov.size / 512, dma_bdrv_cb, dbs);
if (!dbs->acb) {
- dma_bdrv_unmap(dbs);
- qemu_iovec_destroy(&dbs->iov);
- return;
+ dma_complete(dbs, -EIO);
}
}
@@ -131,8 +147,14 @@ static void dma_aio_cancel(BlockDriverAIOCB *acb)
DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
if (dbs->acb) {
- bdrv_aio_cancel(dbs->acb);
+ BlockDriverAIOCB *acb = dbs->acb;
+ dbs->acb = NULL;
+ dbs->in_cancel = true;
+ bdrv_aio_cancel(acb);
+ dbs->in_cancel = false;
}
+ dbs->common.cb = NULL;
+ dma_complete(dbs, 0);
}
static AIOPool dma_aio_pool = {
@@ -143,7 +165,7 @@ static AIOPool dma_aio_pool = {
BlockDriverAIOCB *dma_bdrv_io(
BlockDriverState *bs, QEMUSGList *sg, uint64_t sector_num,
DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
- void *opaque, int is_write)
+ void *opaque, bool to_dev)
{
DMAAIOCB *dbs = qemu_aio_get(&dma_aio_pool, bs, cb, opaque);
@@ -153,15 +175,11 @@ BlockDriverAIOCB *dma_bdrv_io(
dbs->sector_num = sector_num;
dbs->sg_cur_index = 0;
dbs->sg_cur_byte = 0;
- dbs->is_write = is_write;
+ dbs->to_dev = to_dev;
dbs->io_func = io_func;
dbs->bh = NULL;
qemu_iovec_init(&dbs->iov, sg->nsg);
dma_bdrv_cb(dbs, 0);
- if (!dbs->acb) {
- qemu_aio_release(dbs);
- return NULL;
- }
return &dbs->common;
}
@@ -170,12 +188,12 @@ BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector,
void (*cb)(void *opaque, int ret), void *opaque)
{
- return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque, 0);
+ return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque, false);
}
BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector,
void (*cb)(void *opaque, int ret), void *opaque)
{
- return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, 1);
+ return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, true);
}
diff --git a/dma.h b/dma.h
index a6db5bacbb..2bdc236c4c 100644
--- a/dma.h
+++ b/dma.h
@@ -15,10 +15,13 @@
#include "hw/hw.h"
#include "block.h"
-typedef struct {
+typedef struct ScatterGatherEntry ScatterGatherEntry;
+
+#if defined(TARGET_PHYS_ADDR_BITS)
+struct ScatterGatherEntry {
target_phys_addr_t base;
target_phys_addr_t len;
-} ScatterGatherEntry;
+};
struct QEMUSGList {
ScatterGatherEntry *sg;
@@ -31,6 +34,7 @@ void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint);
void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base,
target_phys_addr_t len);
void qemu_sglist_destroy(QEMUSGList *qsg);
+#endif
typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
QEMUIOVector *iov, int nb_sectors,
@@ -39,7 +43,7 @@ typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
BlockDriverAIOCB *dma_bdrv_io(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector_num,
DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
- void *opaque, int is_write);
+ void *opaque, bool to_dev);
BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector,
BlockDriverCompletionFunc *cb, void *opaque);
diff --git a/docs/tracing.txt b/docs/tracing.txt
index d0171aabda..95ca16c05d 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -31,8 +31,8 @@ There is a set of static trace events declared in the "trace-events" source
file. Each trace event declaration names the event, its arguments, and the
format string which can be used for pretty-printing:
- qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
- qemu_free(void *ptr) "ptr %p"
+ qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
+ qemu_vfree(void *ptr) "ptr %p"
The "trace-events" file is processed by the "tracetool" script during build to
generate code for the trace events. Trace events are invoked directly from
@@ -40,14 +40,16 @@ source code like this:
#include "trace.h" /* needed for trace event prototype */
- void *qemu_malloc(size_t size)
+ void *qemu_vmalloc(size_t size)
{
void *ptr;
- if (!size && !allow_zero_malloc()) {
- abort();
+ size_t align = QEMU_VMALLOC_ALIGN;
+
+ if (size < align) {
+ align = getpagesize();
}
- ptr = oom_check(malloc(size ? size : 1));
- trace_qemu_malloc(size, ptr); /* <-- trace event */
+ ptr = qemu_memalign(align, size);
+ trace_qemu_vmalloc(size, ptr);
return ptr;
}
@@ -70,11 +72,6 @@ Trace events should use types as follows:
cannot include all user-defined struct declarations and it is therefore
necessary to use void * for pointers to structs.
- Pointers (including char *) cannot be dereferenced easily (or at all) in
- some trace backends. If pointers are used, ensure they are meaningful by
- themselves and do not assume the data they point to will be traced. Do
- not pass in string arguments.
-
* For everything else, use primitive scalar types (char, int, long) with the
appropriate signedness.
@@ -182,6 +179,9 @@ source tree. It may not be as powerful as platform-specific or third-party
trace backends but it is portable. This is the recommended trace backend
unless you have specific needs for more advanced backends.
+The "simple" backend currently does not capture string arguments, it simply
+records the char* pointer value instead of the string that is pointed to.
+
==== Monitor commands ====
* info trace
diff --git a/exec.c b/exec.c
index c1e045d32c..1e6f732d1d 100644
--- a/exec.c
+++ b/exec.c
@@ -183,7 +183,6 @@ typedef struct PageDesc {
#define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS)
unsigned long qemu_real_host_page_size;
-unsigned long qemu_host_page_bits;
unsigned long qemu_host_page_size;
unsigned long qemu_host_page_mask;
@@ -274,9 +273,6 @@ static void page_init(void)
qemu_host_page_size = qemu_real_host_page_size;
if (qemu_host_page_size < TARGET_PAGE_SIZE)
qemu_host_page_size = TARGET_PAGE_SIZE;
- qemu_host_page_bits = 0;
- while ((1 << qemu_host_page_bits) < qemu_host_page_size)
- qemu_host_page_bits++;
qemu_host_page_mask = ~(qemu_host_page_size - 1);
#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
diff --git a/gdbstub.c b/gdbstub.c
index 90683a46c3..12dd100af4 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2373,7 +2373,7 @@ void gdb_set_stop_cpu(CPUState *env)
}
#ifndef CONFIG_USER_ONLY
-static void gdb_vm_state_change(void *opaque, int running, int reason)
+static void gdb_vm_state_change(void *opaque, int running, RunState state)
{
GDBState *s = gdbserver_state;
CPUState *env = s->c_cpu;
@@ -2384,8 +2384,8 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
return;
}
- switch (reason) {
- case VMSTOP_DEBUG:
+ switch (state) {
+ case RSTATE_DEBUG:
if (env->watchpoint_hit) {
switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
case BP_MEM_READ:
@@ -2408,25 +2408,25 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
tb_flush(env);
ret = GDB_SIGNAL_TRAP;
break;
- case VMSTOP_USER:
+ case RSTATE_PAUSED:
ret = GDB_SIGNAL_INT;
break;
- case VMSTOP_SHUTDOWN:
+ case RSTATE_SHUTDOWN:
ret = GDB_SIGNAL_QUIT;
break;
- case VMSTOP_DISKFULL:
+ case RSTATE_IO_ERROR:
ret = GDB_SIGNAL_IO;
break;
- case VMSTOP_WATCHDOG:
+ case RSTATE_WATCHDOG:
ret = GDB_SIGNAL_ALRM;
break;
- case VMSTOP_PANIC:
+ case RSTATE_PANICKED:
ret = GDB_SIGNAL_ABRT;
break;
- case VMSTOP_SAVEVM:
- case VMSTOP_LOADVM:
+ case RSTATE_SAVEVM:
+ case RSTATE_RESTORE:
return;
- case VMSTOP_MIGRATE:
+ case RSTATE_PRE_MIGRATE:
ret = GDB_SIGNAL_XCPU;
break;
default:
@@ -2463,7 +2463,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
gdb_current_syscall_cb = cb;
s->state = RS_SYSCALL;
#ifndef CONFIG_USER_ONLY
- vm_stop(VMSTOP_DEBUG);
+ vm_stop(RSTATE_DEBUG);
#endif
s->state = RS_IDLE;
va_start(va, fmt);
@@ -2534,10 +2534,10 @@ static void gdb_read_byte(GDBState *s, int ch)
if (ch != '$')
return;
}
- if (vm_running) {
+ if (runstate_is_running()) {
/* when the CPU is running, we cannot do anything except stop
it when receiving a char */
- vm_stop(VMSTOP_USER);
+ vm_stop(RSTATE_PAUSED);
} else
#endif
{
@@ -2799,7 +2799,7 @@ static void gdb_chr_event(void *opaque, int event)
{
switch (event) {
case CHR_EVENT_OPENED:
- vm_stop(VMSTOP_USER);
+ vm_stop(RSTATE_PAUSED);
gdb_has_xml = 0;
break;
default:
@@ -2839,8 +2839,8 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
#ifndef _WIN32
static void gdb_sigterm_handler(int signal)
{
- if (vm_running) {
- vm_stop(VMSTOP_USER);
+ if (runstate_is_running()) {
+ vm_stop(RSTATE_PAUSED);
}
}
#endif
diff --git a/hw/ac97.c b/hw/ac97.c
index 541d9a4b97..bc69d4e345 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1311,7 +1311,6 @@ static int ac97_initfn (PCIDevice *dev)
c[PCI_SUBSYSTEM_ID + 1] = 0x00;
c[PCI_INTERRUPT_LINE] = 0x00; /* intr_ln interrupt line rw */
- /* TODO: RST# value should be 0. */
c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */
memory_region_init_io (&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024);
diff --git a/hw/e1000.c b/hw/e1000.c
index a6d12c55fb..6a3a941488 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1156,8 +1156,7 @@ static int pci_e1000_init(PCIDevice *pci_dev)
/* TODO: RST# value should be 0, PCI spec 6.2.4 */
pci_conf[PCI_CACHE_LINE_SIZE] = 0x10;
- /* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */
- pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
+ pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
e1000_mmio_setup(d);
diff --git a/hw/es1370.c b/hw/es1370.c
index a9387d15cc..2daadde0e6 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1003,7 +1003,6 @@ static int es1370_initfn (PCIDevice *dev)
c[0xdc] = 0x00;
#endif
- /* TODO: RST# value should be 0. */
c[PCI_INTERRUPT_PIN] = 1;
c[PCI_MIN_GNT] = 0x0c;
c[PCI_MAX_LAT] = 0x80;
diff --git a/hw/etraxfs_dma.c b/hw/etraxfs_dma.c
index e8ad9e6a0b..d3082acc8f 100644
--- a/hw/etraxfs_dma.c
+++ b/hw/etraxfs_dma.c
@@ -732,7 +732,7 @@ static void DMA_run(void *opaque)
struct fs_dma_ctrl *etraxfs_dmac = opaque;
int p = 1;
- if (vm_running)
+ if (runstate_is_running())
p = etraxfs_dmac_run(etraxfs_dmac);
if (p)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index a8659cf8b9..226230ca2b 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -499,10 +499,7 @@ static void ahci_reset_port(AHCIState *s, int port)
ide_bus_reset(&d->port);
ide_state->ncq_queues = AHCI_MAX_CMDS;
- pr->irq_stat = 0;
- pr->irq_mask = 0;
pr->scr_stat = 0;
- pr->scr_ctl = 0;
pr->scr_err = 0;
pr->scr_act = 0;
d->busy_slot = -1;
@@ -1103,7 +1100,7 @@ static void ahci_irq_set(void *opaque, int n, int level)
{
}
-static void ahci_dma_restart_cb(void *opaque, int running, int reason)
+static void ahci_dma_restart_cb(void *opaque, int running, RunState state)
{
}
@@ -1159,12 +1156,17 @@ void ahci_uninit(AHCIState *s)
void ahci_reset(void *opaque)
{
struct AHCIPCIState *d = opaque;
+ AHCIPortRegs *pr;
int i;
d->ahci.control_regs.irqstatus = 0;
d->ahci.control_regs.ghc = 0;
for (i = 0; i < d->ahci.ports; i++) {
+ pr = &d->ahci.dev[i].port_regs;
+ pr->irq_stat = 0;
+ pr->irq_mask = 0;
+ pr->scr_ctl = 0;
ahci_reset_port(&d->ahci, i);
}
}
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 9297b9e657..4e76fc78d3 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -527,7 +527,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
s->bus->error_status = op;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(VMSTOP_DISKFULL);
+ vm_stop(RSTATE_IO_ERROR);
} else {
if (op & BM_STATUS_DMA_RETRY) {
dma_buf_commit(s, 0);
@@ -603,7 +603,7 @@ handle_rw_error:
break;
case IDE_DMA_TRIM:
s->bus->dma->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
- ide_issue_trim, ide_dma_cb, s, 1);
+ ide_issue_trim, ide_dma_cb, s, true);
break;
}
@@ -1910,7 +1910,7 @@ static int ide_nop_int(IDEDMA *dma, int x)
return 0;
}
-static void ide_nop_restart(void *opaque, int x, int y)
+static void ide_nop_restart(void *opaque, int x, RunState y)
{
}
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 233915ce0d..9046e96013 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -9,6 +9,7 @@
#include <hw/ide.h>
#include "iorange.h"
#include "dma.h"
+#include "sysemu.h"
/* debug IDE devices */
//#define DEBUG_IDE
@@ -387,7 +388,7 @@ typedef void EndTransferFunc(IDEState *);
typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *);
typedef int DMAFunc(IDEDMA *);
typedef int DMAIntFunc(IDEDMA *, int);
-typedef void DMARestartFunc(void *, int, int);
+typedef void DMARestartFunc(void *, int, RunState);
struct unreported_events {
bool eject_request;
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index c1844cb738..37b8239b4d 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -156,7 +156,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
break;
case IDE_DMA_TRIM:
m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
- ide_issue_trim, pmac_ide_transfer_cb, s, 1);
+ ide_issue_trim, pmac_ide_transfer_cb, s, true);
break;
}
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 9fded02954..f133c422b6 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -222,7 +222,7 @@ static void bmdma_restart_bh(void *opaque)
}
}
-static void bmdma_restart_cb(void *opaque, int running, int reason)
+static void bmdma_restart_cb(void *opaque, int running, RunState state)
{
IDEDMA *dma = opaque;
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
diff --git a/hw/kvmclock.c b/hw/kvmclock.c
index b73aec409c..5388bc489d 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -46,7 +46,7 @@ static void kvmclock_pre_save(void *opaque)
* it on next vmsave (which would return a different value). Will be reset
* when the VM is continued.
*/
- s->clock_valid = !vm_running;
+ s->clock_valid = !runstate_is_running();
}
static int kvmclock_post_load(void *opaque, int version_id)
@@ -59,7 +59,8 @@ static int kvmclock_post_load(void *opaque, int version_id)
return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
}
-static void kvmclock_vm_state_change(void *opaque, int running, int reason)
+static void kvmclock_vm_state_change(void *opaque, int running,
+ RunState state)
{
KVMClockState *s = opaque;
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index dbb3bdf2ce..75a03a74b9 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2106,8 +2106,7 @@ static int lsi_scsi_init(PCIDevice *dev)
/* PCI latency timer = 255 */
pci_conf[PCI_LATENCY_TIMER] = 0xff;
- /* TODO: RST# value should be 0 */
- /* Interrupt pin 1 */
+ /* Interrupt pin A */
pci_conf[PCI_INTERRUPT_PIN] = 0x01;
memory_region_init_io(&s->mmio_io, &lsi_mmio_ops, s, "lsi-mmio", 0x400);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index f3c9f93204..7cac5da920 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -52,44 +52,42 @@ static void main_cpu_reset(void *opaque)
cpu_reset(env);
}
-static uint32_t rtc_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t rtc_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
return cpu_inw(0x71);
}
-static void rtc_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void rtc_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
cpu_outw(0x71, val & 0xff);
}
-static CPUReadMemoryFunc * const rtc_read[3] = {
- rtc_readb,
- rtc_readb,
- rtc_readb,
+static const MemoryRegionOps rtc_ops = {
+ .read = rtc_read,
+ .write = rtc_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static CPUWriteMemoryFunc * const rtc_write[3] = {
- rtc_writeb,
- rtc_writeb,
- rtc_writeb,
-};
-
-static void dma_dummy_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static uint64_t dma_dummy_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
/* Nothing to do. That is only to ensure that
* the current DMA acknowledge cycle is completed. */
+ return 0xff;
}
-static CPUReadMemoryFunc * const dma_dummy_read[3] = {
- NULL,
- NULL,
- NULL,
-};
+static void dma_dummy_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
+{
+ /* Nothing to do. That is only to ensure that
+ * the current DMA acknowledge cycle is completed. */
+}
-static CPUWriteMemoryFunc * const dma_dummy_write[3] = {
- dma_dummy_writeb,
- dma_dummy_writeb,
- dma_dummy_writeb,
+static const MemoryRegionOps dma_dummy_ops = {
+ .read = dma_dummy_read,
+ .write = dma_dummy_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
#define MAGNUM_BIOS_SIZE_MAX 0x7e000
@@ -105,7 +103,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
}
static
-void mips_jazz_init (ram_addr_t ram_size,
+void mips_jazz_init (MemoryRegion *address_space, ram_addr_t ram_size,
const char *cpu_model,
enum jazz_model_e jazz_model)
{
@@ -115,7 +113,8 @@ void mips_jazz_init (ram_addr_t ram_size,
qemu_irq *rc4030, *i8259;
rc4030_dma *dmas;
void* rc4030_opaque;
- int s_rtc, s_dma_dummy;
+ MemoryRegion *rtc = g_new(MemoryRegion, 1);
+ MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
NICInfo *nd;
DeviceState *dev;
SysBusDevice *sysbus;
@@ -123,8 +122,9 @@ void mips_jazz_init (ram_addr_t ram_size,
DriveInfo *fds[MAX_FD];
qemu_irq esp_reset, dma_enable;
qemu_irq *cpu_exit_irq;
- ram_addr_t ram_offset;
- ram_addr_t bios_offset;
+ MemoryRegion *ram = g_new(MemoryRegion, 1);
+ MemoryRegion *bios = g_new(MemoryRegion, 1);
+ MemoryRegion *bios2 = g_new(MemoryRegion, 1);
/* init CPUs */
if (cpu_model == NULL) {
@@ -143,14 +143,15 @@ void mips_jazz_init (ram_addr_t ram_size,
qemu_register_reset(main_cpu_reset, env);
/* allocate RAM */
- ram_offset = qemu_ram_alloc(NULL, "mips_jazz.ram", ram_size);
- cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
+ memory_region_init_ram(ram, NULL, "mips_jazz.ram", ram_size);
+ memory_region_add_subregion(address_space, 0, ram);
- bios_offset = qemu_ram_alloc(NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE);
- cpu_register_physical_memory(0x1fc00000LL,
- MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
- cpu_register_physical_memory(0xfff00000LL,
- MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
+ memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE);
+ memory_region_set_readonly(bios, true);
+ memory_region_init_alias(bios2, "mips_jazz.bios", bios,
+ 0, MAGNUM_BIOS_SIZE);
+ memory_region_add_subregion(address_space, 0x1fc00000LL, bios);
+ memory_region_add_subregion(address_space, 0xfff00000LL, bios2);
/* load the BIOS image. */
if (bios_name == NULL)
@@ -175,9 +176,8 @@ void mips_jazz_init (ram_addr_t ram_size,
/* Chipset */
rc4030_opaque = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas);
- s_dma_dummy = cpu_register_io_memory(dma_dummy_read, dma_dummy_write, NULL,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(0x8000d000, 0x00001000, s_dma_dummy);
+ memory_region_init_io(dma_dummy, &dma_dummy_ops, NULL, "dummy_dma", 0x1000);
+ memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
/* ISA devices */
i8259 = i8259_init(env->irq[4]);
@@ -203,10 +203,11 @@ void mips_jazz_init (ram_addr_t ram_size,
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);
+ MemoryRegion *rom_mr = g_new(MemoryRegion, 1);
+ memory_region_init_ram(rom_mr, NULL, "g364fb.rom", 0x80000);
+ memory_region_set_readonly(rom_mr, true);
+ uint8_t *rom = memory_region_get_ram_ptr(rom_mr);
+ memory_region_add_subregion(address_space, 0x60000000, rom_mr);
rom[0] = 0x10; /* Mips G364 */
}
break;
@@ -252,9 +253,8 @@ void mips_jazz_init (ram_addr_t ram_size,
/* Real time clock */
rtc_init(1980, NULL);
- s_rtc = cpu_register_io_memory(rtc_read, rtc_write, NULL,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc);
+ memory_region_init_io(rtc, &rtc_ops, NULL, "rtc", 0x1000);
+ memory_region_add_subregion(address_space, 0x80004000, rtc);
/* Keyboard (i8042) */
i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0x1000, 0x1);
@@ -299,7 +299,7 @@ void mips_magnum_init (ram_addr_t ram_size,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
{
- mips_jazz_init(ram_size, cpu_model, JAZZ_MAGNUM);
+ mips_jazz_init(get_system_memory(), ram_size, cpu_model, JAZZ_MAGNUM);
}
static
@@ -308,7 +308,7 @@ void mips_pica61_init (ram_addr_t ram_size,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
{
- mips_jazz_init(ram_size, cpu_model, JAZZ_PICA61);
+ mips_jazz_init(get_system_memory(), ram_size, cpu_model, JAZZ_PICA61);
}
static QEMUMachine mips_magnum_machine = {
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index e7cdf2091b..0110daa1a3 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -57,6 +57,9 @@
#define MAX_IDE_BUS 2
typedef struct {
+ MemoryRegion iomem;
+ MemoryRegion iomem_lo; /* 0 - 0x900 */
+ MemoryRegion iomem_hi; /* 0xa00 - 0x100000 */
uint32_t leds;
uint32_t brk;
uint32_t gpout;
@@ -215,7 +218,8 @@ static void eeprom24c0x_write(int scl, int sda)
eeprom.sda = sda;
}
-static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t malta_fpga_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
MaltaFPGAState *s = opaque;
uint32_t val = 0;
@@ -302,8 +306,8 @@ static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
return val;
}
-static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void malta_fpga_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
MaltaFPGAState *s = opaque;
uint32_t saddr;
@@ -328,7 +332,7 @@ static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
/* ASCIIWORD Register */
case 0x00410:
- snprintf(s->display_text, 9, "%08X", val);
+ snprintf(s->display_text, 9, "%08X", (uint32_t)val);
malta_fpga_update_display(s);
break;
@@ -388,16 +392,10 @@ static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const malta_fpga_read[] = {
- malta_fpga_readl,
- malta_fpga_readl,
- malta_fpga_readl
-};
-
-static CPUWriteMemoryFunc * const malta_fpga_write[] = {
- malta_fpga_writel,
- malta_fpga_writel,
- malta_fpga_writel
+static const MemoryRegionOps malta_fpga_ops = {
+ .read = malta_fpga_read,
+ .write = malta_fpga_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void malta_fpga_reset(void *opaque)
@@ -429,20 +427,22 @@ static void malta_fpga_led_init(CharDriverState *chr)
qemu_chr_fe_printf(chr, "+--------+\r\n");
}
-static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr)
+static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
+ target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr)
{
MaltaFPGAState *s;
- int malta;
s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
- malta = cpu_register_io_memory(malta_fpga_read,
- malta_fpga_write, s,
- DEVICE_NATIVE_ENDIAN);
+ memory_region_init_io(&s->iomem, &malta_fpga_ops, s,
+ "malta-fpga", 0x100000);
+ memory_region_init_alias(&s->iomem_lo, "malta-fpga",
+ &s->iomem, 0, 0x900);
+ memory_region_init_alias(&s->iomem_hi, "malta-fpga",
+ &s->iomem, 0xa00, 0x10000-0xa00);
- cpu_register_physical_memory(base, 0x900, malta);
- /* 0xa00 is less than a page, so will still get the right offsets. */
- cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
+ memory_region_add_subregion(address_space, base, &s->iomem_lo);
+ memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
@@ -771,8 +771,8 @@ void mips_malta_init (ram_addr_t ram_size,
{
char *filename;
pflash_t *fl;
- ram_addr_t ram_offset;
MemoryRegion *system_memory = get_system_memory();
+ MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1);
target_long bios_size;
int64_t kernel_entry;
@@ -828,9 +828,8 @@ void mips_malta_init (ram_addr_t ram_size,
((unsigned int)ram_size / (1 << 20)));
exit(1);
}
- ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
-
- cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
+ memory_region_init_ram(ram, NULL, "mips_malta.ram", ram_size);
+ memory_region_add_subregion(system_memory, 0, ram);
#ifdef TARGET_WORDS_BIGENDIAN
be = 1;
@@ -838,7 +837,7 @@ void mips_malta_init (ram_addr_t ram_size,
be = 0;
#endif
/* FPGA */
- malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
+ malta_fpga_init(system_memory, 0x1f000000LL, env->irq[2], serial_hds[2]);
/* Load firmware in flash / BIOS unless we boot directly into a kernel. */
if (kernel_filename) {
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index ac65555b74..740715854b 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -137,8 +137,9 @@ mips_mipssim_init (ram_addr_t ram_size,
const char *initrd_filename, const char *cpu_model)
{
char *filename;
- ram_addr_t ram_offset;
- ram_addr_t bios_offset;
+ MemoryRegion *address_space_mem = get_system_memory();
+ MemoryRegion *ram = g_new(MemoryRegion, 1);
+ MemoryRegion *bios = g_new(MemoryRegion, 1);
CPUState *env;
ResetData *reset_info;
int bios_size;
@@ -162,14 +163,14 @@ mips_mipssim_init (ram_addr_t ram_size,
qemu_register_reset(main_cpu_reset, reset_info);
/* Allocate RAM. */
- ram_offset = qemu_ram_alloc(NULL, "mips_mipssim.ram", ram_size);
- bios_offset = qemu_ram_alloc(NULL, "mips_mipssim.bios", BIOS_SIZE);
+ memory_region_init_ram(ram, NULL, "mips_mipssim.ram", ram_size);
+ memory_region_init_ram(bios, NULL, "mips_mipssim.bios", BIOS_SIZE);
+ memory_region_set_readonly(bios, true);
- cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
+ memory_region_add_subregion(address_space_mem, 0, ram);
/* Map the BIOS / boot exception handler. */
- cpu_register_physical_memory(0x1fc00000LL,
- BIOS_SIZE, bios_offset | IO_MEM_ROM);
+ memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
/* Load a BIOS / boot exception handler image. */
if (bios_name == NULL)
bios_name = BIOS_FILENAME;
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 5d002c5a2b..805d02a4eb 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -42,8 +42,8 @@ static struct _loaderparams {
const char *initrd_filename;
} loaderparams;
-static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void mips_qemu_write (void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
if ((addr & 0xffff) == 0 && val == 42)
qemu_system_reset_request ();
@@ -51,25 +51,18 @@ static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
qemu_system_shutdown_request ();
}
-static uint32_t mips_qemu_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t mips_qemu_read (void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
return 0;
}
-static CPUWriteMemoryFunc * const mips_qemu_write[] = {
- &mips_qemu_writel,
- &mips_qemu_writel,
- &mips_qemu_writel,
+static const MemoryRegionOps mips_qemu_ops = {
+ .read = mips_qemu_read,
+ .write = mips_qemu_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static CPUReadMemoryFunc * const mips_qemu_read[] = {
- &mips_qemu_readl,
- &mips_qemu_readl,
- &mips_qemu_readl,
-};
-
-static int mips_qemu_iomemtype = 0;
-
typedef struct ResetData {
CPUState *env;
uint64_t vector;
@@ -163,8 +156,10 @@ void mips_r4k_init (ram_addr_t ram_size,
const char *initrd_filename, const char *cpu_model)
{
char *filename;
- ram_addr_t ram_offset;
+ MemoryRegion *address_space_mem = get_system_memory();
+ MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *bios;
+ MemoryRegion *iomem = g_new(MemoryRegion, 1);
int bios_size;
CPUState *env;
ResetData *reset_info;
@@ -199,16 +194,12 @@ void mips_r4k_init (ram_addr_t ram_size,
((unsigned int)ram_size / (1 << 20)));
exit(1);
}
- ram_offset = qemu_ram_alloc(NULL, "mips_r4k.ram", ram_size);
+ memory_region_init_ram(ram, NULL, "mips_r4k.ram", ram_size);
- cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
+ memory_region_add_subregion(address_space_mem, 0, ram);
- if (!mips_qemu_iomemtype) {
- mips_qemu_iomemtype = cpu_register_io_memory(mips_qemu_read,
- mips_qemu_write, NULL,
- DEVICE_NATIVE_ENDIAN);
- }
- cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype);
+ memory_region_init_io(iomem, &mips_qemu_ops, NULL, "mips-qemu", 0x10000);
+ memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem);
/* Try to load a BIOS image. If this fails, we continue regardless,
but initialize the hardware ourselves. When a kernel gets
diff --git a/hw/musicpal.c b/hw/musicpal.c
index ade5a91feb..9b1f38062b 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -19,6 +19,7 @@
#include "console.h"
#include "i2c.h"
#include "blockdev.h"
+#include "exec-memory.h"
#define MP_MISC_BASE 0x80002000
#define MP_MISC_SIZE 0x00001000
@@ -142,6 +143,7 @@ typedef struct mv88w8618_rx_desc {
typedef struct mv88w8618_eth_state {
SysBusDevice busdev;
+ MemoryRegion iomem;
qemu_irq irq;
uint32_t smir;
uint32_t icr;
@@ -260,7 +262,8 @@ static void eth_send(mv88w8618_eth_state *s, int queue_index)
} while (desc_addr != s->tx_queue[queue_index]);
}
-static uint32_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset)
+static uint64_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
mv88w8618_eth_state *s = opaque;
@@ -302,7 +305,7 @@ static uint32_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset)
}
static void mv88w8618_eth_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
mv88w8618_eth_state *s = opaque;
@@ -353,16 +356,10 @@ static void mv88w8618_eth_write(void *opaque, target_phys_addr_t offset,
}
}
-static CPUReadMemoryFunc * const mv88w8618_eth_readfn[] = {
- mv88w8618_eth_read,
- mv88w8618_eth_read,
- mv88w8618_eth_read
-};
-
-static CPUWriteMemoryFunc * const mv88w8618_eth_writefn[] = {
- mv88w8618_eth_write,
- mv88w8618_eth_write,
- mv88w8618_eth_write
+static const MemoryRegionOps mv88w8618_eth_ops = {
+ .read = mv88w8618_eth_read,
+ .write = mv88w8618_eth_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void eth_cleanup(VLANClientState *nc)
@@ -387,10 +384,9 @@ static int mv88w8618_eth_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
dev->qdev.info->name, dev->qdev.id, s);
- s->mmio_index = cpu_register_io_memory(mv88w8618_eth_readfn,
- mv88w8618_eth_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, MP_ETH_SIZE, s->mmio_index);
+ memory_region_init_io(&s->iomem, &mv88w8618_eth_ops, s, "mv88w8618-eth",
+ MP_ETH_SIZE);
+ sysbus_init_mmio_region(dev, &s->iomem);
return 0;
}
@@ -444,6 +440,7 @@ static SysBusDeviceInfo mv88w8618_eth_info = {
typedef struct musicpal_lcd_state {
SysBusDevice busdev;
+ MemoryRegion iomem;
uint32_t brightness;
uint32_t mode;
uint32_t irqctrl;
@@ -528,7 +525,8 @@ static void musicpal_lcd_gpio_brigthness_in(void *opaque, int irq, int level)
s->brightness |= level << irq;
}
-static uint32_t musicpal_lcd_read(void *opaque, target_phys_addr_t offset)
+static uint64_t musicpal_lcd_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
musicpal_lcd_state *s = opaque;
@@ -542,7 +540,7 @@ static uint32_t musicpal_lcd_read(void *opaque, target_phys_addr_t offset)
}
static void musicpal_lcd_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
musicpal_lcd_state *s = opaque;
@@ -581,29 +579,21 @@ static void musicpal_lcd_write(void *opaque, target_phys_addr_t offset,
}
}
-static CPUReadMemoryFunc * const musicpal_lcd_readfn[] = {
- musicpal_lcd_read,
- musicpal_lcd_read,
- musicpal_lcd_read
-};
-
-static CPUWriteMemoryFunc * const musicpal_lcd_writefn[] = {
- musicpal_lcd_write,
- musicpal_lcd_write,
- musicpal_lcd_write
+static const MemoryRegionOps musicpal_lcd_ops = {
+ .read = musicpal_lcd_read,
+ .write = musicpal_lcd_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static int musicpal_lcd_init(SysBusDevice *dev)
{
musicpal_lcd_state *s = FROM_SYSBUS(musicpal_lcd_state, dev);
- int iomemtype;
s->brightness = 7;
- iomemtype = cpu_register_io_memory(musicpal_lcd_readfn,
- musicpal_lcd_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, MP_LCD_SIZE, iomemtype);
+ memory_region_init_io(&s->iomem, &musicpal_lcd_ops, s,
+ "musicpal-lcd", MP_LCD_SIZE);
+ sysbus_init_mmio_region(dev, &s->iomem);
s->ds = graphic_console_init(lcd_refresh, lcd_invalidate,
NULL, NULL, s);
@@ -645,6 +635,7 @@ static SysBusDeviceInfo musicpal_lcd_info = {
typedef struct mv88w8618_pic_state
{
SysBusDevice busdev;
+ MemoryRegion iomem;
uint32_t level;
uint32_t enabled;
qemu_irq parent_irq;
@@ -667,7 +658,8 @@ static void mv88w8618_pic_set_irq(void *opaque, int irq, int level)
mv88w8618_pic_update(s);
}
-static uint32_t mv88w8618_pic_read(void *opaque, target_phys_addr_t offset)
+static uint64_t mv88w8618_pic_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
mv88w8618_pic_state *s = opaque;
@@ -681,7 +673,7 @@ static uint32_t mv88w8618_pic_read(void *opaque, target_phys_addr_t offset)
}
static void mv88w8618_pic_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
mv88w8618_pic_state *s = opaque;
@@ -707,29 +699,21 @@ static void mv88w8618_pic_reset(DeviceState *d)
s->enabled = 0;
}
-static CPUReadMemoryFunc * const mv88w8618_pic_readfn[] = {
- mv88w8618_pic_read,
- mv88w8618_pic_read,
- mv88w8618_pic_read
-};
-
-static CPUWriteMemoryFunc * const mv88w8618_pic_writefn[] = {
- mv88w8618_pic_write,
- mv88w8618_pic_write,
- mv88w8618_pic_write
+static const MemoryRegionOps mv88w8618_pic_ops = {
+ .read = mv88w8618_pic_read,
+ .write = mv88w8618_pic_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static int mv88w8618_pic_init(SysBusDevice *dev)
{
mv88w8618_pic_state *s = FROM_SYSBUS(mv88w8618_pic_state, dev);
- int iomemtype;
qdev_init_gpio_in(&dev->qdev, mv88w8618_pic_set_irq, 32);
sysbus_init_irq(dev, &s->parent_irq);
- iomemtype = cpu_register_io_memory(mv88w8618_pic_readfn,
- mv88w8618_pic_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, MP_PIC_SIZE, iomemtype);
+ memory_region_init_io(&s->iomem, &mv88w8618_pic_ops, s,
+ "musicpal-pic", MP_PIC_SIZE);
+ sysbus_init_mmio_region(dev, &s->iomem);
return 0;
}
@@ -775,6 +759,7 @@ typedef struct mv88w8618_timer_state {
typedef struct mv88w8618_pit_state {
SysBusDevice busdev;
+ MemoryRegion iomem;
mv88w8618_timer_state timer[4];
} mv88w8618_pit_state;
@@ -797,7 +782,8 @@ static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
s->ptimer = ptimer_init(bh);
}
-static uint32_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset)
+static uint64_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
mv88w8618_pit_state *s = opaque;
mv88w8618_timer_state *t;
@@ -813,7 +799,7 @@ static uint32_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset)
}
static void mv88w8618_pit_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
mv88w8618_pit_state *s = opaque;
mv88w8618_timer_state *t;
@@ -864,21 +850,14 @@ static void mv88w8618_pit_reset(DeviceState *d)
}
}
-static CPUReadMemoryFunc * const mv88w8618_pit_readfn[] = {
- mv88w8618_pit_read,
- mv88w8618_pit_read,
- mv88w8618_pit_read
-};
-
-static CPUWriteMemoryFunc * const mv88w8618_pit_writefn[] = {
- mv88w8618_pit_write,
- mv88w8618_pit_write,
- mv88w8618_pit_write
+static const MemoryRegionOps mv88w8618_pit_ops = {
+ .read = mv88w8618_pit_read,
+ .write = mv88w8618_pit_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static int mv88w8618_pit_init(SysBusDevice *dev)
{
- int iomemtype;
mv88w8618_pit_state *s = FROM_SYSBUS(mv88w8618_pit_state, dev);
int i;
@@ -888,10 +867,9 @@ static int mv88w8618_pit_init(SysBusDevice *dev)
mv88w8618_timer_init(dev, &s->timer[i], 1000000);
}
- iomemtype = cpu_register_io_memory(mv88w8618_pit_readfn,
- mv88w8618_pit_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, MP_PIT_SIZE, iomemtype);
+ memory_region_init_io(&s->iomem, &mv88w8618_pit_ops, s,
+ "musicpal-pit", MP_PIT_SIZE);
+ sysbus_init_mmio_region(dev, &s->iomem);
return 0;
}
@@ -932,11 +910,13 @@ static SysBusDeviceInfo mv88w8618_pit_info = {
typedef struct mv88w8618_flashcfg_state {
SysBusDevice busdev;
+ MemoryRegion iomem;
uint32_t cfgr0;
} mv88w8618_flashcfg_state;
-static uint32_t mv88w8618_flashcfg_read(void *opaque,
- target_phys_addr_t offset)
+static uint64_t mv88w8618_flashcfg_read(void *opaque,
+ target_phys_addr_t offset,
+ unsigned size)
{
mv88w8618_flashcfg_state *s = opaque;
@@ -950,7 +930,7 @@ static uint32_t mv88w8618_flashcfg_read(void *opaque,
}
static void mv88w8618_flashcfg_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
mv88w8618_flashcfg_state *s = opaque;
@@ -961,28 +941,20 @@ static void mv88w8618_flashcfg_write(void *opaque, target_phys_addr_t offset,
}
}
-static CPUReadMemoryFunc * const mv88w8618_flashcfg_readfn[] = {
- mv88w8618_flashcfg_read,
- mv88w8618_flashcfg_read,
- mv88w8618_flashcfg_read
-};
-
-static CPUWriteMemoryFunc * const mv88w8618_flashcfg_writefn[] = {
- mv88w8618_flashcfg_write,
- mv88w8618_flashcfg_write,
- mv88w8618_flashcfg_write
+static const MemoryRegionOps mv88w8618_flashcfg_ops = {
+ .read = mv88w8618_flashcfg_read,
+ .write = mv88w8618_flashcfg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static int mv88w8618_flashcfg_init(SysBusDevice *dev)
{
- int iomemtype;
mv88w8618_flashcfg_state *s = FROM_SYSBUS(mv88w8618_flashcfg_state, dev);
s->cfgr0 = 0xfffe4285; /* Default as set by U-Boot for 8 MB flash */
- iomemtype = cpu_register_io_memory(mv88w8618_flashcfg_readfn,
- mv88w8618_flashcfg_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, MP_FLASHCFG_SIZE, iomemtype);
+ memory_region_init_io(&s->iomem, &mv88w8618_flashcfg_ops, s,
+ "musicpal-flashcfg", MP_FLASHCFG_SIZE);
+ sysbus_init_mmio_region(dev, &s->iomem);
return 0;
}
@@ -1009,7 +981,8 @@ static SysBusDeviceInfo mv88w8618_flashcfg_info = {
#define MP_BOARD_REVISION 0x31
-static uint32_t musicpal_misc_read(void *opaque, target_phys_addr_t offset)
+static uint64_t musicpal_misc_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
switch (offset) {
case MP_MISC_BOARD_REVISION:
@@ -1021,37 +994,31 @@ static uint32_t musicpal_misc_read(void *opaque, target_phys_addr_t offset)
}
static void musicpal_misc_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
}
-static CPUReadMemoryFunc * const musicpal_misc_readfn[] = {
- musicpal_misc_read,
- musicpal_misc_read,
- musicpal_misc_read,
-};
-
-static CPUWriteMemoryFunc * const musicpal_misc_writefn[] = {
- musicpal_misc_write,
- musicpal_misc_write,
- musicpal_misc_write,
+static const MemoryRegionOps musicpal_misc_ops = {
+ .read = musicpal_misc_read,
+ .write = musicpal_misc_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static void musicpal_misc_init(void)
+static void musicpal_misc_init(SysBusDevice *dev)
{
- int iomemtype;
+ MemoryRegion *iomem = g_new(MemoryRegion, 1);
- iomemtype = cpu_register_io_memory(musicpal_misc_readfn,
- musicpal_misc_writefn, NULL,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(MP_MISC_BASE, MP_MISC_SIZE, iomemtype);
+ memory_region_init_io(iomem, &musicpal_misc_ops, NULL,
+ "musicpal-misc", MP_MISC_SIZE);
+ sysbus_add_memory(dev, MP_MISC_BASE, iomem);
}
/* WLAN register offsets */
#define MP_WLAN_MAGIC1 0x11c
#define MP_WLAN_MAGIC2 0x124
-static uint32_t mv88w8618_wlan_read(void *opaque, target_phys_addr_t offset)
+static uint64_t mv88w8618_wlan_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
switch (offset) {
/* Workaround to allow loading the binary-only wlandrv.ko crap
@@ -1067,30 +1034,23 @@ static uint32_t mv88w8618_wlan_read(void *opaque, target_phys_addr_t offset)
}
static void mv88w8618_wlan_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
}
-static CPUReadMemoryFunc * const mv88w8618_wlan_readfn[] = {
- mv88w8618_wlan_read,
- mv88w8618_wlan_read,
- mv88w8618_wlan_read,
-};
-
-static CPUWriteMemoryFunc * const mv88w8618_wlan_writefn[] = {
- mv88w8618_wlan_write,
- mv88w8618_wlan_write,
- mv88w8618_wlan_write,
+static const MemoryRegionOps mv88w8618_wlan_ops = {
+ .read = mv88w8618_wlan_read,
+ .write =mv88w8618_wlan_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static int mv88w8618_wlan_init(SysBusDevice *dev)
{
- int iomemtype;
+ MemoryRegion *iomem = g_new(MemoryRegion, 1);
- iomemtype = cpu_register_io_memory(mv88w8618_wlan_readfn,
- mv88w8618_wlan_writefn, NULL,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, MP_WLAN_SIZE, iomemtype);
+ memory_region_init_io(iomem, &mv88w8618_wlan_ops, NULL,
+ "musicpal-wlan", MP_WLAN_SIZE);
+ sysbus_init_mmio_region(dev, iomem);
return 0;
}
@@ -1118,6 +1078,7 @@ static int mv88w8618_wlan_init(SysBusDevice *dev)
typedef struct musicpal_gpio_state {
SysBusDevice busdev;
+ MemoryRegion iomem;
uint32_t lcd_brightness;
uint32_t out_state;
uint32_t in_state;
@@ -1190,7 +1151,8 @@ static void musicpal_gpio_pin_event(void *opaque, int pin, int level)
}
}
-static uint32_t musicpal_gpio_read(void *opaque, target_phys_addr_t offset)
+static uint64_t musicpal_gpio_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
musicpal_gpio_state *s = opaque;
@@ -1229,7 +1191,7 @@ static uint32_t musicpal_gpio_read(void *opaque, target_phys_addr_t offset)
}
static void musicpal_gpio_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
musicpal_gpio_state *s = opaque;
switch (offset) {
@@ -1267,16 +1229,10 @@ static void musicpal_gpio_write(void *opaque, target_phys_addr_t offset,
}
}
-static CPUReadMemoryFunc * const musicpal_gpio_readfn[] = {
- musicpal_gpio_read,
- musicpal_gpio_read,
- musicpal_gpio_read,
-};
-
-static CPUWriteMemoryFunc * const musicpal_gpio_writefn[] = {
- musicpal_gpio_write,
- musicpal_gpio_write,
- musicpal_gpio_write,
+static const MemoryRegionOps musicpal_gpio_ops = {
+ .read = musicpal_gpio_read,
+ .write = musicpal_gpio_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void musicpal_gpio_reset(DeviceState *d)
@@ -1295,14 +1251,12 @@ static void musicpal_gpio_reset(DeviceState *d)
static int musicpal_gpio_init(SysBusDevice *dev)
{
musicpal_gpio_state *s = FROM_SYSBUS(musicpal_gpio_state, dev);
- int iomemtype;
sysbus_init_irq(dev, &s->irq);
- iomemtype = cpu_register_io_memory(musicpal_gpio_readfn,
- musicpal_gpio_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, MP_GPIO_SIZE, iomemtype);
+ memory_region_init_io(&s->iomem, &musicpal_gpio_ops, s,
+ "musicpal-gpio", MP_GPIO_SIZE);
+ sysbus_init_mmio_region(dev, &s->iomem);
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
@@ -1501,7 +1455,9 @@ static void musicpal_init(ram_addr_t ram_size,
int i;
unsigned long flash_size;
DriveInfo *dinfo;
- ram_addr_t sram_off;
+ MemoryRegion *address_space_mem = get_system_memory();
+ MemoryRegion *ram = g_new(MemoryRegion, 1);
+ MemoryRegion *sram = g_new(MemoryRegion, 1);
if (!cpu_model) {
cpu_model = "arm926";
@@ -1514,12 +1470,11 @@ static void musicpal_init(ram_addr_t ram_size,
cpu_pic = arm_pic_init_cpu(env);
/* For now we use a fixed - the original - RAM size */
- cpu_register_physical_memory(0, MP_RAM_DEFAULT_SIZE,
- qemu_ram_alloc(NULL, "musicpal.ram",
- MP_RAM_DEFAULT_SIZE));
+ memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE);
+ memory_region_add_subregion(address_space_mem, 0, ram);
- sram_off = qemu_ram_alloc(NULL, "musicpal.sram", MP_SRAM_SIZE);
- cpu_register_physical_memory(MP_SRAM_BASE, MP_SRAM_SIZE, sram_off);
+ memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE);
+ memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
dev = sysbus_create_simple("mv88w8618_pic", MP_PIC_BASE,
cpu_pic[ARM_PIC_CPU_IRQ]);
@@ -1594,7 +1549,7 @@ static void musicpal_init(ram_addr_t ram_size,
sysbus_create_simple("mv88w8618_wlan", MP_WLAN_BASE, NULL);
- musicpal_misc_init();
+ musicpal_misc_init(sysbus_from_qdev(dev));
dev = sysbus_create_simple("musicpal_gpio", MP_GPIO_BASE, pic[MP_GPIO_IRQ]);
i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);
diff --git a/hw/ne2000.c b/hw/ne2000.c
index a035a85244..62e082f8a9 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -749,8 +749,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
uint8_t *pci_conf;
pci_conf = d->dev.config;
- /* TODO: RST# value should be 0. PCI spec 6.2.4 */
- pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
+ pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
s = &d->ne2000;
ne2000_setup_io(s, 0x100);
diff --git a/hw/omap.h b/hw/omap.h
index d9ab006ae0..0260cc0d4a 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -678,7 +678,8 @@ void omap_uart_reset(struct omap_uart_s *s);
void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr);
struct omap_mpuio_s;
-struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
+struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
omap_clk clk);
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
@@ -691,7 +692,8 @@ struct uWireSlave {
void *opaque;
};
struct omap_uwire_s;
-struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
+struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
qemu_irq *irq, qemu_irq dma, omap_clk clk);
void omap_uwire_attach(struct omap_uwire_s *s,
uWireSlave *slave, int chipselect);
@@ -730,7 +732,8 @@ struct I2SCodec {
} in, out;
};
struct omap_mcbsp_s;
-struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
+struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
qemu_irq *irq, qemu_irq *dma, omap_clk clk);
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave);
@@ -741,8 +744,7 @@ void omap_tap_init(struct omap_target_agent_s *ta,
struct omap_lcd_panel_s;
void omap_lcdc_reset(struct omap_lcd_panel_s *s);
struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq,
- struct omap_dma_lcd_channel_s *dma,
- ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk);
+ struct omap_dma_lcd_channel_s *dma, omap_clk clk);
/* omap_dss.c */
struct rfbi_chip_s {
@@ -826,6 +828,22 @@ struct omap_mpu_state_s {
qemu_irq wakeup;
+ MemoryRegion ulpd_pm_iomem;
+ MemoryRegion pin_cfg_iomem;
+ MemoryRegion id_iomem;
+ MemoryRegion id_iomem_e18;
+ MemoryRegion id_iomem_ed4;
+ MemoryRegion id_iomem_e20;
+ MemoryRegion mpui_iomem;
+ MemoryRegion tcmi_iomem;
+ MemoryRegion clkm_iomem;
+ MemoryRegion clkdsp_iomem;
+ MemoryRegion pwl_iomem;
+ MemoryRegion pwt_iomem;
+ MemoryRegion mpui_io_iomem;
+ MemoryRegion imif_ram;
+ MemoryRegion emiff_ram;
+
struct omap_dma_port_if_s {
uint32_t (*read[3])(struct omap_mpu_state_s *s,
target_phys_addr_t offset);
@@ -907,6 +925,7 @@ struct omap_mpu_state_s {
uint32_t tcmi_regs[17];
struct dpll_ctl_s {
+ MemoryRegion iomem;
uint16_t mode;
omap_clk dpll;
} dpll[3];
@@ -947,7 +966,8 @@ struct omap_mpu_state_s {
};
/* omap1.c */
-struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
+struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
+ unsigned long sdram_size,
const char *core);
/* omap2.c */
diff --git a/hw/omap1.c b/hw/omap1.c
index 614fd31b01..f747321e97 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -84,6 +84,7 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
/* MPU OS timers */
struct omap_mpu_timer_s {
+ MemoryRegion iomem;
qemu_irq irq;
omap_clk clk;
uint32_t val;
@@ -179,10 +180,15 @@ static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
timer->rate = omap_clk_getrate(timer->clk);
}
-static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
+ if (size != 4) {
+ return omap_badwidth_read32(opaque, addr);
+ }
+
switch (addr) {
case 0x00: /* CNTL_TIMER */
return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
@@ -199,10 +205,14 @@ static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
}
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
+ if (size != 4) {
+ return omap_badwidth_write32(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* CNTL_TIMER */
omap_timer_sync(s);
@@ -226,16 +236,10 @@ static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_mpu_timer_readfn[] = {
- omap_badwidth_read32,
- omap_badwidth_read32,
- omap_mpu_timer_read,
-};
-
-static CPUWriteMemoryFunc * const omap_mpu_timer_writefn[] = {
- omap_badwidth_write32,
- omap_badwidth_write32,
- omap_mpu_timer_write,
+static const MemoryRegionOps omap_mpu_timer_ops = {
+ .read = omap_mpu_timer_read,
+ .write = omap_mpu_timer_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
@@ -250,10 +254,10 @@ static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
s->it_ena = 1;
}
-static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
+static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
qemu_irq irq, omap_clk clk)
{
- int iomemtype;
struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
g_malloc0(sizeof(struct omap_mpu_timer_s));
@@ -264,9 +268,10 @@ static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
omap_mpu_timer_reset(s);
omap_timer_clk_setup(s);
- iomemtype = cpu_register_io_memory(omap_mpu_timer_readfn,
- omap_mpu_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x100, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_mpu_timer_ops, s,
+ "omap-mpu-timer", 0x100);
+
+ memory_region_add_subregion(system_memory, base, &s->iomem);
return s;
}
@@ -274,16 +279,22 @@ static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
/* Watchdog timer */
struct omap_watchdog_timer_s {
struct omap_mpu_timer_s timer;
+ MemoryRegion iomem;
uint8_t last_wr;
int mode;
int free;
int reset;
};
-static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (addr) {
case 0x00: /* CNTL_TIMER */
return (s->timer.ptv << 9) | (s->timer.ar << 8) |
@@ -301,10 +312,14 @@ static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
}
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
+ if (size != 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* CNTL_TIMER */
omap_timer_sync(&s->timer);
@@ -344,16 +359,10 @@ static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_wd_timer_readfn[] = {
- omap_badwidth_read16,
- omap_wd_timer_read,
- omap_badwidth_read16,
-};
-
-static CPUWriteMemoryFunc * const omap_wd_timer_writefn[] = {
- omap_badwidth_write16,
- omap_wd_timer_write,
- omap_badwidth_write16,
+static const MemoryRegionOps omap_wd_timer_ops = {
+ .read = omap_wd_timer_read,
+ .write = omap_wd_timer_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
@@ -374,10 +383,10 @@ static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
omap_timer_update(&s->timer);
}
-static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
+static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
+ target_phys_addr_t base,
qemu_irq irq, omap_clk clk)
{
- int iomemtype;
struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
g_malloc0(sizeof(struct omap_watchdog_timer_s));
@@ -387,9 +396,9 @@ static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
omap_wd_timer_reset(s);
omap_timer_clk_setup(&s->timer);
- iomemtype = cpu_register_io_memory(omap_wd_timer_readfn,
- omap_wd_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x100, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_wd_timer_ops, s,
+ "omap-wd-timer", 0x100);
+ memory_region_add_subregion(memory, base, &s->iomem);
return s;
}
@@ -397,13 +406,19 @@ static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
/* 32-kHz timer */
struct omap_32khz_timer_s {
struct omap_mpu_timer_s timer;
+ MemoryRegion iomem;
};
-static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_os_timer_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 4) {
+ return omap_badwidth_read32(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* TVR */
return s->timer.reset_val;
@@ -422,11 +437,15 @@ static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
}
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 4) {
+ return omap_badwidth_write32(opaque, addr, value);
+ }
+
switch (offset) {
case 0x00: /* TVR */
s->timer.reset_val = value & 0x00ffffff;
@@ -452,16 +471,10 @@ static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_os_timer_readfn[] = {
- omap_badwidth_read32,
- omap_badwidth_read32,
- omap_os_timer_read,
-};
-
-static CPUWriteMemoryFunc * const omap_os_timer_writefn[] = {
- omap_badwidth_write32,
- omap_badwidth_write32,
- omap_os_timer_write,
+static const MemoryRegionOps omap_os_timer_ops = {
+ .read = omap_os_timer_read,
+ .write = omap_os_timer_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
@@ -476,10 +489,10 @@ static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
s->timer.ar = 1;
}
-static struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
+static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
+ target_phys_addr_t base,
qemu_irq irq, omap_clk clk)
{
- int iomemtype;
struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
g_malloc0(sizeof(struct omap_32khz_timer_s));
@@ -489,19 +502,24 @@ static struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
omap_os_timer_reset(s);
omap_timer_clk_setup(&s->timer);
- iomemtype = cpu_register_io_memory(omap_os_timer_readfn,
- omap_os_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_os_timer_ops, s,
+ "omap-os-timer", 0x800);
+ memory_region_add_subregion(memory, base, &s->iomem);
return s;
}
/* Ultra Low-Power Device Module */
-static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
uint16_t ret;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (addr) {
case 0x14: /* IT_STATUS */
ret = s->ulpd_pm_regs[addr >> 2];
@@ -560,7 +578,7 @@ static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
}
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
int64_t now, ticks;
@@ -568,6 +586,10 @@ static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
static const int bypass_div[4] = { 1, 2, 4, 4 };
uint16_t diff;
+ if (size != 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* COUNTER_32_LSB */
case 0x04: /* COUNTER_32_MSB */
@@ -674,16 +696,10 @@ static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_ulpd_pm_readfn[] = {
- omap_badwidth_read16,
- omap_ulpd_pm_read,
- omap_badwidth_read16,
-};
-
-static CPUWriteMemoryFunc * const omap_ulpd_pm_writefn[] = {
- omap_badwidth_write16,
- omap_ulpd_pm_write,
- omap_badwidth_write16,
+static const MemoryRegionOps omap_ulpd_pm_ops = {
+ .read = omap_ulpd_pm_read,
+ .write = omap_ulpd_pm_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
@@ -713,21 +729,26 @@ static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
}
-static void omap_ulpd_pm_init(target_phys_addr_t base,
+static void omap_ulpd_pm_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
struct omap_mpu_state_s *mpu)
{
- int iomemtype = cpu_register_io_memory(omap_ulpd_pm_readfn,
- omap_ulpd_pm_writefn, mpu, DEVICE_NATIVE_ENDIAN);
-
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&mpu->ulpd_pm_iomem, &omap_ulpd_pm_ops, mpu,
+ "omap-ulpd-pm", 0x800);
+ memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
omap_ulpd_pm_reset(mpu);
}
/* OMAP Pin Configuration */
-static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+ if (size != 4) {
+ return omap_badwidth_read32(opaque, addr);
+ }
+
switch (addr) {
case 0x00: /* FUNC_MUX_CTRL_0 */
case 0x04: /* FUNC_MUX_CTRL_1 */
@@ -827,11 +848,15 @@ static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
}
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
uint32_t diff;
+ if (size != 4) {
+ return omap_badwidth_write32(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* FUNC_MUX_CTRL_0 */
diff = s->func_mux_ctrl[addr >> 2] ^ value;
@@ -900,16 +925,10 @@ static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_pin_cfg_readfn[] = {
- omap_badwidth_read32,
- omap_badwidth_read32,
- omap_pin_cfg_read,
-};
-
-static CPUWriteMemoryFunc * const omap_pin_cfg_writefn[] = {
- omap_badwidth_write32,
- omap_badwidth_write32,
- omap_pin_cfg_write,
+static const MemoryRegionOps omap_pin_cfg_ops = {
+ .read = omap_pin_cfg_read,
+ .write = omap_pin_cfg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
@@ -928,21 +947,26 @@ static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
}
-static void omap_pin_cfg_init(target_phys_addr_t base,
+static void omap_pin_cfg_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
struct omap_mpu_state_s *mpu)
{
- int iomemtype = cpu_register_io_memory(omap_pin_cfg_readfn,
- omap_pin_cfg_writefn, mpu, DEVICE_NATIVE_ENDIAN);
-
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&mpu->pin_cfg_iomem, &omap_pin_cfg_ops, mpu,
+ "omap-pin-cfg", 0x800);
+ memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
omap_pin_cfg_reset(mpu);
}
/* Device Identification, Die Identification */
-static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_id_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+ if (size != 4) {
+ return omap_badwidth_read32(opaque, addr);
+ }
+
switch (addr) {
case 0xfffe1800: /* DIE_ID_LSB */
return 0xc9581f0e;
@@ -982,38 +1006,48 @@ static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
}
static void omap_id_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
+ if (size != 4) {
+ return omap_badwidth_write32(opaque, addr, value);
+ }
+
OMAP_BAD_REG(addr);
}
-static CPUReadMemoryFunc * const omap_id_readfn[] = {
- omap_badwidth_read32,
- omap_badwidth_read32,
- omap_id_read,
+static const MemoryRegionOps omap_id_ops = {
+ .read = omap_id_read,
+ .write = omap_id_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static CPUWriteMemoryFunc * const omap_id_writefn[] = {
- omap_badwidth_write32,
- omap_badwidth_write32,
- omap_id_write,
-};
-
-static void omap_id_init(struct omap_mpu_state_s *mpu)
+static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
{
- int iomemtype = cpu_register_io_memory(omap_id_readfn,
- omap_id_writefn, mpu, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory_offset(0xfffe1800, 0x800, iomemtype, 0xfffe1800);
- cpu_register_physical_memory_offset(0xfffed400, 0x100, iomemtype, 0xfffed400);
- if (!cpu_is_omap15xx(mpu))
- cpu_register_physical_memory_offset(0xfffe2000, 0x800, iomemtype, 0xfffe2000);
+ memory_region_init_io(&mpu->id_iomem, &omap_id_ops, mpu,
+ "omap-id", 0x100000000ULL);
+ memory_region_init_alias(&mpu->id_iomem_e18, "omap-id-e18", &mpu->id_iomem,
+ 0xfffe1800, 0x800);
+ memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
+ memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-ed4", &mpu->id_iomem,
+ 0xfffed400, 0x100);
+ memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
+ if (!cpu_is_omap15xx(mpu)) {
+ memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-e20",
+ &mpu->id_iomem, 0xfffe2000, 0x800);
+ memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
+ }
}
/* MPUI Control (Dummy) */
-static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_mpui_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+ if (size != 4) {
+ return omap_badwidth_read32(opaque, addr);
+ }
+
switch (addr) {
case 0x00: /* CTRL */
return s->mpui_ctrl;
@@ -1039,10 +1073,14 @@ static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
}
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+ if (size != 4) {
+ return omap_badwidth_write32(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* CTRL */
s->mpui_ctrl = value & 0x007fffff;
@@ -1064,16 +1102,10 @@ static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_mpui_readfn[] = {
- omap_badwidth_read32,
- omap_badwidth_read32,
- omap_mpui_read,
-};
-
-static CPUWriteMemoryFunc * const omap_mpui_writefn[] = {
- omap_badwidth_write32,
- omap_badwidth_write32,
- omap_mpui_write,
+static const MemoryRegionOps omap_mpui_ops = {
+ .read = omap_mpui_read,
+ .write = omap_mpui_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_mpui_reset(struct omap_mpu_state_s *s)
@@ -1081,13 +1113,12 @@ static void omap_mpui_reset(struct omap_mpu_state_s *s)
s->mpui_ctrl = 0x0003ff1b;
}
-static void omap_mpui_init(target_phys_addr_t base,
+static void omap_mpui_init(MemoryRegion *memory, target_phys_addr_t base,
struct omap_mpu_state_s *mpu)
{
- int iomemtype = cpu_register_io_memory(omap_mpui_readfn,
- omap_mpui_writefn, mpu, DEVICE_NATIVE_ENDIAN);
-
- cpu_register_physical_memory(base, 0x100, iomemtype);
+ memory_region_init_io(&mpu->mpui_iomem, &omap_mpui_ops, mpu,
+ "omap-mpui", 0x100);
+ memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
omap_mpui_reset(mpu);
}
@@ -1095,6 +1126,7 @@ static void omap_mpui_init(target_phys_addr_t base,
/* TIPB Bridges */
struct omap_tipb_bridge_s {
qemu_irq abort;
+ MemoryRegion iomem;
int width_intr;
uint16_t control;
@@ -1103,10 +1135,15 @@ struct omap_tipb_bridge_s {
uint16_t enh_control;
};
-static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
+ if (size < 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (addr) {
case 0x00: /* TIPB_CNTL */
return s->control;
@@ -1129,10 +1166,14 @@ static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
}
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
+ if (size < 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* TIPB_CNTL */
s->control = value & 0xffff;
@@ -1163,16 +1204,10 @@ static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_tipb_bridge_readfn[] = {
- omap_badwidth_read16,
- omap_tipb_bridge_read,
- omap_tipb_bridge_read,
-};
-
-static CPUWriteMemoryFunc * const omap_tipb_bridge_writefn[] = {
- omap_badwidth_write16,
- omap_tipb_bridge_write,
- omap_tipb_bridge_write,
+static const MemoryRegionOps omap_tipb_bridge_ops = {
+ .read = omap_tipb_bridge_read,
+ .write = omap_tipb_bridge_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
@@ -1183,29 +1218,34 @@ static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
s->enh_control = 0x000f;
}
-static struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
- qemu_irq abort_irq, omap_clk clk)
+static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
+ MemoryRegion *memory, target_phys_addr_t base,
+ qemu_irq abort_irq, omap_clk clk)
{
- int iomemtype;
struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
g_malloc0(sizeof(struct omap_tipb_bridge_s));
s->abort = abort_irq;
omap_tipb_bridge_reset(s);
- iomemtype = cpu_register_io_memory(omap_tipb_bridge_readfn,
- omap_tipb_bridge_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x100, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_tipb_bridge_ops, s,
+ "omap-tipb-bridge", 0x100);
+ memory_region_add_subregion(memory, base, &s->iomem);
return s;
}
/* Dummy Traffic Controller's Memory Interface */
-static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_tcmi_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
uint32_t ret;
+ if (size != 4) {
+ return omap_badwidth_read32(opaque, addr);
+ }
+
switch (addr) {
case 0x00: /* IMIF_PRIO */
case 0x04: /* EMIFS_PRIO */
@@ -1235,10 +1275,14 @@ static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
}
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+ if (size != 4) {
+ return omap_badwidth_write32(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* IMIF_PRIO */
case 0x04: /* EMIFS_PRIO */
@@ -1265,16 +1309,10 @@ static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_tcmi_readfn[] = {
- omap_badwidth_read32,
- omap_badwidth_read32,
- omap_tcmi_read,
-};
-
-static CPUWriteMemoryFunc * const omap_tcmi_writefn[] = {
- omap_badwidth_write32,
- omap_badwidth_write32,
- omap_tcmi_write,
+static const MemoryRegionOps omap_tcmi_ops = {
+ .read = omap_tcmi_read,
+ .write = omap_tcmi_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
@@ -1296,21 +1334,25 @@ static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
}
-static void omap_tcmi_init(target_phys_addr_t base,
+static void omap_tcmi_init(MemoryRegion *memory, target_phys_addr_t base,
struct omap_mpu_state_s *mpu)
{
- int iomemtype = cpu_register_io_memory(omap_tcmi_readfn,
- omap_tcmi_writefn, mpu, DEVICE_NATIVE_ENDIAN);
-
- cpu_register_physical_memory(base, 0x100, iomemtype);
+ memory_region_init_io(&mpu->tcmi_iomem, &omap_tcmi_ops, mpu,
+ "omap-tcmi", 0x100);
+ memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
omap_tcmi_reset(mpu);
}
/* Digital phase-locked loops control */
-static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_dpll_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
if (addr == 0x00) /* CTL_REG */
return s->mode;
@@ -1319,13 +1361,17 @@ static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
}
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
uint16_t diff;
static const int bypass_div[4] = { 1, 2, 4, 4 };
int div, mult;
+ if (size != 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
if (addr == 0x00) { /* CTL_REG */
/* See omap_ulpd_pm_write() too */
diff = s->mode & value;
@@ -1351,16 +1397,10 @@ static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_dpll_readfn[] = {
- omap_badwidth_read16,
- omap_dpll_read,
- omap_badwidth_read16,
-};
-
-static CPUWriteMemoryFunc * const omap_dpll_writefn[] = {
- omap_badwidth_write16,
- omap_dpll_write,
- omap_badwidth_write16,
+static const MemoryRegionOps omap_dpll_ops = {
+ .read = omap_dpll_read,
+ .write = omap_dpll_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_dpll_reset(struct dpll_ctl_s *s)
@@ -1369,23 +1409,27 @@ static void omap_dpll_reset(struct dpll_ctl_s *s)
omap_clk_setrate(s->dpll, 1, 1);
}
-static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
- omap_clk clk)
+static void omap_dpll_init(MemoryRegion *memory, struct dpll_ctl_s *s,
+ target_phys_addr_t base, omap_clk clk)
{
- int iomemtype = cpu_register_io_memory(omap_dpll_readfn,
- omap_dpll_writefn, s, DEVICE_NATIVE_ENDIAN);
+ memory_region_init_io(&s->iomem, &omap_dpll_ops, s, "omap-dpll", 0x100);
s->dpll = clk;
omap_dpll_reset(s);
- cpu_register_physical_memory(base, 0x100, iomemtype);
+ memory_region_add_subregion(memory, base, &s->iomem);
}
/* MPU Clock/Reset/Power Mode Control */
-static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_clkm_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (addr) {
case 0x00: /* ARM_CKCTL */
return s->clkm.arm_ckctl;
@@ -1579,7 +1623,7 @@ static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
}
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
uint16_t diff;
@@ -1589,6 +1633,10 @@ static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
"mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
};
+ if (size != 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
switch (addr) {
case 0x00: /* ARM_CKCTL */
diff = s->clkm.arm_ckctl ^ value;
@@ -1655,22 +1703,21 @@ static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_clkm_readfn[] = {
- omap_badwidth_read16,
- omap_clkm_read,
- omap_badwidth_read16,
+static const MemoryRegionOps omap_clkm_ops = {
+ .read = omap_clkm_read,
+ .write = omap_clkm_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static CPUWriteMemoryFunc * const omap_clkm_writefn[] = {
- omap_badwidth_write16,
- omap_clkm_write,
- omap_badwidth_write16,
-};
-
-static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (addr) {
case 0x04: /* DSP_IDLECT1 */
return s->clkm.dsp_idlect1;
@@ -1707,11 +1754,15 @@ static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
}
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
uint16_t diff;
+ if (size != 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
switch (addr) {
case 0x04: /* DSP_IDLECT1 */
diff = s->clkm.dsp_idlect1 ^ value;
@@ -1738,16 +1789,10 @@ static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_clkdsp_readfn[] = {
- omap_badwidth_read16,
- omap_clkdsp_read,
- omap_badwidth_read16,
-};
-
-static CPUWriteMemoryFunc * const omap_clkdsp_writefn[] = {
- omap_badwidth_write16,
- omap_clkdsp_write,
- omap_badwidth_write16,
+static const MemoryRegionOps omap_clkdsp_ops = {
+ .read = omap_clkdsp_read,
+ .write = omap_clkdsp_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_clkm_reset(struct omap_mpu_state_s *s)
@@ -1773,15 +1818,13 @@ static void omap_clkm_reset(struct omap_mpu_state_s *s)
s->clkm.dsp_rstct2 = 0x0000;
}
-static void omap_clkm_init(target_phys_addr_t mpu_base,
+static void omap_clkm_init(MemoryRegion *memory, target_phys_addr_t mpu_base,
target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
{
- int iomemtype[2] = {
- cpu_register_io_memory(omap_clkm_readfn, omap_clkm_writefn, s,
- DEVICE_NATIVE_ENDIAN),
- cpu_register_io_memory(omap_clkdsp_readfn, omap_clkdsp_writefn, s,
- DEVICE_NATIVE_ENDIAN),
- };
+ memory_region_init_io(&s->clkm_iomem, &omap_clkm_ops, s,
+ "omap-clkm", 0x100);
+ memory_region_init_io(&s->clkdsp_iomem, &omap_clkdsp_ops, s,
+ "omap-clkdsp", 0x1000);
s->clkm.arm_idlect1 = 0x03ff;
s->clkm.arm_idlect2 = 0x0100;
@@ -1789,8 +1832,8 @@ static void omap_clkm_init(target_phys_addr_t mpu_base,
omap_clkm_reset(s);
s->clkm.cold_start = 0x3a;
- cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]);
- cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]);
+ memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
+ memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
}
/* MPU I/O */
@@ -1800,6 +1843,7 @@ struct omap_mpuio_s {
qemu_irq *in;
qemu_irq handler[16];
qemu_irq wakeup;
+ MemoryRegion iomem;
uint16_t inputs;
uint16_t outputs;
@@ -1854,12 +1898,17 @@ static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
s->row_latch = ~rows;
}
-static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_mpuio_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
uint16_t ret;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* INPUT_LATCH */
return s->inputs;
@@ -1910,13 +1959,17 @@ static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
}
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
uint16_t diff;
int ln;
+ if (size != 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
switch (offset) {
case 0x04: /* OUTPUT_REG */
diff = (s->outputs ^ value) & ~s->dir;
@@ -1982,16 +2035,10 @@ static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_mpuio_readfn[] = {
- omap_badwidth_read16,
- omap_mpuio_read,
- omap_badwidth_read16,
-};
-
-static CPUWriteMemoryFunc * const omap_mpuio_writefn[] = {
- omap_badwidth_write16,
- omap_mpuio_write,
- omap_badwidth_write16,
+static const MemoryRegionOps omap_mpuio_ops = {
+ .read = omap_mpuio_read,
+ .write = omap_mpuio_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_mpuio_reset(struct omap_mpuio_s *s)
@@ -2019,11 +2066,11 @@ static void omap_mpuio_onoff(void *opaque, int line, int on)
omap_mpuio_kbd_update(s);
}
-struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
+struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
+ target_phys_addr_t base,
qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
omap_clk clk)
{
- int iomemtype;
struct omap_mpuio_s *s = (struct omap_mpuio_s *)
g_malloc0(sizeof(struct omap_mpuio_s));
@@ -2033,9 +2080,9 @@ struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
omap_mpuio_reset(s);
- iomemtype = cpu_register_io_memory(omap_mpuio_readfn,
- omap_mpuio_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_mpuio_ops, s,
+ "omap-mpuio", 0x800);
+ memory_region_add_subregion(memory, base, &s->iomem);
omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
@@ -2069,6 +2116,7 @@ void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
/* MicroWire Interface */
struct omap_uwire_s {
+ MemoryRegion iomem;
qemu_irq txirq;
qemu_irq rxirq;
qemu_irq txdrq;
@@ -2106,11 +2154,16 @@ static void omap_uwire_transfer_start(struct omap_uwire_s *s)
}
}
-static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_uwire_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* RDR */
s->control &= ~(1 << 15); /* RDRB */
@@ -2136,11 +2189,15 @@ static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
}
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 2) {
+ return omap_badwidth_write16(opaque, addr, value);
+ }
+
switch (offset) {
case 0x00: /* TDR */
s->txbuf = value; /* TD */
@@ -2184,16 +2241,10 @@ static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_uwire_readfn[] = {
- omap_badwidth_read16,
- omap_uwire_read,
- omap_badwidth_read16,
-};
-
-static CPUWriteMemoryFunc * const omap_uwire_writefn[] = {
- omap_badwidth_write16,
- omap_uwire_write,
- omap_badwidth_write16,
+static const MemoryRegionOps omap_uwire_ops = {
+ .read = omap_uwire_read,
+ .write = omap_uwire_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_uwire_reset(struct omap_uwire_s *s)
@@ -2206,10 +2257,10 @@ static void omap_uwire_reset(struct omap_uwire_s *s)
s->setup[4] = 0;
}
-struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
+struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
qemu_irq *irq, qemu_irq dma, omap_clk clk)
{
- int iomemtype;
struct omap_uwire_s *s = (struct omap_uwire_s *)
g_malloc0(sizeof(struct omap_uwire_s));
@@ -2218,9 +2269,8 @@ struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
s->txdrq = dma;
omap_uwire_reset(s);
- iomemtype = cpu_register_io_memory(omap_uwire_readfn,
- omap_uwire_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_uwire_ops, s, "omap-uwire", 0x800);
+ memory_region_add_subregion(system_memory, base, &s->iomem);
return s;
}
@@ -2247,11 +2297,16 @@ static void omap_pwl_update(struct omap_mpu_state_s *s)
}
}
-static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_pwl_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 1) {
+ return omap_badwidth_read8(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* PWL_LEVEL */
return s->pwl.level;
@@ -2263,11 +2318,15 @@ static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
}
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 1) {
+ return omap_badwidth_write8(opaque, addr, value);
+ }
+
switch (offset) {
case 0x00: /* PWL_LEVEL */
s->pwl.level = value;
@@ -2283,16 +2342,10 @@ static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_pwl_readfn[] = {
- omap_pwl_read,
- omap_badwidth_read8,
- omap_badwidth_read8,
-};
-
-static CPUWriteMemoryFunc * const omap_pwl_writefn[] = {
- omap_pwl_write,
- omap_badwidth_write8,
- omap_badwidth_write8,
+static const MemoryRegionOps omap_pwl_ops = {
+ .read = omap_pwl_read,
+ .write = omap_pwl_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_pwl_reset(struct omap_mpu_state_s *s)
@@ -2312,26 +2365,30 @@ static void omap_pwl_clk_update(void *opaque, int line, int on)
omap_pwl_update(s);
}
-static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
+static void omap_pwl_init(MemoryRegion *system_memory,
+ target_phys_addr_t base, struct omap_mpu_state_s *s,
omap_clk clk)
{
- int iomemtype;
-
omap_pwl_reset(s);
- iomemtype = cpu_register_io_memory(omap_pwl_readfn,
- omap_pwl_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->pwl_iomem, &omap_pwl_ops, s,
+ "omap-pwl", 0x800);
+ memory_region_add_subregion(system_memory, base, &s->pwl_iomem);
omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
}
/* Pulse-Width Tone module */
-static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_pwt_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 1) {
+ return omap_badwidth_read8(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* FRC */
return s->pwt.frc;
@@ -2345,11 +2402,15 @@ static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
}
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 1) {
+ return omap_badwidth_write8(opaque, addr, value);
+ }
+
switch (offset) {
case 0x00: /* FRC */
s->pwt.frc = value & 0x3f;
@@ -2387,16 +2448,10 @@ static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_pwt_readfn[] = {
- omap_pwt_read,
- omap_badwidth_read8,
- omap_badwidth_read8,
-};
-
-static CPUWriteMemoryFunc * const omap_pwt_writefn[] = {
- omap_pwt_write,
- omap_badwidth_write8,
- omap_badwidth_write8,
+static const MemoryRegionOps omap_pwt_ops = {
+ .read =omap_pwt_read,
+ .write = omap_pwt_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_pwt_reset(struct omap_mpu_state_s *s)
@@ -2406,21 +2461,21 @@ static void omap_pwt_reset(struct omap_mpu_state_s *s)
s->pwt.gcr = 0;
}
-static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
+static void omap_pwt_init(MemoryRegion *system_memory,
+ target_phys_addr_t base, struct omap_mpu_state_s *s,
omap_clk clk)
{
- int iomemtype;
-
s->pwt.clk = clk;
omap_pwt_reset(s);
- iomemtype = cpu_register_io_memory(omap_pwt_readfn,
- omap_pwt_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->pwt_iomem, &omap_pwt_ops, s,
+ "omap-pwt", 0x800);
+ memory_region_add_subregion(system_memory, base, &s->pwt_iomem);
}
/* Real-time Clock module */
struct omap_rtc_s {
+ MemoryRegion iomem;
qemu_irq irq;
qemu_irq alarm;
QEMUTimer *clk;
@@ -2453,12 +2508,17 @@ static void omap_rtc_alarm_update(struct omap_rtc_s *s)
printf("%s: conversion failed\n", __FUNCTION__);
}
-static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_rtc_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
uint8_t i;
+ if (size != 1) {
+ return omap_badwidth_read8(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* SECONDS_REG */
return to_bcd(s->current_tm.tm_sec);
@@ -2531,13 +2591,17 @@ static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
}
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
struct tm new_tm;
time_t ti[2];
+ if (size != 1) {
+ return omap_badwidth_write8(opaque, addr, value);
+ }
+
switch (offset) {
case 0x00: /* SECONDS_REG */
#ifdef ALMDEBUG
@@ -2718,16 +2782,10 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_rtc_readfn[] = {
- omap_rtc_read,
- omap_badwidth_read8,
- omap_badwidth_read8,
-};
-
-static CPUWriteMemoryFunc * const omap_rtc_writefn[] = {
- omap_rtc_write,
- omap_badwidth_write8,
- omap_badwidth_write8,
+static const MemoryRegionOps omap_rtc_ops = {
+ .read = omap_rtc_read,
+ .write = omap_rtc_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_rtc_tick(void *opaque)
@@ -2814,10 +2872,10 @@ static void omap_rtc_reset(struct omap_rtc_s *s)
omap_rtc_tick(s);
}
-static struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
+static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
qemu_irq *irq, omap_clk clk)
{
- int iomemtype;
struct omap_rtc_s *s = (struct omap_rtc_s *)
g_malloc0(sizeof(struct omap_rtc_s));
@@ -2827,15 +2885,16 @@ static struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
omap_rtc_reset(s);
- iomemtype = cpu_register_io_memory(omap_rtc_readfn,
- omap_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_rtc_ops, s,
+ "omap-rtc", 0x800);
+ memory_region_add_subregion(system_memory, base, &s->iomem);
return s;
}
/* Multi-channel Buffered Serial Port interfaces */
struct omap_mcbsp_s {
+ MemoryRegion iomem;
qemu_irq txirq;
qemu_irq rxirq;
qemu_irq txdrq;
@@ -3041,12 +3100,17 @@ static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
omap_mcbsp_rx_stop(s);
}
-static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
uint16_t ret;
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* DRR2 */
if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */
@@ -3303,16 +3367,20 @@ static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
omap_badwidth_write16(opaque, addr, value);
}
-static CPUReadMemoryFunc * const omap_mcbsp_readfn[] = {
- omap_badwidth_read16,
- omap_mcbsp_read,
- omap_badwidth_read16,
-};
+static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ switch (size) {
+ case 2: return omap_mcbsp_writeh(opaque, addr, value);
+ case 4: return omap_mcbsp_writew(opaque, addr, value);
+ default: return omap_badwidth_write16(opaque, addr, value);
+ }
+}
-static CPUWriteMemoryFunc * const omap_mcbsp_writefn[] = {
- omap_badwidth_write16,
- omap_mcbsp_writeh,
- omap_mcbsp_writew,
+static const MemoryRegionOps omap_mcbsp_ops = {
+ .read = omap_mcbsp_read,
+ .write = omap_mcbsp_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
@@ -3334,10 +3402,10 @@ static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
qemu_del_timer(s->sink_timer);
}
-struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
+struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
+ target_phys_addr_t base,
qemu_irq *irq, qemu_irq *dma, omap_clk clk)
{
- int iomemtype;
struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
g_malloc0(sizeof(struct omap_mcbsp_s));
@@ -3349,9 +3417,8 @@ struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
s->source_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_source_tick, s);
omap_mcbsp_reset(s);
- iomemtype = cpu_register_io_memory(omap_mcbsp_readfn,
- omap_mcbsp_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
+ memory_region_add_subregion(system_memory, base, &s->iomem);
return s;
}
@@ -3385,6 +3452,7 @@ void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
/* LED Pulse Generators */
struct omap_lpg_s {
+ MemoryRegion iomem;
QEMUTimer *tm;
uint8_t control;
@@ -3449,11 +3517,16 @@ static void omap_lpg_reset(struct omap_lpg_s *s)
omap_lpg_update(s);
}
-static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_lpg_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 1) {
+ return omap_badwidth_read8(opaque, addr);
+ }
+
switch (offset) {
case 0x00: /* LCR */
return s->control;
@@ -3467,11 +3540,15 @@ static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
}
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
- uint32_t value)
+ uint64_t value, unsigned size)
{
struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
+ if (size != 1) {
+ return omap_badwidth_write8(opaque, addr, value);
+ }
+
switch (offset) {
case 0x00: /* LCR */
if (~value & (1 << 6)) /* LPGRES */
@@ -3491,16 +3568,10 @@ static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
}
}
-static CPUReadMemoryFunc * const omap_lpg_readfn[] = {
- omap_lpg_read,
- omap_badwidth_read8,
- omap_badwidth_read8,
-};
-
-static CPUWriteMemoryFunc * const omap_lpg_writefn[] = {
- omap_lpg_write,
- omap_badwidth_write8,
- omap_badwidth_write8,
+static const MemoryRegionOps omap_lpg_ops = {
+ .read = omap_lpg_read,
+ .write = omap_lpg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void omap_lpg_clk_update(void *opaque, int line, int on)
@@ -3511,9 +3582,9 @@ static void omap_lpg_clk_update(void *opaque, int line, int on)
omap_lpg_update(s);
}
-static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
+static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
+ target_phys_addr_t base, omap_clk clk)
{
- int iomemtype;
struct omap_lpg_s *s = (struct omap_lpg_s *)
g_malloc0(sizeof(struct omap_lpg_s));
@@ -3521,9 +3592,8 @@ static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
omap_lpg_reset(s);
- iomemtype = cpu_register_io_memory(omap_lpg_readfn,
- omap_lpg_writefn, s, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x800, iomemtype);
+ memory_region_init_io(&s->iomem, &omap_lpg_ops, s, "omap-lpg", 0x800);
+ memory_region_add_subregion(system_memory, base, &s->iomem);
omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
@@ -3531,8 +3601,13 @@ static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
}
/* MPUI Peripheral Bridge configuration */
-static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
+ if (size != 2) {
+ return omap_badwidth_read16(opaque, addr);
+ }
+
if (addr == OMAP_MPUI_BASE) /* CMR */
return 0xfe4d;
@@ -3540,23 +3615,26 @@ static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
return 0;
}
-static CPUReadMemoryFunc * const omap_mpui_io_readfn[] = {
- omap_badwidth_read16,
- omap_mpui_io_read,
- omap_badwidth_read16,
-};
+static void omap_mpui_io_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ /* FIXME: infinite loop */
+ omap_badwidth_write16(opaque, addr, value);
+}
-static CPUWriteMemoryFunc * const omap_mpui_io_writefn[] = {
- omap_badwidth_write16,
- omap_badwidth_write16,
- omap_badwidth_write16,
+static const MemoryRegionOps omap_mpui_io_ops = {
+ .read = omap_mpui_io_read,
+ .write = omap_mpui_io_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
+static void omap_setup_mpui_io(MemoryRegion *system_memory,
+ struct omap_mpu_state_s *mpu)
{
- int iomemtype = cpu_register_io_memory(omap_mpui_io_readfn,
- omap_mpui_io_writefn, mpu, DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
+ memory_region_init_io(&mpu->mpui_io_iomem, &omap_mpui_io_ops, mpu,
+ "omap-mpui-io", 0x7fff);
+ memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
+ &mpu->mpui_io_iomem);
}
/* General chip reset */
@@ -3630,14 +3708,16 @@ static const struct omap_map_s {
{ 0 }
};
-static void omap_setup_dsp_mapping(const struct omap_map_s *map)
+static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
+ const struct omap_map_s *map)
{
- int io;
+ MemoryRegion *io;
for (; map->phys_dsp; map ++) {
- io = cpu_get_physical_page_desc(map->phys_mpu);
-
- cpu_register_physical_memory(map->phys_dsp, map->size, io);
+ io = g_new(MemoryRegion, 1);
+ memory_region_init_alias(io, map->name,
+ system_memory, map->phys_mpu, map->size);
+ memory_region_add_subregion(system_memory, map->phys_dsp, io);
}
}
@@ -3706,13 +3786,13 @@ static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
}
-struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
+struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
+ unsigned long sdram_size,
const char *core)
{
int i;
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
g_malloc0(sizeof(struct omap_mpu_state_s));
- ram_addr_t imif_base, emiff_base;
qemu_irq *cpu_irq;
qemu_irq dma_irqs[6];
DriveInfo *dinfo;
@@ -3736,14 +3816,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
omap_clk_init(s);
/* Memory-mapped stuff */
- cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
- (emiff_base = qemu_ram_alloc(NULL, "omap1.dram",
- s->sdram_size)) | IO_MEM_RAM);
- cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
- (imif_base = qemu_ram_alloc(NULL, "omap1.sram",
- s->sram_size)) | IO_MEM_RAM);
+ memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size);
+ memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
+ memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size);
+ memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
- omap_clkm_init(0xfffece00, 0xe1008000, s);
+ omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
cpu_irq = arm_pic_init_cpu(s->env);
s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
@@ -3767,47 +3845,46 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
/* Register SDRAM and SRAM DMA ports for fast transfers. */
- soc_dma_port_add_mem_ram(s->dma,
- emiff_base, OMAP_EMIFF_BASE, s->sdram_size);
- soc_dma_port_add_mem_ram(s->dma,
- imif_base, OMAP_IMIF_BASE, s->sram_size);
+ soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
+ OMAP_EMIFF_BASE, s->sdram_size);
+ soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
+ OMAP_IMIF_BASE, s->sram_size);
- s->timer[0] = omap_mpu_timer_init(0xfffec500,
+ s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
s->irq[0][OMAP_INT_TIMER1],
omap_findclk(s, "mputim_ck"));
- s->timer[1] = omap_mpu_timer_init(0xfffec600,
+ s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
s->irq[0][OMAP_INT_TIMER2],
omap_findclk(s, "mputim_ck"));
- s->timer[2] = omap_mpu_timer_init(0xfffec700,
+ s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
s->irq[0][OMAP_INT_TIMER3],
omap_findclk(s, "mputim_ck"));
- s->wdt = omap_wd_timer_init(0xfffec800,
+ s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
s->irq[0][OMAP_INT_WD_TIMER],
omap_findclk(s, "armwdt_ck"));
- s->os_timer = omap_os_timer_init(0xfffb9000,
+ s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
s->irq[1][OMAP_INT_OS_TIMER],
omap_findclk(s, "clk32-kHz"));
s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
- omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
- omap_findclk(s, "lcd_ck"));
+ omap_dma_get_lcdch(s->dma), omap_findclk(s, "lcd_ck"));
- omap_ulpd_pm_init(0xfffe0800, s);
- omap_pin_cfg_init(0xfffe1000, s);
- omap_id_init(s);
+ omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
+ omap_pin_cfg_init(system_memory, 0xfffe1000, s);
+ omap_id_init(system_memory, s);
- omap_mpui_init(0xfffec900, s);
+ omap_mpui_init(system_memory, 0xfffec900, s);
- s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
+ s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
s->irq[0][OMAP_INT_BRIDGE_PRIV],
omap_findclk(s, "tipb_ck"));
- s->public_tipb = omap_tipb_bridge_init(0xfffed300,
+ s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
s->irq[0][OMAP_INT_BRIDGE_PUB],
omap_findclk(s, "tipb_ck"));
- omap_tcmi_init(0xfffecc00, s);
+ omap_tcmi_init(system_memory, 0xfffecc00, s);
s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
omap_findclk(s, "uart1_ck"),
@@ -3828,9 +3905,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
"uart3",
serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
- omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
- omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
- omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
+ omap_dpll_init(system_memory,
+ &s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
+ omap_dpll_init(system_memory,
+ &s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
+ omap_dpll_init(system_memory,
+ &s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
dinfo = drive_get(IF_SD, 0, 0);
if (!dinfo) {
@@ -3841,7 +3921,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
omap_findclk(s, "mmc_ck"));
- s->mpuio = omap_mpuio_init(0xfffb5000,
+ s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
s->wakeup, omap_findclk(s, "clk32-kHz"));
@@ -3852,27 +3932,34 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
s->irq[0][OMAP_INT_GPIO_BANK1]);
sysbus_mmio_map(sysbus_from_qdev(s->gpio), 0, 0xfffce000);
- s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
+ s->microwire = omap_uwire_init(system_memory,
+ 0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
- omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
- omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
+ omap_pwl_init(system_memory, 0xfffb5800, s, omap_findclk(s, "armxor_ck"));
+ omap_pwt_init(system_memory, 0xfffb6000, s, omap_findclk(s, "armxor_ck"));
s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
&s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
- s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
+ s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
+ &s->irq[1][OMAP_INT_RTC_TIMER],
omap_findclk(s, "clk32-kHz"));
- s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
+ s->mcbsp1 = omap_mcbsp_init(system_memory,
+ 0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
&s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
- s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
+ s->mcbsp2 = omap_mcbsp_init(system_memory,
+ 0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
&s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
- s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
+ s->mcbsp3 = omap_mcbsp_init(system_memory,
+ 0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
&s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
- s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
- s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
+ s->led[0] = omap_lpg_init(system_memory,
+ 0xfffbd000, omap_findclk(s, "clk32-kHz"));
+ s->led[1] = omap_lpg_init(system_memory,
+ 0xfffbd800, omap_findclk(s, "clk32-kHz"));
/* Register mappings not currenlty implemented:
* MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
@@ -3889,8 +3976,8 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
* DSP MMU fffed200 - fffed2ff
*/
- omap_setup_dsp_mapping(omap15xx_dsp_mm);
- omap_setup_mpui_io(s);
+ omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
+ omap_setup_mpui_io(system_memory, s);
qemu_register_reset(omap1_mpu_reset, s);
diff --git a/hw/omap2.c b/hw/omap2.c
index ca088d9f53..3d529cefd6 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -2284,8 +2284,10 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
s->port->addr_valid = omap2_validate_addr;
/* Register SDRAM and SRAM ports for fast DMA transfers. */
- soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
- soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
+ soc_dma_port_add_mem(s->dma, qemu_get_ram_ptr(q2_base),
+ OMAP2_Q2_BASE, s->sdram_size);
+ soc_dma_port_add_mem(s->dma, qemu_get_ram_ptr(sram_base),
+ OMAP2_SRAM_BASE, s->sram_size);
s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
s->irq[0][OMAP_INT_24XX_UART1_IRQ],
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index a9054227e2..29e604863d 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -24,8 +24,6 @@
struct omap_lcd_panel_s {
qemu_irq irq;
DisplayState *state;
- ram_addr_t imif_base;
- ram_addr_t emiff_base;
int plm;
int tft;
@@ -436,8 +434,7 @@ void omap_lcdc_reset(struct omap_lcd_panel_s *s)
}
struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq,
- struct omap_dma_lcd_channel_s *dma,
- ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk)
+ struct omap_dma_lcd_channel_s *dma, omap_clk clk)
{
int iomemtype;
struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *)
@@ -445,8 +442,6 @@ struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq,
s->irq = irq;
s->dma = dma;
- s->imif_base = imif_base;
- s->emiff_base = emiff_base;
omap_lcdc_reset(s);
iomemtype = cpu_register_io_memory(omap_lcdc_readfn,
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 15cfbb52f3..fe535459df 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -32,6 +32,7 @@
#include "arm-misc.h"
#include "flash.h"
#include "blockdev.h"
+#include "exec-memory.h"
/*****************************************************************************/
/* Siemens SX1 Cellphone V1 */
@@ -121,6 +122,7 @@ static void sx1_init(ram_addr_t ram_size,
const int version)
{
struct omap_mpu_state_s *cpu;
+ MemoryRegion *address_space = get_system_memory();
int io;
static uint32_t cs0val = 0x00213090;
static uint32_t cs1val = 0x00215070;
@@ -135,7 +137,7 @@ static void sx1_init(ram_addr_t ram_size,
flash_size = flash2_size;
}
- cpu = omap310_mpu_init(sx1_binfo.ram_size, cpu_model);
+ cpu = omap310_mpu_init(address_space, sx1_binfo.ram_size, cpu_model);
/* External Flash (EMIFS) */
cpu_register_physical_memory(OMAP_CS0_BASE, flash_size,
diff --git a/hw/palm.c b/hw/palm.c
index 4c67e75c83..d8f50e3413 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -25,6 +25,7 @@
#include "arm-misc.h"
#include "devices.h"
#include "loader.h"
+#include "exec-memory.h"
static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
{
@@ -198,6 +199,7 @@ static void palmte_init(ram_addr_t ram_size,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
{
+ MemoryRegion *address_space_mem = get_system_memory();
struct omap_mpu_state_s *cpu;
int flash_size = 0x00800000;
int sdram_size = palmte_binfo.ram_size;
@@ -209,7 +211,7 @@ static void palmte_init(ram_addr_t ram_size,
int rom_size, rom_loaded = 0;
DisplayState *ds = get_displaystate();
- cpu = omap310_mpu_init(sdram_size, cpu_model);
+ cpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model);
/* External Flash (EMIFS) */
cpu_register_physical_memory(OMAP_CS0_BASE, flash_size,
diff --git a/hw/pci.c b/hw/pci.c
index af7400374b..5c4f071d28 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -878,7 +878,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
r = &pci_dev->io_regions[region_num];
r->addr = PCI_BAR_UNMAPPED;
r->size = size;
- r->filtered_size = size;
r->type = type;
r->memory = NULL;
@@ -909,41 +908,6 @@ pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
return pci_dev->io_regions[region_num].addr;
}
-static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
- uint8_t type)
-{
- pcibus_t base = *addr;
- pcibus_t limit = *addr + *size - 1;
- PCIDevice *br;
-
- for (br = d->bus->parent_dev; br; br = br->bus->parent_dev) {
- uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);
-
- if (type & PCI_BASE_ADDRESS_SPACE_IO) {
- if (!(cmd & PCI_COMMAND_IO)) {
- goto no_map;
- }
- } else {
- if (!(cmd & PCI_COMMAND_MEMORY)) {
- goto no_map;
- }
- }
-
- base = MAX(base, pci_bridge_get_base(br, type));
- limit = MIN(limit, pci_bridge_get_limit(br, type));
- }
-
- if (base > limit) {
- goto no_map;
- }
- *addr = base;
- *size = limit - base + 1;
- return;
-no_map:
- *addr = PCI_BAR_UNMAPPED;
- *size = 0;
-}
-
static pcibus_t pci_bar_address(PCIDevice *d,
int reg, uint8_t type, pcibus_t size)
{
@@ -1013,7 +977,7 @@ static void pci_update_mappings(PCIDevice *d)
{
PCIIORegion *r;
int i;
- pcibus_t new_addr, filtered_size;
+ pcibus_t new_addr;
for(i = 0; i < PCI_NUM_REGIONS; i++) {
r = &d->io_regions[i];
@@ -1024,14 +988,8 @@ static void pci_update_mappings(PCIDevice *d)
new_addr = pci_bar_address(d, i, r->type, r->size);
- /* bridge filtering */
- filtered_size = r->size;
- if (new_addr != PCI_BAR_UNMAPPED) {
- pci_bridge_filter(d, &new_addr, &filtered_size, r->type);
- }
-
/* This bar isn't changed */
- if (new_addr == r->addr && filtered_size == r->filtered_size)
+ if (new_addr == r->addr)
continue;
/* now do the real mapping */
@@ -1039,15 +997,7 @@ static void pci_update_mappings(PCIDevice *d)
memory_region_del_subregion(r->address_space, r->memory);
}
r->addr = new_addr;
- r->filtered_size = filtered_size;
if (r->addr != PCI_BAR_UNMAPPED) {
- /*
- * TODO: currently almost all the map funcions assumes
- * filtered_size == size and addr & ~(size - 1) == addr.
- * However with bridge filtering, they aren't always true.
- * Teach them such cases, such that filtered_size < size and
- * addr & (size - 1) != 0.
- */
if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
memory_region_add_subregion_overlap(r->address_space,
r->addr,
@@ -1564,22 +1514,6 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
return res;
}
-static void pci_bridge_update_mappings_fn(PCIBus *b, PCIDevice *d)
-{
- pci_update_mappings(d);
-}
-
-void pci_bridge_update_mappings(PCIBus *b)
-{
- PCIBus *child;
-
- pci_for_each_device_under_bus(b, pci_bridge_update_mappings_fn);
-
- QLIST_FOREACH(child, &b->child, sibling) {
- pci_bridge_update_mappings(child);
- }
-}
-
/* Whether a given bus number is in range of the secondary
* bus of the given bridge device. */
static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
@@ -2016,12 +1950,6 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST;
}
-/* Reserve space for capability at a known offset (to call after load). */
-void pci_reserve_capability(PCIDevice *pdev, uint8_t offset, uint8_t size)
-{
- memset(pdev->used + offset, 0xff, size);
-}
-
uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id)
{
return pci_find_capability_list(pdev, cap_id, NULL);
diff --git a/hw/pci.h b/hw/pci.h
index c04b1693c3..7b62df16fb 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -90,7 +90,6 @@ typedef struct PCIIORegion {
pcibus_t addr; /* current PCI mapping address. -1 means not mapped */
#define PCI_BAR_UNMAPPED (~(pcibus_t)0)
pcibus_t size;
- pcibus_t filtered_size;
uint8_t type;
MemoryRegion *memory;
MemoryRegion *address_space;
@@ -209,8 +208,6 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size);
-void pci_reserve_capability(PCIDevice *pci_dev, uint8_t offset, uint8_t size);
-
uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id);
@@ -275,7 +272,6 @@ int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
void do_pci_info_print(Monitor *mon, const QObject *data);
void do_pci_info(Monitor *mon, QObject **ret_data);
-void pci_bridge_update_mappings(PCIBus *b);
void pci_device_deassert_intx(PCIDevice *dev);
diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 464d89708f..b6287cdc6d 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -135,6 +135,76 @@ pcibus_t pci_bridge_get_limit(const PCIDevice *bridge, uint8_t type)
return limit;
}
+static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
+ uint8_t type, const char *name,
+ MemoryRegion *space,
+ MemoryRegion *parent_space,
+ bool enabled)
+{
+ pcibus_t base = pci_bridge_get_base(&bridge->dev, type);
+ pcibus_t limit = pci_bridge_get_limit(&bridge->dev, type);
+ /* TODO: this doesn't handle base = 0 limit = 2^64 - 1 correctly.
+ * Apparently no way to do this with existing memory APIs. */
+ pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0;
+
+ memory_region_init_alias(alias, name, space, base, size);
+ memory_region_add_subregion_overlap(parent_space, base, alias, 1);
+}
+
+static void pci_bridge_cleanup_alias(MemoryRegion *alias,
+ MemoryRegion *parent_space)
+{
+ memory_region_del_subregion(parent_space, alias);
+ memory_region_destroy(alias);
+}
+
+static void pci_bridge_region_init(PCIBridge *br)
+{
+ PCIBus *parent = br->dev.bus;
+ uint16_t cmd = pci_get_word(br->dev.config + PCI_COMMAND);
+
+ pci_bridge_init_alias(br, &br->alias_pref_mem,
+ PCI_BASE_ADDRESS_MEM_PREFETCH,
+ "pci_bridge_pref_mem",
+ &br->address_space_mem,
+ parent->address_space_mem,
+ cmd & PCI_COMMAND_MEMORY);
+ pci_bridge_init_alias(br, &br->alias_mem,
+ PCI_BASE_ADDRESS_SPACE_MEMORY,
+ "pci_bridge_mem",
+ &br->address_space_mem,
+ parent->address_space_mem,
+ cmd & PCI_COMMAND_MEMORY);
+ pci_bridge_init_alias(br, &br->alias_io,
+ PCI_BASE_ADDRESS_SPACE_IO,
+ "pci_bridge_io",
+ &br->address_space_io,
+ parent->address_space_io,
+ cmd & PCI_COMMAND_IO);
+ /* TODO: optinal VGA and VGA palette snooping support. */
+}
+
+static void pci_bridge_region_cleanup(PCIBridge *br)
+{
+ PCIBus *parent = br->dev.bus;
+ pci_bridge_cleanup_alias(&br->alias_io,
+ parent->address_space_io);
+ pci_bridge_cleanup_alias(&br->alias_mem,
+ parent->address_space_mem);
+ pci_bridge_cleanup_alias(&br->alias_pref_mem,
+ parent->address_space_mem);
+}
+
+static void pci_bridge_update_mappings(PCIBridge *br)
+{
+ /* Make updates atomic to: handle the case of one VCPU updating the bridge
+ * while another accesses an unaffected region. */
+ memory_region_transaction_begin();
+ pci_bridge_region_cleanup(br);
+ pci_bridge_region_init(br);
+ memory_region_transaction_commit();
+}
+
/* default write_config function for PCI-to-PCI bridge */
void pci_bridge_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len)
@@ -145,13 +215,15 @@ void pci_bridge_write_config(PCIDevice *d,
pci_default_write_config(d, address, val, len);
- if (/* io base/limit */
+ if (ranges_overlap(address, len, PCI_COMMAND, 2) ||
+
+ /* io base/limit */
ranges_overlap(address, len, PCI_IO_BASE, 2) ||
/* memory base/limit, prefetchable base/limit and
io base/limit upper 16 */
ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
- pci_bridge_update_mappings(&s->sec_bus);
+ pci_bridge_update_mappings(s);
}
newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
@@ -246,7 +318,11 @@ int pci_bridge_initfn(PCIDevice *dev)
br->bus_name);
sec_bus->parent_dev = dev;
sec_bus->map_irq = br->map_irq;
-
+ sec_bus->address_space_mem = &br->address_space_mem;
+ memory_region_init(&br->address_space_mem, "pci_pridge_pci", INT64_MAX);
+ sec_bus->address_space_io = &br->address_space_io;
+ memory_region_init(&br->address_space_io, "pci_bridge_io", 65536);
+ pci_bridge_region_init(br);
QLIST_INIT(&sec_bus->child);
QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling);
return 0;
@@ -258,6 +334,9 @@ int pci_bridge_exitfn(PCIDevice *pci_dev)
PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
assert(QLIST_EMPTY(&s->sec_bus.child));
QLIST_REMOVE(&s->sec_bus, sibling);
+ pci_bridge_region_cleanup(s);
+ memory_region_destroy(&s->address_space_mem);
+ memory_region_destroy(&s->address_space_io);
/* qbus_free() is called automatically by qdev_free() */
return 0;
}
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index c7fd23dc54..96690b72d3 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -24,7 +24,6 @@ struct PCIBus {
void *irq_opaque;
PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
PCIDevice *parent_dev;
- target_phys_addr_t mem_base;
MemoryRegion *address_space_mem;
MemoryRegion *address_space_io;
@@ -42,6 +41,24 @@ struct PCIBridge {
/* private member */
PCIBus sec_bus;
+ /*
+ * Memory regions for the bridge's address spaces. These regions are not
+ * directly added to system_memory/system_io or its descendants.
+ * Bridge's secondary bus points to these, so that devices
+ * under the bridge see these regions as its address spaces.
+ * The regions are as large as the entire address space -
+ * they don't take into account any windows.
+ */
+ MemoryRegion address_space_mem;
+ MemoryRegion address_space_io;
+ /*
+ * Aliases for each of the address space windows that the bridge
+ * can forward. Mapped into the bridge's parent's address space,
+ * as subregions.
+ */
+ MemoryRegion alias_pref_mem;
+ MemoryRegion alias_mem;
+ MemoryRegion alias_io;
pci_map_irq_fn map_irq;
const char *bus_name;
};
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 51e132050f..fb2a00caad 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -285,7 +285,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0);
pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0);
- pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
+ pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
pci_conf[PCI_MIN_GNT] = 0x06;
pci_conf[PCI_MAX_LAT] = 0xff;
diff --git a/hw/qxl.c b/hw/qxl.c
index a282d2396b..6db2f1a466 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1453,10 +1453,11 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
}
}
-static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
+static void qxl_vm_change_state_handler(void *opaque, int running,
+ RunState state)
{
PCIQXLDevice *qxl = opaque;
- qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
+ qemu_spice_vm_change_state_handler(&qxl->ssd, running, state);
if (running) {
/*
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index c5de5b48ba..37539508c5 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3464,7 +3464,7 @@ static int pci_rtl8139_init(PCIDevice *dev)
uint8_t *pci_conf;
pci_conf = s->dev.config;
- pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin 0 */
+ pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
/* TODO: start of capability list, but no capability
* list bit in status register, and offset 0xdc seems unused. */
pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 02482947ca..aca65a16df 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -542,15 +542,15 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
break;
case 1:
case 2:
- cmd->xfer = buf[8] | (buf[7] << 8);
+ cmd->xfer = lduw_be_p(&buf[7]);
cmd->len = 10;
break;
case 4:
- cmd->xfer = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
+ cmd->xfer = ldl_be_p(&buf[10]);
cmd->len = 16;
break;
case 5:
- cmd->xfer = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
+ cmd->xfer = ldl_be_p(&buf[6]);
cmd->len = 12;
break;
default:
@@ -710,23 +710,15 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
switch (buf[0] >> 5) {
case 0:
- lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
- (((uint64_t) buf[1] & 0x1f) << 16);
+ lba = ldl_be_p(&buf[0]) & 0x1fffff;
break;
case 1:
case 2:
- lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
- ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
+ case 5:
+ lba = ldl_be_p(&buf[2]);
break;
case 4:
- lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
- ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
- ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
- ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
- break;
- case 5:
- lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
- ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
+ lba = ldq_be_p(&buf[2]);
break;
default:
lba = -1;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 4a60820b18..e843f712c2 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -55,6 +55,7 @@ typedef struct SCSIDiskReq {
/* Both sector and sector_count are in terms of qemu 512 byte blocks. */
uint64_t sector;
uint32_t sector_count;
+ uint32_t buflen;
struct iovec iov;
QEMUIOVector qiov;
uint32_t status;
@@ -78,13 +79,15 @@ struct SCSIDiskState
};
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
-static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
+static int scsi_disk_emulate_command(SCSIDiskReq *r);
static void scsi_free_request(SCSIRequest *req)
{
SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
- qemu_vfree(r->iov.iov_base);
+ if (r->iov.iov_base) {
+ qemu_vfree(r->iov.iov_base);
+ }
}
/* Helper function for command completion with sense. */
@@ -108,6 +111,19 @@ static void scsi_cancel_io(SCSIRequest *req)
r->req.aiocb = NULL;
}
+static uint32_t scsi_init_iovec(SCSIDiskReq *r)
+{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+
+ if (!r->iov.iov_base) {
+ r->buflen = SCSI_DMA_BUF_SIZE;
+ r->iov.iov_base = qemu_blockalign(s->bs, r->buflen);
+ }
+ r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
+ qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+ return r->qiov.size / 512;
+}
+
static void scsi_read_complete(void * opaque, int ret)
{
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -125,12 +141,12 @@ static void scsi_read_complete(void * opaque, int ret)
}
}
- DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len);
+ DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size);
- n = r->iov.iov_len / 512;
+ n = r->qiov.size / 512;
r->sector += n;
r->sector_count -= n;
- scsi_req_data(&r->req, r->iov.iov_len);
+ scsi_req_data(&r->req, r->qiov.size);
}
static void scsi_flush_complete(void * opaque, int ret)
@@ -181,16 +197,10 @@ static void scsi_read_data(SCSIRequest *req)
return;
}
- n = r->sector_count;
- if (n > SCSI_DMA_BUF_SIZE / 512)
- n = SCSI_DMA_BUF_SIZE / 512;
-
if (s->tray_open) {
scsi_read_complete(r, -ENOMEDIUM);
}
- r->iov.iov_len = n * 512;
- qemu_iovec_init_external(&r->qiov, &r->iov, 1);
-
+ n = scsi_init_iovec(r);
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);
@@ -217,7 +227,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
r->status |= SCSI_REQ_STATUS_RETRY | type;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(VMSTOP_DISKFULL);
+ vm_stop(RSTATE_IO_ERROR);
} else {
switch (error) {
case ENOMEM:
@@ -239,7 +249,6 @@ 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;
if (r->req.aiocb != NULL) {
@@ -253,19 +262,15 @@ static void scsi_write_complete(void * opaque, int ret)
}
}
- n = r->iov.iov_len / 512;
+ n = r->qiov.size / 512;
r->sector += n;
r->sector_count -= n;
if (r->sector_count == 0) {
scsi_req_complete(&r->req, GOOD);
} else {
- len = r->sector_count * 512;
- if (len > SCSI_DMA_BUF_SIZE) {
- len = SCSI_DMA_BUF_SIZE;
- }
- r->iov.iov_len = len;
- DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
- scsi_req_data(&r->req, len);
+ scsi_init_iovec(r);
+ DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size);
+ scsi_req_data(&r->req, r->qiov.size);
}
}
@@ -284,21 +289,19 @@ static void scsi_write_data(SCSIRequest *req)
return;
}
- n = r->iov.iov_len / 512;
+ n = r->qiov.size / 512;
if (n) {
if (s->tray_open) {
scsi_write_complete(r, -ENOMEDIUM);
}
- 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);
+ scsi_write_complete, r);
if (r->req.aiocb == NULL) {
scsi_write_complete(r, -ENOMEM);
}
} else {
- /* Invoke completion routine to fetch data from host. */
+ /* Called for the first time. Ask the driver to send us more data. */
scsi_write_complete(r, 0);
}
}
@@ -329,7 +332,7 @@ static void scsi_dma_restart_bh(void *opaque)
scsi_write_data(&r->req);
break;
case SCSI_REQ_STATUS_RETRY_FLUSH:
- ret = scsi_disk_emulate_command(r, r->iov.iov_base);
+ ret = scsi_disk_emulate_command(r);
if (ret == 0) {
scsi_req_complete(&r->req, GOOD);
}
@@ -338,7 +341,7 @@ static void scsi_dma_restart_bh(void *opaque)
}
}
-static void scsi_dma_restart_cb(void *opaque, int running, int reason)
+static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
{
SCSIDiskState *s = opaque;
@@ -844,13 +847,31 @@ static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
return 0;
}
-static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
+static int scsi_disk_emulate_command(SCSIDiskReq *r)
{
SCSIRequest *req = &r->req;
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
uint64_t nb_sectors;
+ uint8_t *outbuf;
int buflen = 0;
+ if (!r->iov.iov_base) {
+ /*
+ * FIXME: we shouldn't return anything bigger than 4k, but the code
+ * requires the buffer to be as big as req->cmd.xfer in several
+ * places. So, do not allow CDBs with a very large ALLOCATION
+ * LENGTH. The real fix would be to modify scsi_read_data and
+ * dma_buf_read, so that they return data beyond the buflen
+ * as all zeros.
+ */
+ if (req->cmd.xfer > 65536) {
+ goto illegal_request;
+ }
+ r->buflen = MAX(4096, req->cmd.xfer);
+ r->iov.iov_base = qemu_blockalign(s->bs, r->buflen);
+ }
+
+ outbuf = r->iov.iov_base;
switch (req->cmd.buf[0]) {
case TEST_UNIT_READY:
if (s->tray_open || !bdrv_is_inserted(s->bs))
@@ -1001,11 +1022,9 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
int32_t len;
uint8_t command;
- uint8_t *outbuf;
int rc;
command = buf[0];
- outbuf = (uint8_t *)r->iov.iov_base;
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
#ifdef DEBUG_SCSI
@@ -1034,7 +1053,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
case GET_CONFIGURATION:
case SERVICE_ACTION_IN_16:
case VERIFY_10:
- rc = scsi_disk_emulate_command(r, outbuf);
+ rc = scsi_disk_emulate_command(r);
if (rc < 0) {
return 0;
}
@@ -1285,11 +1304,8 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
SCSIRequest *req;
- SCSIDiskReq *r;
req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private);
- r = DO_UPCAST(SCSIDiskReq, req, req);
- r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
return req;
}
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 5ce01afdce..8f6b70df2b 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -244,12 +244,6 @@ static uint8_t *scsi_get_buf(SCSIRequest *req)
static void scsi_req_fixup(SCSIRequest *req)
{
switch(req->cmd.buf[0]) {
- case WRITE_10:
- req->cmd.buf[1] &= ~0x08; /* disable FUA */
- break;
- case READ_10:
- req->cmd.buf[1] &= ~0x08; /* disable FUA */
- break;
case REWIND:
case START_STOP:
if (req->dev->type == TYPE_TAPE) {
diff --git a/hw/soc_dma.h b/hw/soc_dma.h
index c0ebb8d715..904b26c5a8 100644
--- a/hw/soc_dma.h
+++ b/hw/soc_dma.h
@@ -18,6 +18,8 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "memory.h"
+
struct soc_dma_s;
struct soc_dma_ch_s;
typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len);
@@ -105,9 +107,3 @@ static inline void soc_dma_port_add_fifo_out(struct soc_dma_s *dma,
{
return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 1);
}
-
-static inline void soc_dma_port_add_mem_ram(struct soc_dma_s *dma,
- ram_addr_t offset, target_phys_addr_t virt_base, size_t size)
-{
- return soc_dma_port_add_mem(dma, qemu_get_ram_ptr(offset), virt_base, size);
-}
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 32e6ab9beb..6afb0e7158 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -763,7 +763,6 @@ static void sun4uv_init(ram_addr_t RAM_size,
irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2,
&pci_bus3);
- isa_mem_base = APB_PCI_IO_BASE;
pci_vga_init(pci_bus);
// XXX Should be pci_bus3
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index e9e0789795..27376a2351 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2291,7 +2291,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00);
//pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50);
- pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); // interrupt pin 3
+ pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); /* interrupt pin D */
pci_set_byte(&pci_conf[PCI_MIN_GNT], 0);
pci_set_byte(&pci_conf[PCI_MAX_LAT], 0);
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 503ca2d31f..c3be65a2e9 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1780,8 +1780,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
- /* TODO: RST# value should be 0. */
- ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
+ ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0,
ohci->masterbus, ohci->firstport) != 0) {
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 64f7b36c00..17992cf003 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1131,7 +1131,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
pci_conf[PCI_CLASS_PROG] = 0x00;
/* TODO: reset value should be 0. */
- pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
+ pci_conf[PCI_INTERRUPT_PIN] = 4; /* interrupt pin D */
pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
if (s->masterbus) {
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index c2ee0001eb..daa8e42be7 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -77,7 +77,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
req->next = s->rq;
s->rq = req;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
- vm_stop(VMSTOP_DISKFULL);
+ vm_stop(RSTATE_IO_ERROR);
} else {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
bdrv_acct_done(s->bs, &req->acct);
@@ -439,7 +439,8 @@ static void virtio_blk_dma_restart_bh(void *opaque)
virtio_submit_multiwrite(s->bs, &mrb);
}
-static void virtio_blk_dma_restart_cb(void *opaque, int running, int reason)
+static void virtio_blk_dma_restart_cb(void *opaque, int running,
+ RunState state)
{
VirtIOBlock *s = opaque;
diff --git a/hw/virtio.c b/hw/virtio.c
index 946d911580..d9bf266492 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -847,7 +847,7 @@ void virtio_cleanup(VirtIODevice *vdev)
g_free(vdev);
}
-static void virtio_vmstate_change(void *opaque, int running, int reason)
+static void virtio_vmstate_change(void *opaque, int running, RunState state)
{
VirtIODevice *vdev = opaque;
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
@@ -880,7 +880,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
vdev->queue_sel = 0;
vdev->config_vector = VIRTIO_NO_VECTOR;
vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
- vdev->vm_running = vm_running;
+ vdev->vm_running = runstate_is_running();
for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
vdev->vq[i].vector = VIRTIO_NO_VECTOR;
vdev->vq[i].vdev = vdev;
diff --git a/hw/watchdog.c b/hw/watchdog.c
index 1c900a1189..71c6c7df63 100644
--- a/hw/watchdog.c
+++ b/hw/watchdog.c
@@ -132,7 +132,7 @@ void watchdog_perform_action(void)
case WDT_PAUSE: /* same as 'stop' command in monitor */
watchdog_mon_event("pause");
- vm_stop(VMSTOP_WATCHDOG);
+ vm_stop(RSTATE_WATCHDOG);
break;
case WDT_DEBUG:
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index aeca8da96b..ef2a2d6997 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -25,7 +25,6 @@
#include <inttypes.h>
#include <fcntl.h>
#include <errno.h>
-#include <pthread.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/types.h>
diff --git a/hw/xics.c b/hw/xics.c
index 9bf82aaf24..80e064eaa3 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -29,8 +29,6 @@
#include "hw/spapr.h"
#include "hw/xics.h"
-#include <pthread.h>
-
/*
* ICP: Presentation layer
*/
diff --git a/kvm-all.c b/kvm-all.c
index fbb9ff3bef..228655b388 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1014,7 +1014,7 @@ int kvm_cpu_exec(CPUState *env)
if (ret < 0) {
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
- vm_stop(VMSTOP_PANIC);
+ vm_stop(RSTATE_PANICKED);
}
env->exit_request = 0;
diff --git a/libcacard/Makefile b/libcacard/Makefile
index 81d9eb5206..a145569044 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -27,6 +27,8 @@ clean:
rm -Rf .libs
all: vscclient
+# Dummy command so that make thinks it has done something
+ @true
#########################################################################
# Rules for building libcacard standalone library
diff --git a/linux-aio.c b/linux-aio.c
index 5265a029b2..bffa6cd0e3 100644
--- a/linux-aio.c
+++ b/linux-aio.c
@@ -68,15 +68,6 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
qemu_aio_release(laiocb);
}
-/*
- * All requests are directly processed when they complete, so there's nothing
- * left to do during qemu_aio_wait().
- */
-static int qemu_laio_process_requests(void *opaque)
-{
- return 0;
-}
-
static void qemu_laio_completion_cb(void *opaque)
{
struct qemu_laio_state *s = opaque;
@@ -215,7 +206,7 @@ void *laio_init(void)
goto out_close_efd;
qemu_aio_set_fd_handler(s->efd, qemu_laio_completion_cb, NULL,
- qemu_laio_flush_cb, qemu_laio_process_requests, s);
+ qemu_laio_flush_cb, NULL, s);
return s;
diff --git a/migration.c b/migration.c
index f5959b4391..7dd8f4eee9 100644
--- a/migration.c
+++ b/migration.c
@@ -70,10 +70,11 @@ void process_incoming_migration(QEMUFile *f)
qemu_announce_self();
DPRINTF("successfully loaded vm state\n");
- incoming_expected = false;
-
- if (autostart)
+ if (autostart) {
vm_start();
+ } else {
+ runstate_set(RSTATE_PRE_LAUNCH);
+ }
}
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
@@ -371,10 +372,10 @@ void migrate_fd_put_ready(void *opaque)
DPRINTF("iterate\n");
if (qemu_savevm_state_iterate(s->mon, s->file) == 1) {
int state;
- int old_vm_running = vm_running;
+ int old_vm_running = runstate_is_running();
DPRINTF("done iterating\n");
- vm_stop(VMSTOP_MIGRATE);
+ vm_stop(RSTATE_PRE_MIGRATE);
if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) {
if (old_vm_running) {
@@ -390,6 +391,9 @@ void migrate_fd_put_ready(void *opaque)
}
state = MIG_STATE_ERROR;
}
+ if (state == MIG_STATE_COMPLETED) {
+ runstate_set(RSTATE_POST_MIGRATE);
+ }
s->state = state;
notifier_list_notify(&migration_state_notifiers, NULL);
}
diff --git a/monitor.c b/monitor.c
index 03ae997ffe..8ec2c5efea 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1293,7 +1293,7 @@ static void do_singlestep(Monitor *mon, const QDict *qdict)
*/
static int do_stop(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
- vm_stop(VMSTOP_USER);
+ vm_stop(RSTATE_PAUSED);
return 0;
}
@@ -1311,10 +1311,15 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
struct bdrv_iterate_context context = { mon, 0 };
- if (incoming_expected) {
+ if (runstate_check(RSTATE_IN_MIGRATE)) {
qerror_report(QERR_MIGRATION_EXPECTED);
return -1;
+ } else if (runstate_check(RSTATE_PANICKED) ||
+ runstate_check(RSTATE_SHUTDOWN)) {
+ qerror_report(QERR_RESET_REQUIRED);
+ return -1;
}
+
bdrv_iterate(encrypted_bdrv_it, &context);
/* only resume the vm if all keys are set and valid */
if (!context.err) {
@@ -2613,6 +2618,7 @@ static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data)
static void do_info_status_print(Monitor *mon, const QObject *data)
{
QDict *qdict;
+ const char *status;
qdict = qobject_to_qdict(data);
@@ -2626,13 +2632,17 @@ static void do_info_status_print(Monitor *mon, const QObject *data)
monitor_printf(mon, "paused");
}
+ status = qdict_get_str(qdict, "status");
+ if (strcmp(status, "paused") && strcmp(status, "running")) {
+ monitor_printf(mon, " (%s)", status);
+ }
+
monitor_printf(mon, "\n");
}
static void do_info_status(Monitor *mon, QObject **ret_data)
{
- *ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i }",
- vm_running, singlestep);
+ *ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i, 'status': %s }", runstate_is_running(), singlestep, runstate_as_string());
}
static qemu_acl *find_acl(Monitor *mon, const char *name)
@@ -2825,10 +2835,10 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data)
static void do_loadvm(Monitor *mon, const QDict *qdict)
{
- int saved_vm_running = vm_running;
+ int saved_vm_running = runstate_is_running();
const char *name = qdict_get_str(qdict, "name");
- vm_stop(VMSTOP_LOADVM);
+ vm_stop(RSTATE_RESTORE);
if (load_vmstate(name) == 0 && saved_vm_running) {
vm_start();
diff --git a/nbd.c b/nbd.c
index 6d81cfbcd0..595f4d8df3 100644
--- a/nbd.c
+++ b/nbd.c
@@ -30,6 +30,10 @@
#include <ctype.h>
#include <inttypes.h>
+#ifdef __linux__
+#include <linux/fs.h>
+#endif
+
#include "qemu_socket.h"
//#define DEBUG_NBD
@@ -63,6 +67,8 @@
#define NBD_PRINT_DEBUG _IO(0xab, 6)
#define NBD_SET_SIZE_BLOCKS _IO(0xab, 7)
#define NBD_DISCONNECT _IO(0xab, 8)
+#define NBD_SET_TIMEOUT _IO(0xab, 9)
+#define NBD_SET_FLAGS _IO(0xab, 10)
#define NBD_OPT_EXPORT_NAME (1 << 0)
@@ -172,7 +178,7 @@ int unix_socket_outgoing(const char *path)
Request (type == 2)
*/
-int nbd_negotiate(int csock, off_t size)
+int nbd_negotiate(int csock, off_t size, uint32_t flags)
{
char buf[8 + 8 + 8 + 128];
@@ -180,14 +186,16 @@ int nbd_negotiate(int csock, off_t size)
[ 0 .. 7] passwd ("NBDMAGIC")
[ 8 .. 15] magic (0x00420281861253)
[16 .. 23] size
- [24 .. 151] reserved (0)
+ [24 .. 27] flags
+ [28 .. 151] reserved (0)
*/
TRACE("Beginning negotiation.");
memcpy(buf, "NBDMAGIC", 8);
cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
cpu_to_be64w((uint64_t*)(buf + 16), size);
- memset(buf + 24, 0, 128);
+ cpu_to_be32w((uint32_t*)(buf + 24), flags | NBD_FLAG_HAS_FLAGS);
+ memset(buf + 28, 0, 124);
if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
LOG("write failed");
@@ -337,8 +345,8 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
return 0;
}
-#ifndef _WIN32
-int nbd_init(int fd, int csock, off_t size, size_t blocksize)
+#ifdef __linux__
+int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
{
TRACE("Setting block size to %lu", (unsigned long)blocksize);
@@ -358,6 +366,26 @@ int nbd_init(int fd, int csock, off_t size, size_t blocksize)
return -1;
}
+ if (flags & NBD_FLAG_READ_ONLY) {
+ int read_only = 1;
+ TRACE("Setting readonly attribute");
+
+ if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {
+ int serrno = errno;
+ LOG("Failed setting read-only attribute");
+ errno = serrno;
+ return -1;
+ }
+ }
+
+ if (ioctl(fd, NBD_SET_FLAGS, flags) < 0
+ && errno != ENOTTY) {
+ int serrno = errno;
+ LOG("Failed setting flags");
+ errno = serrno;
+ return -1;
+ }
+
TRACE("Clearing NBD socket");
if (ioctl(fd, NBD_CLEAR_SOCK) == -1) {
@@ -548,7 +576,7 @@ static int nbd_send_reply(int csock, struct nbd_reply *reply)
}
int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
- off_t *offset, bool readonly, uint8_t *data, int data_size)
+ off_t *offset, uint32_t nbdflags, uint8_t *data, int data_size)
{
struct nbd_request request;
struct nbd_reply reply;
@@ -632,7 +660,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
return -1;
}
- if (readonly) {
+ if (nbdflags & NBD_FLAG_READ_ONLY) {
TRACE("Server is read-only, return error");
reply.error = 1;
} else {
diff --git a/nbd.h b/nbd.h
index df7b7af7c0..61553f4128 100644
--- a/nbd.h
+++ b/nbd.h
@@ -37,10 +37,22 @@ struct nbd_reply {
uint64_t handle;
} QEMU_PACKED;
+#define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */
+#define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */
+#define NBD_FLAG_SEND_FLUSH (1 << 2) /* Send FLUSH */
+#define NBD_FLAG_SEND_FUA (1 << 3) /* Send FUA (Force Unit Access) */
+#define NBD_FLAG_ROTATIONAL (1 << 4) /* Use elevator algorithm - rotational media */
+#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */
+
+#define NBD_CMD_MASK_COMMAND 0x0000ffff
+#define NBD_CMD_FLAG_FUA (1 << 16)
+
enum {
NBD_CMD_READ = 0,
NBD_CMD_WRITE = 1,
- NBD_CMD_DISC = 2
+ NBD_CMD_DISC = 2,
+ NBD_CMD_FLUSH = 3,
+ NBD_CMD_TRIM = 4
};
#define NBD_DEFAULT_PORT 10809
@@ -53,14 +65,14 @@ int tcp_socket_incoming_spec(const char *address_and_port);
int unix_socket_outgoing(const char *path);
int unix_socket_incoming(const char *path);
-int nbd_negotiate(int csock, off_t size);
+int nbd_negotiate(int csock, off_t size, uint32_t flags);
int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
off_t *size, size_t *blocksize);
-int nbd_init(int fd, int csock, off_t size, size_t blocksize);
+int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize);
int nbd_send_request(int csock, struct nbd_request *request);
int nbd_receive_reply(int csock, struct nbd_reply *reply);
int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
- off_t *offset, bool readonly, uint8_t *data, int data_size);
+ off_t *offset, uint32_t nbdflags, uint8_t *data, int data_size);
int nbd_client(int fd);
int nbd_disconnect(int fd);
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index 3193dbf83c..d3c1174ebf 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -42,7 +42,6 @@ struct qemu_paiocb {
int aio_niov;
size_t aio_nbytes;
#define aio_ioctl_cmd aio_nbytes /* for QEMU_AIO_IOCTL */
- int ev_signo;
off_t aio_offset;
QTAILQ_ENTRY(qemu_paiocb) node;
@@ -181,7 +180,6 @@ qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset)
static ssize_t handle_aiocb_rw_vector(struct qemu_paiocb *aiocb)
{
- size_t offset = 0;
ssize_t len;
do {
@@ -189,12 +187,12 @@ static ssize_t handle_aiocb_rw_vector(struct qemu_paiocb *aiocb)
len = qemu_pwritev(aiocb->aio_fildes,
aiocb->aio_iov,
aiocb->aio_niov,
- aiocb->aio_offset + offset);
+ aiocb->aio_offset);
else
len = qemu_preadv(aiocb->aio_fildes,
aiocb->aio_iov,
aiocb->aio_niov,
- aiocb->aio_offset + offset);
+ aiocb->aio_offset);
} while (len == -1 && errno == EINTR);
if (len == -1)
@@ -309,12 +307,10 @@ static ssize_t handle_aiocb_rw(struct qemu_paiocb *aiocb)
return nbytes;
}
+static void posix_aio_notify_event(void);
+
static void *aio_thread(void *unused)
{
- pid_t pid;
-
- pid = getpid();
-
mutex_lock(&lock);
pending_threads--;
mutex_unlock(&lock);
@@ -381,7 +377,7 @@ static void *aio_thread(void *unused)
aiocb->ret = ret;
mutex_unlock(&lock);
- if (kill(pid, aiocb->ev_signo)) die("kill failed");
+ posix_aio_notify_event();
}
cur_threads--;
@@ -548,18 +544,14 @@ static int posix_aio_flush(void *opaque)
static PosixAioState *posix_aio_state;
-static void aio_signal_handler(int signum)
+static void posix_aio_notify_event(void)
{
- if (posix_aio_state) {
- char byte = 0;
- ssize_t ret;
-
- ret = write(posix_aio_state->wfd, &byte, sizeof(byte));
- if (ret < 0 && errno != EAGAIN)
- die("write()");
- }
+ char byte = 0;
+ ssize_t ret;
- qemu_service_io();
+ ret = write(posix_aio_state->wfd, &byte, sizeof(byte));
+ if (ret < 0 && errno != EAGAIN)
+ die("write()");
}
static void paio_remove(struct qemu_paiocb *acb)
@@ -623,7 +615,6 @@ BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,
return NULL;
acb->aio_type = type;
acb->aio_fildes = fd;
- acb->ev_signo = SIGUSR2;
if (qiov) {
acb->aio_iov = qiov->iov;
@@ -651,7 +642,6 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd,
return NULL;
acb->aio_type = QEMU_AIO_IOCTL;
acb->aio_fildes = fd;
- acb->ev_signo = SIGUSR2;
acb->aio_offset = 0;
acb->aio_ioctl_buf = buf;
acb->aio_ioctl_cmd = req;
@@ -665,7 +655,6 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd,
int paio_init(void)
{
- struct sigaction act;
PosixAioState *s;
int fds[2];
int ret;
@@ -675,11 +664,6 @@ int paio_init(void)
s = g_malloc(sizeof(PosixAioState));
- sigfillset(&act.sa_mask);
- act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
- act.sa_handler = aio_signal_handler;
- sigaction(SIGUSR2, &act, NULL);
-
s->first_aio = NULL;
if (qemu_pipe(fds) == -1) {
fprintf(stderr, "failed to create pipe\n");
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 3a39145174..d8d3e15a84 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -185,7 +185,7 @@ int main(int argc, char **argv)
BlockDriverState *bs;
off_t dev_offset = 0;
off_t offset = 0;
- bool readonly = false;
+ uint32_t nbdflags = 0;
bool disconnect = false;
const char *bindto = "0.0.0.0";
int port = NBD_DEFAULT_PORT;
@@ -230,7 +230,6 @@ int main(int argc, char **argv)
int nb_fds = 0;
int max_fd;
int persistent = 0;
- uint32_t nbdflags;
while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
switch (ch) {
@@ -263,7 +262,7 @@ int main(int argc, char **argv)
}
break;
case 'r':
- readonly = true;
+ nbdflags |= NBD_FLAG_READ_ONLY;
flags &= ~BDRV_O_RDWR;
break;
case 'P':
@@ -398,13 +397,13 @@ int main(int argc, char **argv)
}
ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
- &size, &blocksize);
+ &size, &blocksize);
if (ret == -1) {
ret = 1;
goto out;
}
- ret = nbd_init(fd, sock, size, blocksize);
+ ret = nbd_init(fd, sock, nbdflags, size, blocksize);
if (ret == -1) {
ret = 1;
goto out;
@@ -463,7 +462,7 @@ int main(int argc, char **argv)
for (i = 1; i < nb_fds && ret; i++) {
if (FD_ISSET(sharing_fds[i], &fds)) {
if (nbd_trip(bs, sharing_fds[i], fd_size, dev_offset,
- &offset, readonly, data, NBD_BUFFER_SIZE) != 0) {
+ &offset, nbdflags, data, NBD_BUFFER_SIZE) != 0) {
close(sharing_fds[i]);
nb_fds--;
sharing_fds[i] = sharing_fds[nb_fds];
@@ -479,7 +478,7 @@ int main(int argc, char **argv)
(struct sockaddr *)&addr,
&addr_len);
if (sharing_fds[nb_fds] != -1 &&
- nbd_negotiate(sharing_fds[nb_fds], fd_size) != -1) {
+ nbd_negotiate(sharing_fds[nb_fds], fd_size, nbdflags) != -1) {
if (sharing_fds[nb_fds] > max_fd)
max_fd = sharing_fds[nb_fds];
nb_fds++;
diff --git a/qemu-thread-posix.c b/qemu-thread-posix.c
index 2bd02efeff..ac3c0c9d14 100644
--- a/qemu-thread-posix.c
+++ b/qemu-thread-posix.c
@@ -22,7 +22,7 @@
static void error_exit(int err, const char *msg)
{
fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
- exit(1);
+ abort();
}
void qemu_mutex_init(QemuMutex *mutex)
diff --git a/qemu-thread-win32.c b/qemu-thread-win32.c
index a27332e669..db8e744729 100644
--- a/qemu-thread-win32.c
+++ b/qemu-thread-win32.c
@@ -24,7 +24,7 @@ static void error_exit(int err, const char *msg)
NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
LocalFree(pstr);
- exit(1);
+ abort();
}
void qemu_mutex_init(QemuMutex *mutex)
diff --git a/qemu-timer.c b/qemu-timer.c
index 46dd483fdd..ad1fc8b871 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -230,7 +230,7 @@ static void icount_adjust(void)
int64_t delta;
static int64_t last_delta;
/* If the VM is not running, then do nothing. */
- if (!vm_running)
+ if (!runstate_is_running())
return;
cur_time = cpu_get_clock();
@@ -388,7 +388,7 @@ static void icount_warp_rt(void *opaque)
return;
}
- if (vm_running) {
+ if (runstate_is_running()) {
int64_t clock = qemu_get_clock_ns(rt_clock);
int64_t warp_delta = clock - vm_clock_warp_start;
if (use_icount == 1) {
@@ -710,7 +710,7 @@ void qemu_run_all_timers(void)
}
/* vm time timers */
- if (vm_running) {
+ if (runstate_is_running()) {
qemu_run_timers(vm_clock);
}
@@ -1116,7 +1116,8 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
#endif /* _WIN32 */
-static void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason)
+static void alarm_timer_on_change_state_rearm(void *opaque, int running,
+ RunState state)
{
if (running)
qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
diff --git a/qerror.c b/qerror.c
index 3d64b80b24..c591a5443c 100644
--- a/qerror.c
+++ b/qerror.c
@@ -194,6 +194,10 @@ static const QErrorStringTable qerror_table[] = {
.desc = "QMP input object member '%(member)' is unexpected",
},
{
+ .error_fmt = QERR_RESET_REQUIRED,
+ .desc = "Resetting the Virtual Machine is required",
+ },
+ {
.error_fmt = QERR_SET_PASSWD_FAILED,
.desc = "Could not set password",
},
diff --git a/qerror.h b/qerror.h
index 8058456d2e..d4070015f7 100644
--- a/qerror.h
+++ b/qerror.h
@@ -163,6 +163,9 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_QMP_EXTRA_MEMBER \
"{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }"
+#define QERR_RESET_REQUIRED \
+ "{ 'class': 'ResetRequired', 'data': {} }"
+
#define QERR_SET_PASSWD_FAILED \
"{ 'class': 'SetPasswdFailed', 'data': {} }"
diff --git a/qmp-commands.hx b/qmp-commands.hx
index d1c2c5905d..d83bce5662 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1573,11 +1573,28 @@ Return a json-object with the following information:
- "running": true if the VM is running, or false if it is paused (json-bool)
- "singlestep": true if the VM is in single step mode,
false otherwise (json-bool)
+- "status": one of the following values (json-string)
+ "debug" - QEMU is running on a debugger
+ "inmigrate" - guest is paused waiting for an incoming migration
+ "internal-error" - An internal error that prevents further guest
+ execution has occurred
+ "io-error" - the last IOP has failed and the device is configured
+ to pause on I/O errors
+ "paused" - guest has been paused via the 'stop' command
+ "postmigrate" - guest is paused following a successful 'migrate'
+ "prelaunch" - QEMU was started with -S and guest has not started
+ "finish-migrate" - guest is paused to finish the migration process
+ "restore-vm" - guest is paused to restore VM state
+ "running" - guest is actively running
+ "save-vm" - guest is paused to save the VM state
+ "shutdown" - guest is shut down (and -no-shutdown is in use)
+ "watchdog" - the watchdog action is configured to pause and
+ has been triggered
Example:
-> { "execute": "query-status" }
-<- { "return": { "running": true, "singlestep": false } }
+<- { "return": { "running": true, "singlestep": false, "status": "running" } }
EQMP
diff --git a/savevm.c b/savevm.c
index 1feaa70ccc..46f2447dc0 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1602,8 +1602,8 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
int saved_vm_running;
int ret;
- saved_vm_running = vm_running;
- vm_stop(VMSTOP_SAVEVM);
+ saved_vm_running = runstate_is_running();
+ vm_stop(RSTATE_SAVEVM);
if (qemu_savevm_state_blocked(mon)) {
ret = -EINVAL;
@@ -1931,8 +1931,8 @@ void do_savevm(Monitor *mon, const QDict *qdict)
return;
}
- saved_vm_running = vm_running;
- vm_stop(VMSTOP_SAVEVM);
+ saved_vm_running = runstate_is_running();
+ vm_stop(RSTATE_SAVEVM);
memset(sn, 0, sizeof(*sn));
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 8bbd70caf1..2f1a196b39 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -610,6 +610,7 @@ findso:
so->so_ti = ti;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
tp->t_state = TCPS_SYN_RECEIVED;
+ tcp_template(tp);
}
return;
diff --git a/sysemu.h b/sysemu.h
index 9090457881..43ff546f9b 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -9,42 +9,56 @@
#include "notify.h"
/* vl.c */
+
+typedef enum {
+ RSTATE_NO_STATE,
+ RSTATE_DEBUG, /* qemu is running under gdb */
+ RSTATE_IN_MIGRATE, /* paused waiting for an incoming migration */
+ RSTATE_PANICKED, /* paused due to an internal error */
+ RSTATE_IO_ERROR, /* paused due to an I/O error */
+ RSTATE_PAUSED, /* paused by the user (ie. the 'stop' command) */
+ RSTATE_POST_MIGRATE, /* paused following a successful migration */
+ RSTATE_PRE_LAUNCH, /* qemu was started with -S and haven't started */
+ RSTATE_PRE_MIGRATE, /* paused preparing to finish migrate */
+ RSTATE_RESTORE, /* paused restoring the VM state */
+ RSTATE_RUNNING, /* qemu is running */
+ RSTATE_SAVEVM, /* paused saving VM state */
+ RSTATE_SHUTDOWN, /* guest shut down and -no-shutdown is in use */
+ RSTATE_WATCHDOG, /* watchdog fired and qemu is configured to pause */
+ RSTATE_MAX
+} RunState;
+
extern const char *bios_name;
-extern int vm_running;
extern const char *qemu_name;
extern uint8_t qemu_uuid[];
int qemu_uuid_parse(const char *str, uint8_t *uuid);
#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
+void runstate_init(void);
+bool runstate_check(RunState state);
+void runstate_set(RunState new_state);
+int runstate_is_running(void);
+const char *runstate_as_string(void);
typedef struct vm_change_state_entry VMChangeStateEntry;
-typedef void VMChangeStateHandler(void *opaque, int running, int reason);
+typedef void VMChangeStateHandler(void *opaque, int running, RunState state);
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque);
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
-
-#define VMSTOP_USER 0
-#define VMSTOP_DEBUG 1
-#define VMSTOP_SHUTDOWN 2
-#define VMSTOP_DISKFULL 3
-#define VMSTOP_WATCHDOG 4
-#define VMSTOP_PANIC 5
-#define VMSTOP_SAVEVM 6
-#define VMSTOP_LOADVM 7
-#define VMSTOP_MIGRATE 8
+void vm_state_notify(int running, RunState state);
#define VMRESET_SILENT false
#define VMRESET_REPORT true
void vm_start(void);
-void vm_stop(int reason);
+void vm_stop(RunState state);
void qemu_system_reset_request(void);
void qemu_system_shutdown_request(void);
void qemu_system_powerdown_request(void);
void qemu_system_debug_request(void);
-void qemu_system_vmstop_request(int reason);
+void qemu_system_vmstop_request(RunState reason);
int qemu_shutdown_requested_get(void);
int qemu_reset_requested_get(void);
int qemu_shutdown_requested(void);
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4a6f675f98..ae36489a9a 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -991,11 +991,6 @@ static inline int cpu_mmu_index (CPUState *env)
/* translate.c */
void optimize_flags_init(void);
-typedef struct CCTable {
- int (*compute_all)(void); /* return all the flags */
- int (*compute_c)(void); /* return the C flag */
-} CCTable;
-
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 22b1dd0665..b6eef047bf 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -334,7 +334,7 @@ static int kvm_inject_mce_oldstyle(CPUState *env)
return 0;
}
-static void cpu_update_state(void *opaque, int running, int reason)
+static void cpu_update_state(void *opaque, int running, RunState state)
{
CPUState *env = opaque;
@@ -1130,7 +1130,7 @@ static int kvm_get_msrs(CPUState *env)
if (!env->tsc_valid) {
msrs[n++].index = MSR_IA32_TSC;
- env->tsc_valid = !vm_running;
+ env->tsc_valid = !runstate_is_running();
}
#ifdef TARGET_X86_64
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b9667628a0..b894e97e15 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7641,11 +7641,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
void optimize_flags_init(void)
{
-#if TCG_TARGET_REG_BITS == 32
- assert(sizeof(CCTable) == (1 << 3));
-#else
- assert(sizeof(CCTable) == (1 << 4));
-#endif
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUState, cc_op), "cc_op");
diff --git a/trace-events b/trace-events
index 829dc927cf..a31d9aa2ae 100644
--- a/trace-events
+++ b/trace-events
@@ -455,7 +455,7 @@ milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08
mipsnet_send(uint32_t size) "sending len=%u"
mipsnet_receive(uint32_t size) "receiving len=%u"
mipsnet_read(uint64_t addr, uint32_t val) "read addr=0x%" PRIx64 " val=0x%x"
-mipsnet_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64
+mipsnet_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64 ""
mipsnet_irq(uint32_t isr, uint32_t intctl) "set irq to %d (%02x)"
# xen-all.c
diff --git a/trace/simple.c b/trace/simple.c
index a6093682dd..b639dda806 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -12,8 +12,10 @@
#include <stdint.h>
#include <stdio.h>
#include <time.h>
+#ifndef _WIN32
#include <signal.h>
#include <pthread.h>
+#endif
#include "qemu-timer.h"
#include "trace.h"
#include "trace/control.h"
@@ -54,9 +56,9 @@ enum {
* Trace records are written out by a dedicated thread. The thread waits for
* records to become available, writes them out, and then waits again.
*/
-static pthread_mutex_t trace_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t trace_available_cond = PTHREAD_COND_INITIALIZER;
-static pthread_cond_t trace_empty_cond = PTHREAD_COND_INITIALIZER;
+static GStaticMutex trace_lock = G_STATIC_MUTEX_INIT;
+static GCond *trace_available_cond;
+static GCond *trace_empty_cond;
static bool trace_available;
static bool trace_writeout_enabled;
@@ -93,29 +95,30 @@ static bool get_trace_record(unsigned int idx, TraceRecord *record)
*/
static void flush_trace_file(bool wait)
{
- pthread_mutex_lock(&trace_lock);
+ g_static_mutex_lock(&trace_lock);
trace_available = true;
- pthread_cond_signal(&trace_available_cond);
+ g_cond_signal(trace_available_cond);
if (wait) {
- pthread_cond_wait(&trace_empty_cond, &trace_lock);
+ g_cond_wait(trace_empty_cond, g_static_mutex_get_mutex(&trace_lock));
}
- pthread_mutex_unlock(&trace_lock);
+ g_static_mutex_unlock(&trace_lock);
}
static void wait_for_trace_records_available(void)
{
- pthread_mutex_lock(&trace_lock);
+ g_static_mutex_lock(&trace_lock);
while (!(trace_available && trace_writeout_enabled)) {
- pthread_cond_signal(&trace_empty_cond);
- pthread_cond_wait(&trace_available_cond, &trace_lock);
+ g_cond_signal(trace_empty_cond);
+ g_cond_wait(trace_available_cond,
+ g_static_mutex_get_mutex(&trace_lock));
}
trace_available = false;
- pthread_mutex_unlock(&trace_lock);
+ g_static_mutex_unlock(&trace_lock);
}
-static void *writeout_thread(void *opaque)
+static gpointer writeout_thread(gpointer opaque)
{
TraceRecord record;
unsigned int writeout_idx = 0;
@@ -159,7 +162,7 @@ static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
timestamp = get_clock();
- idx = __sync_fetch_and_add(&trace_idx, 1) % TRACE_BUF_LEN;
+ idx = g_atomic_int_exchange_and_add((gint *)&trace_idx, 1) % TRACE_BUF_LEN;
trace_buf[idx] = (TraceRecord){
.event = event,
.timestamp_ns = timestamp,
@@ -231,7 +234,7 @@ void st_set_trace_file_enabled(bool enable)
.x1 = HEADER_VERSION,
};
- trace_fp = fopen(trace_file_name, "w");
+ trace_fp = fopen(trace_file_name, "wb");
if (!trace_fp) {
return;
}
@@ -331,28 +334,47 @@ bool trace_event_set_state(const char *name, bool state)
return false;
}
-bool trace_backend_init(const char *events, const char *file)
+/* Helper function to create a thread with signals blocked. Use glib's
+ * portable threads since QEMU abstractions cannot be used due to reentrancy in
+ * the tracer. Also note the signal masking on POSIX hosts so that the thread
+ * does not steal signals when the rest of the program wants them blocked.
+ */
+static GThread *trace_thread_create(GThreadFunc fn)
{
- pthread_t thread;
- pthread_attr_t attr;
+ GThread *thread;
+#ifndef _WIN32
sigset_t set, oldset;
- int ret;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
sigfillset(&set);
pthread_sigmask(SIG_SETMASK, &set, &oldset);
- ret = pthread_create(&thread, &attr, writeout_thread, NULL);
+#endif
+ thread = g_thread_create(writeout_thread, NULL, FALSE, NULL);
+#ifndef _WIN32
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+#endif
- if (ret != 0) {
+ return thread;
+}
+
+bool trace_backend_init(const char *events, const char *file)
+{
+ GThread *thread;
+
+ if (!g_thread_supported()) {
+ g_thread_init(NULL);
+ }
+
+ trace_available_cond = g_cond_new();
+ trace_empty_cond = g_cond_new();
+
+ thread = trace_thread_create(writeout_thread);
+ if (!thread) {
fprintf(stderr, "warning: unable to initialize simple trace backend\n");
- } else {
- atexit(st_flush_trace_buffer);
- trace_backend_init_events(events);
- st_set_trace_file(file);
+ return false;
}
+ atexit(st_flush_trace_buffer);
+ trace_backend_init_events(events);
+ st_set_trace_file(file);
return true;
}
diff --git a/ui/keymaps.c b/ui/keymaps.c
index 81003bb5ca..f54a11437b 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -146,7 +146,7 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
if (rest && strstr(rest, "addupper")) {
char *c;
for (c = line; *c; c++)
- *c = toupper(*c);
+ *c = qemu_toupper(*c);
keysym = get_keysym(table, line);
if (keysym)
add_keysym(line, keysym, keycode | SCANCODE_SHIFT, k);
diff --git a/ui/sdl.c b/ui/sdl.c
index c7aaedf32d..8cafc44e71 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -409,7 +409,7 @@ static void sdl_update_caption(void)
char icon_title[1024];
const char *status = "";
- if (!vm_running)
+ if (!runstate_is_running())
status = " [Stopped]";
else if (gui_grab) {
if (alt_grab)
@@ -853,8 +853,8 @@ static void sdl_refresh(DisplayState *ds)
{
SDL_Event ev1, *ev = &ev1;
- if (last_vm_running != vm_running) {
- last_vm_running = vm_running;
+ if (last_vm_running != runstate_is_running()) {
+ last_vm_running = runstate_is_running();
sdl_update_caption();
}
diff --git a/ui/spice-display.c b/ui/spice-display.c
index e38536114b..6c302a3909 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -15,8 +15,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <pthread.h>
-
#include "qemu-common.h"
#include "qemu-spice.h"
#include "qemu-timer.h"
@@ -255,7 +253,8 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
}
-void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
+void qemu_spice_vm_change_state_handler(void *opaque, int running,
+ RunState state)
{
SimpleSpiceDisplay *ssd = opaque;
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 1388641370..5e52df99be 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -22,6 +22,7 @@
#include "qemu-thread.h"
#include "console.h"
#include "pflib.h"
+#include "sysemu.h"
#define NUM_MEMSLOTS 8
#define MEMSLOT_GENERATION_BITS 8
@@ -88,7 +89,8 @@ void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *upda
void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
-void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
+void qemu_spice_vm_change_state_handler(void *opaque, int running,
+ RunState state);
void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
diff --git a/vl.c b/vl.c
index 0c2fc3fb3d..bd4a5ce8a2 100644
--- a/vl.c
+++ b/vl.c
@@ -185,9 +185,7 @@ int mem_prealloc = 0; /* force preallocation of physical target memory */
#endif
int nb_nics;
NICInfo nd_table[MAX_NICS];
-int vm_running;
int autostart;
-int incoming_expected; /* Started with -incoming and waiting for incoming */
static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
QEMUClock *rtc_clock;
@@ -323,6 +321,120 @@ static int default_driver_check(QemuOpts *opts, void *opaque)
}
/***********************************************************/
+/* QEMU state */
+
+static RunState current_run_state = RSTATE_NO_STATE;
+
+typedef struct {
+ RunState from;
+ RunState to;
+} RunStateTransition;
+
+static const RunStateTransition runstate_transitions_def[] = {
+ /* from -> to */
+ { RSTATE_NO_STATE, RSTATE_RUNNING },
+ { RSTATE_NO_STATE, RSTATE_IN_MIGRATE },
+ { RSTATE_NO_STATE, RSTATE_PRE_LAUNCH },
+
+ { RSTATE_DEBUG, RSTATE_RUNNING },
+
+ { RSTATE_IN_MIGRATE, RSTATE_RUNNING },
+ { RSTATE_IN_MIGRATE, RSTATE_PRE_LAUNCH },
+
+ { RSTATE_PANICKED, RSTATE_PAUSED },
+
+ { RSTATE_IO_ERROR, RSTATE_RUNNING },
+
+ { RSTATE_PAUSED, RSTATE_RUNNING },
+
+ { RSTATE_POST_MIGRATE, RSTATE_RUNNING },
+
+ { RSTATE_PRE_LAUNCH, RSTATE_RUNNING },
+ { RSTATE_PRE_LAUNCH, RSTATE_POST_MIGRATE },
+
+ { RSTATE_PRE_MIGRATE, RSTATE_RUNNING },
+ { RSTATE_PRE_MIGRATE, RSTATE_POST_MIGRATE },
+
+ { RSTATE_RESTORE, RSTATE_RUNNING },
+
+ { RSTATE_RUNNING, RSTATE_DEBUG },
+ { RSTATE_RUNNING, RSTATE_PANICKED },
+ { RSTATE_RUNNING, RSTATE_IO_ERROR },
+ { RSTATE_RUNNING, RSTATE_PAUSED },
+ { RSTATE_RUNNING, RSTATE_PRE_MIGRATE },
+ { RSTATE_RUNNING, RSTATE_RESTORE },
+ { RSTATE_RUNNING, RSTATE_SAVEVM },
+ { RSTATE_RUNNING, RSTATE_SHUTDOWN },
+ { RSTATE_RUNNING, RSTATE_WATCHDOG },
+
+ { RSTATE_SAVEVM, RSTATE_RUNNING },
+
+ { RSTATE_SHUTDOWN, RSTATE_PAUSED },
+
+ { RSTATE_WATCHDOG, RSTATE_RUNNING },
+
+ { RSTATE_MAX, RSTATE_MAX },
+};
+
+static bool runstate_valid_transitions[RSTATE_MAX][RSTATE_MAX];
+
+static const char *const runstate_name_tbl[RSTATE_MAX] = {
+ [RSTATE_DEBUG] = "debug",
+ [RSTATE_IN_MIGRATE] = "incoming-migration",
+ [RSTATE_PANICKED] = "internal-error",
+ [RSTATE_IO_ERROR] = "io-error",
+ [RSTATE_PAUSED] = "paused",
+ [RSTATE_POST_MIGRATE] = "post-migrate",
+ [RSTATE_PRE_LAUNCH] = "prelaunch",
+ [RSTATE_PRE_MIGRATE] = "finish-migrate",
+ [RSTATE_RESTORE] = "restore-vm",
+ [RSTATE_RUNNING] = "running",
+ [RSTATE_SAVEVM] = "save-vm",
+ [RSTATE_SHUTDOWN] = "shutdown",
+ [RSTATE_WATCHDOG] = "watchdog",
+};
+
+bool runstate_check(RunState state)
+{
+ return current_run_state == state;
+}
+
+void runstate_init(void)
+{
+ const RunStateTransition *p;
+
+ memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
+
+ for (p = &runstate_transitions_def[0]; p->from != RSTATE_MAX; p++) {
+ runstate_valid_transitions[p->from][p->to] = true;
+ }
+}
+
+/* This function will abort() on invalid state transitions */
+void runstate_set(RunState new_state)
+{
+ if (new_state >= RSTATE_MAX ||
+ !runstate_valid_transitions[current_run_state][new_state]) {
+ fprintf(stderr, "invalid runstate transition\n");
+ abort();
+ }
+
+ current_run_state = new_state;
+}
+
+const char *runstate_as_string(void)
+{
+ assert(current_run_state > RSTATE_NO_STATE &&
+ current_run_state < RSTATE_MAX);
+ return runstate_name_tbl[current_run_state];
+}
+
+int runstate_is_running(void)
+{
+ return runstate_check(RSTATE_RUNNING);
+}
+
+/***********************************************************/
/* real time host monotonic timer */
/***********************************************************/
@@ -1145,23 +1257,23 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
g_free (e);
}
-void vm_state_notify(int running, int reason)
+void vm_state_notify(int running, RunState state)
{
VMChangeStateEntry *e;
- trace_vm_state_notify(running, reason);
+ trace_vm_state_notify(running, state);
for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
- e->cb(e->opaque, running, reason);
+ e->cb(e->opaque, running, state);
}
}
void vm_start(void)
{
- if (!vm_running) {
+ if (!runstate_is_running()) {
cpu_enable_ticks();
- vm_running = 1;
- vm_state_notify(1, 0);
+ runstate_set(RSTATE_RUNNING);
+ vm_state_notify(1, RSTATE_RUNNING);
resume_all_vcpus();
monitor_protocol_event(QEVENT_RESUME, NULL);
}
@@ -1182,7 +1294,7 @@ static int shutdown_requested, shutdown_signal = -1;
static pid_t shutdown_pid;
static int powerdown_requested;
static int debug_requested;
-static int vmstop_requested;
+static RunState vmstop_requested = RSTATE_NO_STATE;
int qemu_shutdown_requested_get(void)
{
@@ -1238,11 +1350,11 @@ static int qemu_debug_requested(void)
return r;
}
-static int qemu_vmstop_requested(void)
+static RunState qemu_vmstop_requested(void)
{
- int r = vmstop_requested;
- vmstop_requested = 0;
- return r;
+ RunState s = vmstop_requested;
+ vmstop_requested = RSTATE_NO_STATE;
+ return s;
}
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
@@ -1318,9 +1430,9 @@ void qemu_system_debug_request(void)
qemu_notify_event();
}
-void qemu_system_vmstop_request(int reason)
+void qemu_system_vmstop_request(RunState state)
{
- vmstop_requested = reason;
+ vmstop_requested = state;
qemu_notify_event();
}
@@ -1470,13 +1582,13 @@ static void main_loop(void)
#endif
if (qemu_debug_requested()) {
- vm_stop(VMSTOP_DEBUG);
+ vm_stop(RSTATE_DEBUG);
}
if (qemu_shutdown_requested()) {
qemu_kill_report();
monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
if (no_shutdown) {
- vm_stop(VMSTOP_SHUTDOWN);
+ vm_stop(RSTATE_SHUTDOWN);
} else
break;
}
@@ -1485,6 +1597,10 @@ static void main_loop(void)
cpu_synchronize_all_states();
qemu_system_reset(VMRESET_REPORT);
resume_all_vcpus();
+ if (runstate_check(RSTATE_PANICKED) ||
+ runstate_check(RSTATE_SHUTDOWN)) {
+ runstate_set(RSTATE_PAUSED);
+ }
}
if (qemu_powerdown_requested()) {
monitor_protocol_event(QEVENT_POWERDOWN, NULL);
@@ -2203,6 +2319,8 @@ int main(int argc, char **argv, char **envp)
g_mem_set_vtable(&mem_trace);
g_thread_init(NULL);
+ runstate_init();
+
init_clocks();
qemu_cache_utils_init(envp);
@@ -2953,7 +3071,6 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_incoming:
incoming = optarg;
- incoming_expected = true;
break;
case QEMU_OPTION_nodefaults:
default_serial = 0;
@@ -3439,6 +3556,7 @@ int main(int argc, char **argv, char **envp)
}
if (incoming) {
+ runstate_set(RSTATE_IN_MIGRATE);
int ret = qemu_start_incoming_migration(incoming);
if (ret < 0) {
fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",
@@ -3447,6 +3565,8 @@ int main(int argc, char **argv, char **envp)
}
} else if (autostart) {
vm_start();
+ } else {
+ runstate_set(RSTATE_PRE_LAUNCH);
}
os_setup_post();
diff --git a/xen-all.c b/xen-all.c
index 1bc2c3c8de..b5e28abd40 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -736,7 +736,7 @@ static void cpu_handle_ioreq(void *opaque)
* guest resumes and does a hlt with interrupts disabled which
* causes Xen to powerdown the domain.
*/
- if (vm_running) {
+ if (runstate_is_running()) {
if (qemu_shutdown_requested_get()) {
destroy_hvm_domain();
}
@@ -846,7 +846,8 @@ static void xen_main_loop_prepare(XenIOState *state)
/* Initialise Xen */
-static void xen_change_state_handler(void *opaque, int running, int reason)
+static void xen_change_state_handler(void *opaque, int running,
+ RunState state)
{
if (running) {
/* record state running */
@@ -854,11 +855,12 @@ static void xen_change_state_handler(void *opaque, int running, int reason)
}
}
-static void xen_hvm_change_state_handler(void *opaque, int running, int reason)
+static void xen_hvm_change_state_handler(void *opaque, int running,
+ RunState rstate)
{
- XenIOState *state = opaque;
+ XenIOState *xstate = opaque;
if (running) {
- xen_main_loop_prepare(state);
+ xen_main_loop_prepare(xstate);
}
}