summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/virtio-9p-debug.c (renamed from hw/virtio-9p-debug.c)0
-rw-r--r--hw/9pfs/virtio-9p-debug.h (renamed from hw/virtio-9p-debug.h)0
-rw-r--r--hw/9pfs/virtio-9p-local.c (renamed from hw/virtio-9p-local.c)2
-rw-r--r--hw/9pfs/virtio-9p-posix-acl.c (renamed from hw/virtio-9p-posix-acl.c)17
-rw-r--r--hw/9pfs/virtio-9p-xattr-user.c (renamed from hw/virtio-9p-xattr-user.c)2
-rw-r--r--hw/9pfs/virtio-9p-xattr.c (renamed from hw/virtio-9p-xattr.c)2
-rw-r--r--hw/9pfs/virtio-9p-xattr.h (renamed from hw/virtio-9p-xattr.h)0
-rw-r--r--hw/9pfs/virtio-9p.c (renamed from hw/virtio-9p.c)14
-rw-r--r--hw/9pfs/virtio-9p.h (renamed from hw/virtio-9p.h)4
-rw-r--r--hw/adb.c83
-rw-r--r--hw/ads7846.c41
-rw-r--r--hw/an5206.c1
-rw-r--r--hw/arm_boot.c2
-rw-r--r--hw/arm_timer.c66
-rw-r--r--hw/armv7m.c1
-rw-r--r--hw/armv7m_nvic.c39
-rw-r--r--hw/axis_dev88.c1
-rw-r--r--hw/blizzard.c1
-rw-r--r--hw/bt-hci-csr.c1
-rw-r--r--hw/collie.c69
-rw-r--r--hw/cris-boot.c1
-rw-r--r--hw/cuda.c116
-rw-r--r--hw/dummy_m68k.c1
-rw-r--r--hw/e1000.c2
-rw-r--r--hw/eepro100.c2
-rw-r--r--hw/empty_slot.c21
-rw-r--r--hw/etraxfs.c1
-rw-r--r--hw/file-op-9p.h107
-rw-r--r--hw/flash.h4
-rw-r--r--hw/grlib_apbuart.c2
-rw-r--r--hw/grlib_gptimer.c29
-rw-r--r--hw/grlib_irqmp.c4
-rw-r--r--hw/gumstix.c1
-rw-r--r--hw/heathrow_pic.c62
-rw-r--r--hw/hw.h17
-rw-r--r--hw/ide/atapi.c1138
-rw-r--r--hw/ide/core.c1067
-rw-r--r--hw/ide/ich.c1
-rw-r--r--hw/ide/internal.h10
-rw-r--r--hw/ide/isa.c1
-rw-r--r--hw/ide/macio.c1
-rw-r--r--hw/ide/microdrive.c1
-rw-r--r--hw/ide/mmio.c1
-rw-r--r--hw/ide/pci.c1
-rw-r--r--hw/integratorcp.c1
-rw-r--r--hw/ioapic.c5
-rw-r--r--hw/isa-bus.c1
-rw-r--r--hw/kvmclock.c6
-rw-r--r--hw/lm32_boards.c1
-rw-r--r--hw/m48t59.c36
-rw-r--r--hw/mac_dbdma.c83
-rw-r--r--hw/mac_nvram.c32
-rw-r--r--hw/mainstone.c1
-rw-r--r--hw/max111x.c51
-rw-r--r--hw/milkymist-hw.h20
-rw-r--r--hw/milkymist-minimac2.c (renamed from hw/milkymist-minimac.c)297
-rw-r--r--hw/milkymist-sysctl.c26
-rw-r--r--hw/milkymist-vgafb.c3
-rw-r--r--hw/milkymist.c2
-rw-r--r--hw/mipsnet.c53
-rw-r--r--hw/nand.c79
-rw-r--r--hw/ne2000.c2
-rw-r--r--hw/omap_sx1.c1
-rw-r--r--hw/pcie.c3
-rw-r--r--hw/pcnet-pci.c2
-rw-r--r--hw/pflash_cfi02.c12
-rw-r--r--hw/piix4.c44
-rw-r--r--hw/pl011.c76
-rw-r--r--hw/pl022.c84
-rw-r--r--hw/ppc440_bamboo.c1
-rw-r--r--hw/ppc4xx_devs.c1
-rw-r--r--hw/ppc4xx_pci.c80
-rw-r--r--hw/ppce500_pci.c87
-rw-r--r--hw/ptimer.c59
-rw-r--r--hw/pxa2xx.c158
-rw-r--r--hw/pxa2xx_keypad.c53
-rw-r--r--hw/pxa2xx_lcd.c138
-rw-r--r--hw/qdev-properties.c4
-rw-r--r--hw/rtl8139.c440
-rw-r--r--hw/s390-virtio-bus.c10
-rw-r--r--hw/s390-virtio.c21
-rw-r--r--hw/stellaris.c324
-rw-r--r--hw/stellaris_input.c50
-rw-r--r--hw/strongarm.c1598
-rw-r--r--hw/strongarm.h64
-rw-r--r--hw/syborg.c1
-rw-r--r--hw/syborg_keyboard.c57
-rw-r--r--hw/syborg_pointer.c73
-rw-r--r--hw/syborg_rtc.c34
-rw-r--r--hw/syborg_serial.c60
-rw-r--r--hw/syborg_timer.c46
-rw-r--r--hw/syborg_virtio.c1
-rw-r--r--hw/sysbus.c1
-rw-r--r--hw/tc58128.c1
-rw-r--r--hw/tosa.c1
-rw-r--r--hw/twl92230.c1
-rw-r--r--hw/usb-hid.c2
-rw-r--r--hw/usb-msd.c4
-rw-r--r--hw/virtio-balloon.c1
-rw-r--r--hw/virtio-console.c18
-rw-r--r--hw/virtio-pci.c2
-rw-r--r--hw/virtio-serial-bus.c23
-rw-r--r--hw/virtio.c1
-rw-r--r--hw/vmport.c1
-rw-r--r--hw/xen_console.c1
-rw-r--r--hw/xen_domainbuild.c1
-rw-r--r--hw/xen_machine_pv.c1
-rw-r--r--hw/xenfb.c1
-rw-r--r--hw/xilinx_timer.c1
109 files changed, 4280 insertions, 2999 deletions
diff --git a/hw/virtio-9p-debug.c b/hw/9pfs/virtio-9p-debug.c
index 6b18842fd..6b18842fd 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/9pfs/virtio-9p-debug.c
diff --git a/hw/virtio-9p-debug.h b/hw/9pfs/virtio-9p-debug.h
index d9a249118..d9a249118 100644
--- a/hw/virtio-9p-debug.h
+++ b/hw/9pfs/virtio-9p-debug.h
diff --git a/hw/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index a8e7525bf..0a015de9a 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -370,7 +370,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
return fd;
}
/* Write the oldpath (target) to the file. */
- oldpath_size = strlen(oldpath) + 1;
+ oldpath_size = strlen(oldpath);
do {
write_size = write(fd, (void *)oldpath, oldpath_size);
} while (write_size == -1 && errno == EINTR);
diff --git a/hw/virtio-9p-posix-acl.c b/hw/9pfs/virtio-9p-posix-acl.c
index 3978d0cf7..575abe86b 100644
--- a/hw/virtio-9p-posix-acl.c
+++ b/hw/9pfs/virtio-9p-posix-acl.c
@@ -15,7 +15,7 @@
#include <attr/xattr.h>
#include "virtio.h"
#include "virtio-9p.h"
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
#include "virtio-9p-xattr.h"
#define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
@@ -60,7 +60,7 @@ static int mp_pacl_removexattr(FsContext *ctx,
ret = lremovexattr(rpath(ctx, path), MAP_ACL_ACCESS);
if (ret == -1 && errno == ENODATA) {
/*
- * We don't get ENODATA error when trying to remote a
+ * We don't get ENODATA error when trying to remove a
* posix acl that is not present. So don't throw the error
* even in case of mapped security model
*/
@@ -103,7 +103,18 @@ static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
static int mp_dacl_removexattr(FsContext *ctx,
const char *path, const char *name)
{
- return lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT);
+ int ret;
+ ret = lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT);
+ if (ret == -1 && errno == ENODATA) {
+ /*
+ * We don't get ENODATA error when trying to remove a
+ * posix acl that is not present. So don't throw the error
+ * even in case of mapped security model
+ */
+ errno = 0;
+ ret = 0;
+ }
+ return ret;
}
diff --git a/hw/virtio-9p-xattr-user.c b/hw/9pfs/virtio-9p-xattr-user.c
index faa02a191..bba13ce64 100644
--- a/hw/virtio-9p-xattr-user.c
+++ b/hw/9pfs/virtio-9p-xattr-user.c
@@ -14,7 +14,7 @@
#include <sys/types.h>
#include "virtio.h"
#include "virtio-9p.h"
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
#include "virtio-9p-xattr.h"
diff --git a/hw/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c
index 1aab081de..03c3d3f6b 100644
--- a/hw/virtio-9p-xattr.c
+++ b/hw/9pfs/virtio-9p-xattr.c
@@ -13,7 +13,7 @@
#include "virtio.h"
#include "virtio-9p.h"
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
#include "virtio-9p-xattr.h"
diff --git a/hw/virtio-9p-xattr.h b/hw/9pfs/virtio-9p-xattr.h
index 2bbae2dcb..2bbae2dcb 100644
--- a/hw/virtio-9p-xattr.h
+++ b/hw/9pfs/virtio-9p-xattr.h
diff --git a/hw/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 7e2953567..b5fc52b3e 100644
--- a/hw/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -596,7 +596,10 @@ static V9fsPDU *alloc_pdu(V9fsState *s)
static void free_pdu(V9fsState *s, V9fsPDU *pdu)
{
if (pdu) {
- QLIST_INSERT_HEAD(&s->free_list, pdu, next);
+ if (debug_9p_pdu) {
+ pprint_pdu(pdu);
+ }
+ QLIST_INSERT_HEAD(&s->free_list, pdu, next);
}
}
@@ -1479,7 +1482,7 @@ static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
{
complete_pdu(s, vs->pdu, err);
- if (vs->nwnames) {
+ if (vs->nwnames && vs->nwnames <= P9_MAXWELEM) {
for (vs->name_idx = 0; vs->name_idx < vs->nwnames; vs->name_idx++) {
v9fs_string_free(&vs->wnames[vs->name_idx]);
}
@@ -1575,7 +1578,7 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
&newfid, &vs->nwnames);
- if (vs->nwnames) {
+ if (vs->nwnames && vs->nwnames <= P9_MAXWELEM) {
vs->wnames = qemu_mallocz(sizeof(vs->wnames[0]) * vs->nwnames);
vs->qids = qemu_mallocz(sizeof(vs->qids[0]) * vs->nwnames);
@@ -1584,6 +1587,9 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "s",
&vs->wnames[i]);
}
+ } else if (vs->nwnames > P9_MAXWELEM) {
+ err = -EINVAL;
+ goto out;
}
vs->fidp = lookup_fid(s, fid);
@@ -1768,7 +1774,7 @@ static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
v9fs_string_copy(&vs->fidp->path, &vs->fullname);
stat_to_qid(&vs->stbuf, &vs->qid);
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid,
- &vs->iounit);
+ vs->iounit);
err = vs->offset;
} else {
vs->fidp->fid_type = P9_FID_NONE;
diff --git a/hw/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 2ae4ce718..622928fce 100644
--- a/hw/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -6,7 +6,7 @@
#include <sys/time.h>
#include <utime.h>
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
/* The feature bitmap for virtio 9P */
/* The mount point is specified in a config variable */
@@ -282,7 +282,7 @@ typedef struct V9fsStatStateDotl {
typedef struct V9fsWalkState {
V9fsPDU *pdu;
size_t offset;
- int16_t nwnames;
+ uint16_t nwnames;
int name_idx;
V9fsQID *qids;
V9fsFidState *fidp;
diff --git a/hw/adb.c b/hw/adb.c
index 99b30f6bc..7499cdcef 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -261,30 +261,19 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
return olen;
}
-static void adb_kbd_save(QEMUFile *f, void *opaque)
-{
- KBDState *s = (KBDState *)opaque;
-
- qemu_put_buffer(f, s->data, sizeof(s->data));
- qemu_put_sbe32s(f, &s->rptr);
- qemu_put_sbe32s(f, &s->wptr);
- qemu_put_sbe32s(f, &s->count);
-}
-
-static int adb_kbd_load(QEMUFile *f, void *opaque, int version_id)
-{
- KBDState *s = (KBDState *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_buffer(f, s->data, sizeof(s->data));
- qemu_get_sbe32s(f, &s->rptr);
- qemu_get_sbe32s(f, &s->wptr);
- qemu_get_sbe32s(f, &s->count);
-
- return 0;
-}
+static const VMStateDescription vmstate_adb_kbd = {
+ .name = "adb_kbd",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_BUFFER(data, KBDState),
+ VMSTATE_INT32(rptr, KBDState),
+ VMSTATE_INT32(wptr, KBDState),
+ VMSTATE_INT32(count, KBDState),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int adb_kbd_reset(ADBDevice *d)
{
@@ -305,8 +294,7 @@ void adb_kbd_init(ADBBusState *bus)
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
- register_savevm(NULL, "adb_kbd", -1, 1, adb_kbd_save,
- adb_kbd_load, s);
+ vmstate_register(NULL, -1, &vmstate_adb_kbd, s);
}
/***************************************************************/
@@ -439,32 +427,20 @@ static int adb_mouse_reset(ADBDevice *d)
return 0;
}
-static void adb_mouse_save(QEMUFile *f, void *opaque)
-{
- MouseState *s = (MouseState *)opaque;
-
- qemu_put_sbe32s(f, &s->buttons_state);
- qemu_put_sbe32s(f, &s->last_buttons_state);
- qemu_put_sbe32s(f, &s->dx);
- qemu_put_sbe32s(f, &s->dy);
- qemu_put_sbe32s(f, &s->dz);
-}
-
-static int adb_mouse_load(QEMUFile *f, void *opaque, int version_id)
-{
- MouseState *s = (MouseState *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_sbe32s(f, &s->buttons_state);
- qemu_get_sbe32s(f, &s->last_buttons_state);
- qemu_get_sbe32s(f, &s->dx);
- qemu_get_sbe32s(f, &s->dy);
- qemu_get_sbe32s(f, &s->dz);
-
- return 0;
-}
+static const VMStateDescription vmstate_adb_mouse = {
+ .name = "adb_mouse",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(buttons_state, MouseState),
+ VMSTATE_INT32(last_buttons_state, MouseState),
+ VMSTATE_INT32(dx, MouseState),
+ VMSTATE_INT32(dy, MouseState),
+ VMSTATE_INT32(dz, MouseState),
+ VMSTATE_END_OF_LIST()
+ }
+};
void adb_mouse_init(ADBBusState *bus)
{
@@ -475,6 +451,5 @@ void adb_mouse_init(ADBBusState *bus)
d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
adb_mouse_reset, s);
qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
- register_savevm(NULL, "adb_mouse", -1, 1, adb_mouse_save,
- adb_mouse_load, s);
+ vmstate_register(NULL, -1, &vmstate_adb_mouse, s);
}
diff --git a/hw/ads7846.c b/hw/ads7846.c
index b3bbeaf68..9c58a5f59 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -105,35 +105,30 @@ static void ads7846_ts_event(void *opaque,
}
}
-static void ads7846_save(QEMUFile *f, void *opaque)
+static int ads7856_post_load(void *opaque, int version_id)
{
- ADS7846State *s = (ADS7846State *) opaque;
- int i;
-
- for (i = 0; i < 8; i ++)
- qemu_put_be32(f, s->input[i]);
- qemu_put_be32(f, s->noise);
- qemu_put_be32(f, s->cycle);
- qemu_put_be32(f, s->output);
-}
-
-static int ads7846_load(QEMUFile *f, void *opaque, int version_id)
-{
- ADS7846State *s = (ADS7846State *) opaque;
- int i;
-
- for (i = 0; i < 8; i ++)
- s->input[i] = qemu_get_be32(f);
- s->noise = qemu_get_be32(f);
- s->cycle = qemu_get_be32(f);
- s->output = qemu_get_be32(f);
+ ADS7846State *s = opaque;
s->pressure = 0;
ads7846_int_update(s);
-
return 0;
}
+static const VMStateDescription vmstate_ads7846 = {
+ .name = "ads7846",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = ads7856_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
+ VMSTATE_INT32(noise, ADS7846State),
+ VMSTATE_INT32(cycle, ADS7846State),
+ VMSTATE_INT32(output, ADS7846State),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static int ads7846_init(SSISlave *dev)
{
ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
@@ -151,7 +146,7 @@ static int ads7846_init(SSISlave *dev)
ads7846_int_update(s);
- register_savevm(NULL, "ads7846", -1, 0, ads7846_save, ads7846_load, s);
+ vmstate_register(NULL, -1, &vmstate_ads7846, s);
return 0;
}
diff --git a/hw/an5206.c b/hw/an5206.c
index b9f19a994..42a0163fb 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -9,7 +9,6 @@
#include "hw.h"
#include "pc.h"
#include "mcf.h"
-#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 41e99d133..bfac982e6 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -15,7 +15,7 @@
#define KERNEL_ARGS_ADDR 0x100
#define KERNEL_LOAD_ADDR 0x00010000
-#define INITRD_LOAD_ADDR 0x00800000
+#define INITRD_LOAD_ADDR 0x00d00000
/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
static uint32_t bootloader[] = {
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 82f05dec8..dac9e7075 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -140,28 +140,19 @@ static void arm_timer_tick(void *opaque)
arm_timer_update(s);
}
-static void arm_timer_save(QEMUFile *f, void *opaque)
-{
- arm_timer_state *s = (arm_timer_state *)opaque;
- qemu_put_be32(f, s->control);
- qemu_put_be32(f, s->limit);
- qemu_put_be32(f, s->int_level);
- qemu_put_ptimer(f, s->timer);
-}
-
-static int arm_timer_load(QEMUFile *f, void *opaque, int version_id)
-{
- arm_timer_state *s = (arm_timer_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->control = qemu_get_be32(f);
- s->limit = qemu_get_be32(f);
- s->int_level = qemu_get_be32(f);
- qemu_get_ptimer(f, s->timer);
- return 0;
-}
+static const VMStateDescription vmstate_arm_timer = {
+ .name = "arm_timer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(control, arm_timer_state),
+ VMSTATE_UINT32(limit, arm_timer_state),
+ VMSTATE_INT32(int_level, arm_timer_state),
+ VMSTATE_PTIMER(timer, arm_timer_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
static arm_timer_state *arm_timer_init(uint32_t freq)
{
@@ -174,7 +165,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
bh = qemu_bh_new(arm_timer_tick, s);
s->timer = ptimer_init(bh);
- register_savevm(NULL, "arm_timer", -1, 1, arm_timer_save, arm_timer_load, s);
+ vmstate_register(NULL, -1, &vmstate_arm_timer, s);
return s;
}
@@ -235,24 +226,17 @@ static CPUWriteMemoryFunc * const sp804_writefn[] = {
sp804_write
};
-static void sp804_save(QEMUFile *f, void *opaque)
-{
- sp804_state *s = (sp804_state *)opaque;
- qemu_put_be32(f, s->level[0]);
- qemu_put_be32(f, s->level[1]);
-}
-
-static int sp804_load(QEMUFile *f, void *opaque, int version_id)
-{
- sp804_state *s = (sp804_state *)opaque;
- if (version_id != 1)
- return -EINVAL;
-
- s->level[0] = qemu_get_be32(f);
- s->level[1] = qemu_get_be32(f);
- return 0;
-}
+static const VMStateDescription vmstate_sp804 = {
+ .name = "sp804",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32_ARRAY(level, sp804_state, 2),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int sp804_init(SysBusDevice *dev)
{
@@ -271,7 +255,7 @@ static int sp804_init(SysBusDevice *dev)
iomemtype = cpu_register_io_memory(sp804_readfn,
sp804_writefn, s, DEVICE_NATIVE_ENDIAN);
sysbus_init_mmio(dev, 0x1000, iomemtype);
- register_savevm(&dev->qdev, "sp804", -1, 1, sp804_save, sp804_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_sp804, s);
return 0;
}
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 304cd34bc..72d010a63 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -9,7 +9,6 @@
#include "sysbus.h"
#include "arm-misc.h"
-#include "sysemu.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index ffe16b8a6..d06eec9b3 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -365,30 +365,19 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value)
}
}
-static void nvic_save(QEMUFile *f, void *opaque)
-{
- nvic_state *s = (nvic_state *)opaque;
-
- qemu_put_be32(f, s->systick.control);
- qemu_put_be32(f, s->systick.reload);
- qemu_put_be64(f, s->systick.tick);
- qemu_put_timer(f, s->systick.timer);
-}
-
-static int nvic_load(QEMUFile *f, void *opaque, int version_id)
-{
- nvic_state *s = (nvic_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->systick.control = qemu_get_be32(f);
- s->systick.reload = qemu_get_be32(f);
- s->systick.tick = qemu_get_be64(f);
- qemu_get_timer(f, s->systick.timer);
-
- return 0;
-}
+static const VMStateDescription vmstate_nvic = {
+ .name = "armv7m_nvic",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(systick.control, nvic_state),
+ VMSTATE_UINT32(systick.reload, nvic_state),
+ VMSTATE_INT64(systick.tick, nvic_state),
+ VMSTATE_TIMER(systick.timer, nvic_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int armv7m_nvic_init(SysBusDevice *dev)
{
@@ -397,7 +386,7 @@ static int armv7m_nvic_init(SysBusDevice *dev)
gic_init(&s->gic);
cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype);
s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
- register_savevm(&dev->qdev, "armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_nvic, s);
return 0;
}
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 57b5e2f04..0e2135afd 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -26,7 +26,6 @@
#include "net.h"
#include "flash.h"
#include "boards.h"
-#include "sysemu.h"
#include "etraxfs.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 5f329ad13..c5245504a 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -19,7 +19,6 @@
*/
#include "qemu-common.h"
-#include "sysemu.h"
#include "console.h"
#include "devices.h"
#include "vga_int.h"
diff --git a/hw/bt-hci-csr.c b/hw/bt-hci-csr.c
index 65ffa37fd..d135ef479 100644
--- a/hw/bt-hci-csr.c
+++ b/hw/bt-hci-csr.c
@@ -22,7 +22,6 @@
#include "qemu-char.h"
#include "qemu-timer.h"
#include "irq.h"
-#include "sysemu.h"
#include "net.h"
#include "bt.h"
diff --git a/hw/collie.c b/hw/collie.c
new file mode 100644
index 000000000..156404d9f
--- /dev/null
+++ b/hw/collie.c
@@ -0,0 +1,69 @@
+/*
+ * SA-1110-based Sharp Zaurus SL-5500 platform.
+ *
+ * Copyright (C) 2011 Dmitry Eremin-Solenikov
+ *
+ * This code is licensed under GNU GPL v2.
+ */
+#include "hw.h"
+#include "sysbus.h"
+#include "boards.h"
+#include "devices.h"
+#include "strongarm.h"
+#include "arm-misc.h"
+#include "flash.h"
+#include "blockdev.h"
+
+static struct arm_boot_info collie_binfo = {
+ .loader_start = SA_SDCS0,
+ .ram_size = 0x20000000,
+};
+
+static void collie_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+ StrongARMState *s;
+ DriveInfo *dinfo;
+ ram_addr_t phys_flash;
+
+ if (!cpu_model) {
+ cpu_model = "sa1110";
+ }
+
+ s = sa1110_init(collie_binfo.ram_size, cpu_model);
+
+ phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
+ pflash_cfi01_register(SA_CS0, phys_flash,
+ dinfo ? dinfo->bdrv : NULL, (64 * 1024),
+ 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+
+ phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
+ dinfo = drive_get(IF_PFLASH, 0, 1);
+ pflash_cfi01_register(SA_CS1, phys_flash,
+ dinfo ? dinfo->bdrv : NULL, (64 * 1024),
+ 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+
+ sysbus_create_simple("scoop", 0x40800000, NULL);
+
+ collie_binfo.kernel_filename = kernel_filename;
+ collie_binfo.kernel_cmdline = kernel_cmdline;
+ collie_binfo.initrd_filename = initrd_filename;
+ collie_binfo.board_id = 0x208;
+ arm_load_kernel(s->env, &collie_binfo);
+}
+
+static QEMUMachine collie_machine = {
+ .name = "collie",
+ .desc = "Collie PDA (SA-1110)",
+ .init = collie_init,
+};
+
+static void collie_machine_init(void)
+{
+ qemu_register_machine(&collie_machine);
+}
+
+machine_init(collie_machine_init)
diff --git a/hw/cris-boot.c b/hw/cris-boot.c
index 2ef17f606..37894f8b5 100644
--- a/hw/cris-boot.c
+++ b/hw/cris-boot.c
@@ -23,7 +23,6 @@
*/
#include "hw.h"
-#include "sysemu.h"
#include "loader.h"
#include "elf.h"
#include "cris-boot.h"
diff --git a/hw/cuda.c b/hw/cuda.c
index 37aa3f47f..065c362ae 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -644,80 +644,56 @@ static CPUReadMemoryFunc * const cuda_read[] = {
&cuda_readl,
};
-static void cuda_save_timer(QEMUFile *f, CUDATimer *s)
+static bool cuda_timer_exist(void *opaque, int version_id)
{
- qemu_put_be16s(f, &s->latch);
- qemu_put_be16s(f, &s->counter_value);
- qemu_put_sbe64s(f, &s->load_time);
- qemu_put_sbe64s(f, &s->next_irq_time);
- if (s->timer)
- qemu_put_timer(f, s->timer);
-}
-
-static void cuda_save(QEMUFile *f, void *opaque)
-{
- CUDAState *s = (CUDAState *)opaque;
-
- qemu_put_ubyte(f, s->b);
- qemu_put_ubyte(f, s->a);
- qemu_put_ubyte(f, s->dirb);
- qemu_put_ubyte(f, s->dira);
- qemu_put_ubyte(f, s->sr);
- qemu_put_ubyte(f, s->acr);
- qemu_put_ubyte(f, s->pcr);
- qemu_put_ubyte(f, s->ifr);
- qemu_put_ubyte(f, s->ier);
- qemu_put_ubyte(f, s->anh);
- qemu_put_sbe32s(f, &s->data_in_size);
- qemu_put_sbe32s(f, &s->data_in_index);
- qemu_put_sbe32s(f, &s->data_out_index);
- qemu_put_ubyte(f, s->autopoll);
- qemu_put_buffer(f, s->data_in, sizeof(s->data_in));
- qemu_put_buffer(f, s->data_out, sizeof(s->data_out));
- qemu_put_be32s(f, &s->tick_offset);
- cuda_save_timer(f, &s->timers[0]);
- cuda_save_timer(f, &s->timers[1]);
-}
+ CUDATimer *s = opaque;
-static void cuda_load_timer(QEMUFile *f, CUDATimer *s)
-{
- qemu_get_be16s(f, &s->latch);
- qemu_get_be16s(f, &s->counter_value);
- qemu_get_sbe64s(f, &s->load_time);
- qemu_get_sbe64s(f, &s->next_irq_time);
- if (s->timer)
- qemu_get_timer(f, s->timer);
+ return s->timer != NULL;
}
-static int cuda_load(QEMUFile *f, void *opaque, int version_id)
-{
- CUDAState *s = (CUDAState *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->b = qemu_get_ubyte(f);
- s->a = qemu_get_ubyte(f);
- s->dirb = qemu_get_ubyte(f);
- s->dira = qemu_get_ubyte(f);
- s->sr = qemu_get_ubyte(f);
- s->acr = qemu_get_ubyte(f);
- s->pcr = qemu_get_ubyte(f);
- s->ifr = qemu_get_ubyte(f);
- s->ier = qemu_get_ubyte(f);
- s->anh = qemu_get_ubyte(f);
- qemu_get_sbe32s(f, &s->data_in_size);
- qemu_get_sbe32s(f, &s->data_in_index);
- qemu_get_sbe32s(f, &s->data_out_index);
- s->autopoll = qemu_get_ubyte(f);
- qemu_get_buffer(f, s->data_in, sizeof(s->data_in));
- qemu_get_buffer(f, s->data_out, sizeof(s->data_out));
- qemu_get_be32s(f, &s->tick_offset);
- cuda_load_timer(f, &s->timers[0]);
- cuda_load_timer(f, &s->timers[1]);
+static const VMStateDescription vmstate_cuda_timer = {
+ .name = "cuda_timer",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT16(latch, CUDATimer),
+ VMSTATE_UINT16(counter_value, CUDATimer),
+ VMSTATE_INT64(load_time, CUDATimer),
+ VMSTATE_INT64(next_irq_time, CUDATimer),
+ VMSTATE_TIMER_TEST(timer, CUDATimer, cuda_timer_exist),
+ VMSTATE_END_OF_LIST()
+ }
+};
- return 0;
-}
+static const VMStateDescription vmstate_cuda = {
+ .name = "cuda",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(a, CUDAState),
+ VMSTATE_UINT8(b, CUDAState),
+ VMSTATE_UINT8(dira, CUDAState),
+ VMSTATE_UINT8(dirb, CUDAState),
+ VMSTATE_UINT8(sr, CUDAState),
+ VMSTATE_UINT8(acr, CUDAState),
+ VMSTATE_UINT8(pcr, CUDAState),
+ VMSTATE_UINT8(ifr, CUDAState),
+ VMSTATE_UINT8(ier, CUDAState),
+ VMSTATE_UINT8(anh, CUDAState),
+ VMSTATE_INT32(data_in_size, CUDAState),
+ VMSTATE_INT32(data_in_index, CUDAState),
+ VMSTATE_INT32(data_out_index, CUDAState),
+ VMSTATE_UINT8(autopoll, CUDAState),
+ VMSTATE_BUFFER(data_in, CUDAState),
+ VMSTATE_BUFFER(data_out, CUDAState),
+ VMSTATE_UINT32(tick_offset, CUDAState),
+ VMSTATE_STRUCT_ARRAY(timers, CUDAState, 2, 1,
+ vmstate_cuda_timer, CUDATimer),
+ VMSTATE_END_OF_LIST()
+ }
+};
static void cuda_reset(void *opaque)
{
@@ -764,6 +740,6 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq)
s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
*cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s,
DEVICE_NATIVE_ENDIAN);
- register_savevm(NULL, "cuda", -1, 1, cuda_save, cuda_load, s);
+ vmstate_register(NULL, -1, &vmstate_cuda, s);
qemu_register_reset(cuda_reset, s);
}
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 61efb3989..cec1cc8e8 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -7,7 +7,6 @@
*/
#include "hw.h"
-#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
diff --git a/hw/e1000.c b/hw/e1000.c
index fe3e81261..f160bfc2a 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1220,7 +1220,7 @@ static PCIDeviceInfo e1000_info = {
.qdev.vmsd = &vmstate_e1000,
.init = pci_e1000_init,
.exit = pci_e1000_uninit,
- .romfile = "pxe-e1000.bin",
+ .romfile = "pxe-e1000.rom",
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(E1000State, conf),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/eepro100.c b/hw/eepro100.c
index edf48f61d..369ad7f84 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -2054,7 +2054,7 @@ static void eepro100_register_devices(void)
PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
/* We use the same rom file for all device ids.
QEMU fixes the device id during rom load. */
- pci_dev->romfile = "gpxe-eepro100-80861209.rom";
+ pci_dev->romfile = "pxe-eepro100.rom";
pci_dev->init = e100_nic_init;
pci_dev->exit = pci_nic_uninit;
pci_dev->qdev.props = e100_properties;
diff --git a/hw/empty_slot.c b/hw/empty_slot.c
index 664b8d9c4..da8adc4d0 100644
--- a/hw/empty_slot.c
+++ b/hw/empty_slot.c
@@ -53,18 +53,21 @@ static CPUWriteMemoryFunc * const empty_slot_write[3] = {
void empty_slot_init(target_phys_addr_t addr, uint64_t slot_size)
{
- DeviceState *dev;
- SysBusDevice *s;
- EmptySlot *e;
+ if (slot_size > 0) {
+ /* Only empty slots larger than 0 byte need handling. */
+ DeviceState *dev;
+ SysBusDevice *s;
+ EmptySlot *e;
- dev = qdev_create(NULL, "empty_slot");
- s = sysbus_from_qdev(dev);
- e = FROM_SYSBUS(EmptySlot, s);
- e->size = slot_size;
+ dev = qdev_create(NULL, "empty_slot");
+ s = sysbus_from_qdev(dev);
+ e = FROM_SYSBUS(EmptySlot, s);
+ e->size = slot_size;
- qdev_init_nofail(dev);
+ qdev_init_nofail(dev);
- sysbus_mmio_map(s, 0, addr);
+ sysbus_mmio_map(s, 0, addr);
+ }
}
static int empty_slot_init1(SysBusDevice *dev)
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 5ee5f979a..b84d74a11 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -24,7 +24,6 @@
#include "sysbus.h"
#include "boards.h"
-#include "sysemu.h"
#include "net.h"
#include "flash.h"
#include "etraxfs.h"
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
deleted file mode 100644
index 126e60e27..000000000
--- a/hw/file-op-9p.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Virtio 9p
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-#ifndef _FILEOP_H
-#define _FILEOP_H
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/time.h>
-#include <utime.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <sys/vfs.h>
-#define SM_LOCAL_MODE_BITS 0600
-#define SM_LOCAL_DIR_MODE_BITS 0700
-
-typedef enum
-{
- /*
- * Server will try to set uid/gid.
- * On failure ignore the error.
- */
- SM_NONE = 0,
- /*
- * uid/gid set on fileserver files
- */
- SM_PASSTHROUGH = 1,
- /*
- * uid/gid part of xattr
- */
- SM_MAPPED,
-} SecModel;
-
-typedef struct FsCred
-{
- uid_t fc_uid;
- gid_t fc_gid;
- mode_t fc_mode;
- dev_t fc_rdev;
-} FsCred;
-
-struct xattr_operations;
-
-typedef struct FsContext
-{
- char *fs_root;
- SecModel fs_sm;
- uid_t uid;
- struct xattr_operations **xops;
-} FsContext;
-
-void cred_init(FsCred *);
-
-typedef struct FileOperations
-{
- int (*lstat)(FsContext *, const char *, struct stat *);
- ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
- int (*chmod)(FsContext *, const char *, FsCred *);
- int (*chown)(FsContext *, const char *, FsCred *);
- int (*mknod)(FsContext *, const char *, FsCred *);
- int (*utimensat)(FsContext *, const char *, const struct timespec *);
- int (*remove)(FsContext *, const char *);
- int (*symlink)(FsContext *, const char *, const char *, FsCred *);
- int (*link)(FsContext *, const char *, const char *);
- int (*setuid)(FsContext *, uid_t);
- int (*close)(FsContext *, int);
- int (*closedir)(FsContext *, DIR *);
- DIR *(*opendir)(FsContext *, const char *);
- int (*open)(FsContext *, const char *, int);
- int (*open2)(FsContext *, const char *, int, FsCred *);
- void (*rewinddir)(FsContext *, DIR *);
- off_t (*telldir)(FsContext *, DIR *);
- struct dirent *(*readdir)(FsContext *, DIR *);
- void (*seekdir)(FsContext *, DIR *, off_t);
- ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t);
- ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t);
- int (*mkdir)(FsContext *, const char *, FsCred *);
- int (*fstat)(FsContext *, int, struct stat *);
- int (*rename)(FsContext *, const char *, const char *);
- int (*truncate)(FsContext *, const char *, off_t);
- int (*fsync)(FsContext *, int, int);
- int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf);
- ssize_t (*lgetxattr)(FsContext *, const char *,
- const char *, void *, size_t);
- ssize_t (*llistxattr)(FsContext *, const char *, void *, size_t);
- int (*lsetxattr)(FsContext *, const char *,
- const char *, void *, size_t, int);
- int (*lremovexattr)(FsContext *, const char *, const char *);
- void *opaque;
-} FileOperations;
-
-static inline const char *rpath(FsContext *ctx, const char *path)
-{
- /* FIXME: so wrong... */
- static char buffer[4096];
- snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
- return buffer;
-}
-#endif
diff --git a/hw/flash.h b/hw/flash.h
index d7d103e66..c22e1a922 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -21,8 +21,8 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
typedef struct NANDFlashState NANDFlashState;
NANDFlashState *nand_init(int manf_id, int chip_id);
void nand_done(NANDFlashState *s);
-void nand_setpins(NANDFlashState *s,
- int cle, int ale, int ce, int wp, int gnd);
+void nand_setpins(NANDFlashState *s, uint8_t cle, uint8_t ale,
+ uint8_t ce, uint8_t wp, uint8_t gnd);
void nand_getpins(NANDFlashState *s, int *rb);
void nand_setio(NANDFlashState *s, uint8_t value);
uint8_t nand_getio(NANDFlashState *s);
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 101b150aa..169a56eb1 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -133,7 +133,7 @@ grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
break;
}
- trace_grlib_apbuart_unknown_register("write", addr);
+ trace_grlib_apbuart_writel_unknown(addr, value);
}
static CPUReadMemoryFunc * const grlib_apbuart_read[] = {
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 596a9000a..99e90336b 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -165,15 +165,15 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
/* Unit registers */
switch (addr) {
case SCALER_OFFSET:
- trace_grlib_gptimer_readl(-1, "scaler:", unit->scaler);
+ trace_grlib_gptimer_readl(-1, addr, unit->scaler);
return unit->scaler;
case SCALER_RELOAD_OFFSET:
- trace_grlib_gptimer_readl(-1, "reload:", unit->reload);
+ trace_grlib_gptimer_readl(-1, addr, unit->reload);
return unit->reload;
case CONFIG_OFFSET:
- trace_grlib_gptimer_readl(-1, "config:", unit->config);
+ trace_grlib_gptimer_readl(-1, addr, unit->config);
return unit->config;
default:
@@ -189,17 +189,16 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
switch (timer_addr) {
case COUNTER_OFFSET:
value = ptimer_get_count(unit->timers[id].ptimer);
- trace_grlib_gptimer_readl(id, "counter value:", value);
+ trace_grlib_gptimer_readl(id, addr, value);
return value;
case COUNTER_RELOAD_OFFSET:
value = unit->timers[id].reload;
- trace_grlib_gptimer_readl(id, "reload value:", value);
+ trace_grlib_gptimer_readl(id, addr, value);
return value;
case CONFIG_OFFSET:
- trace_grlib_gptimer_readl(id, "scaler value:",
- unit->timers[id].config);
+ trace_grlib_gptimer_readl(id, addr, unit->timers[id].config);
return unit->timers[id].config;
default:
@@ -208,7 +207,7 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
}
- trace_grlib_gptimer_unknown_register("read", addr);
+ trace_grlib_gptimer_readl(-1, addr, 0);
return 0;
}
@@ -226,19 +225,19 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
case SCALER_OFFSET:
value &= 0xFFFF; /* clean up the value */
unit->scaler = value;
- trace_grlib_gptimer_writel(-1, "scaler:", unit->scaler);
+ trace_grlib_gptimer_writel(-1, addr, unit->scaler);
return;
case SCALER_RELOAD_OFFSET:
value &= 0xFFFF; /* clean up the value */
unit->reload = value;
- trace_grlib_gptimer_writel(-1, "reload:", unit->reload);
+ trace_grlib_gptimer_writel(-1, addr, unit->reload);
grlib_gptimer_set_scaler(unit, value);
return;
case CONFIG_OFFSET:
/* Read Only (disable timer freeze not supported) */
- trace_grlib_gptimer_writel(-1, "config (Read Only):", 0);
+ trace_grlib_gptimer_writel(-1, addr, 0);
return;
default:
@@ -253,18 +252,18 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
/* GPTimer registers */
switch (timer_addr) {
case COUNTER_OFFSET:
- trace_grlib_gptimer_writel(id, "counter:", value);
+ trace_grlib_gptimer_writel(id, addr, value);
unit->timers[id].counter = value;
grlib_gptimer_enable(&unit->timers[id]);
return;
case COUNTER_RELOAD_OFFSET:
- trace_grlib_gptimer_writel(id, "reload:", value);
+ trace_grlib_gptimer_writel(id, addr, value);
unit->timers[id].reload = value;
return;
case CONFIG_OFFSET:
- trace_grlib_gptimer_writel(id, "config:", value);
+ trace_grlib_gptimer_writel(id, addr, value);
if (value & GPTIMER_INT_PENDING) {
/* clear pending bit */
@@ -297,7 +296,7 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
}
- trace_grlib_gptimer_unknown_register("write", addr);
+ trace_grlib_gptimer_writel(-1, addr, value);
}
static CPUReadMemoryFunc * const grlib_gptimer_read[] = {
diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c
index f47c491a4..b8738fc04 100644
--- a/hw/grlib_irqmp.c
+++ b/hw/grlib_irqmp.c
@@ -220,7 +220,7 @@ static uint32_t grlib_irqmp_readl(void *opaque, target_phys_addr_t addr)
return state->extended[cpu];
}
- trace_grlib_irqmp_unknown_register("read", addr);
+ trace_grlib_irqmp_readl_unknown(addr);
return 0;
}
@@ -308,7 +308,7 @@ grlib_irqmp_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
return;
}
- trace_grlib_irqmp_unknown_register("write", addr);
+ trace_grlib_irqmp_writel_unknown(addr, value);
}
static CPUReadMemoryFunc * const grlib_irqmp_read[] = {
diff --git a/hw/gumstix.c b/hw/gumstix.c
index ee63f634c..853f7e1ee 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -35,7 +35,6 @@
#include "pxa.h"
#include "net.h"
#include "flash.h"
-#include "sysemu.h"
#include "devices.h"
#include "boards.h"
#include "blockdev.h"
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index b19b754b3..5fd71a0f7 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -159,42 +159,31 @@ static void heathrow_pic_set_irq(void *opaque, int num, int level)
heathrow_pic_update(s);
}
-static void heathrow_pic_save_one(QEMUFile *f, HeathrowPIC *s)
-{
- qemu_put_be32s(f, &s->events);
- qemu_put_be32s(f, &s->mask);
- qemu_put_be32s(f, &s->levels);
- qemu_put_be32s(f, &s->level_triggered);
-}
-
-static void heathrow_pic_save(QEMUFile *f, void *opaque)
-{
- HeathrowPICS *s = (HeathrowPICS *)opaque;
-
- heathrow_pic_save_one(f, &s->pics[0]);
- heathrow_pic_save_one(f, &s->pics[1]);
-}
-
-static void heathrow_pic_load_one(QEMUFile *f, HeathrowPIC *s)
-{
- qemu_get_be32s(f, &s->events);
- qemu_get_be32s(f, &s->mask);
- qemu_get_be32s(f, &s->levels);
- qemu_get_be32s(f, &s->level_triggered);
-}
-
-static int heathrow_pic_load(QEMUFile *f, void *opaque, int version_id)
-{
- HeathrowPICS *s = (HeathrowPICS *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- heathrow_pic_load_one(f, &s->pics[0]);
- heathrow_pic_load_one(f, &s->pics[1]);
+static const VMStateDescription vmstate_heathrow_pic_one = {
+ .name = "heathrow_pic_one",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(events, HeathrowPIC),
+ VMSTATE_UINT32(mask, HeathrowPIC),
+ VMSTATE_UINT32(levels, HeathrowPIC),
+ VMSTATE_UINT32(level_triggered, HeathrowPIC),
+ VMSTATE_END_OF_LIST()
+ }
+};
- return 0;
-}
+static const VMStateDescription vmstate_heathrow_pic = {
+ .name = "heathrow_pic",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT_ARRAY(pics, HeathrowPICS, 2, 1,
+ vmstate_heathrow_pic_one, HeathrowPIC),
+ VMSTATE_END_OF_LIST()
+ }
+};
static void heathrow_pic_reset_one(HeathrowPIC *s)
{
@@ -223,8 +212,7 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
*pmem_index = cpu_register_io_memory(pic_read, pic_write, s,
DEVICE_LITTLE_ENDIAN);
- register_savevm(NULL, "heathrow_pic", -1, 1, heathrow_pic_save,
- heathrow_pic_load, s);
+ vmstate_register(NULL, -1, &vmstate_heathrow_pic, s);
qemu_register_reset(heathrow_pic_reset, s);
return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
}
diff --git a/hw/hw.h b/hw/hw.h
index 87b0328b9..2ca601d49 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -693,6 +693,17 @@ extern const VMStateDescription vmstate_usb_device;
.offset = vmstate_offset_macaddr(_state, _field), \
}
+extern const VMStateDescription vmstate_ptimer;
+
+#define VMSTATE_PTIMER(_field, _state) { \
+ .name = (stringify(_field)), \
+ .version_id = (1), \
+ .vmsd = &vmstate_ptimer, \
+ .size = sizeof(ptimer_state *), \
+ .flags = VMS_STRUCT|VMS_POINTER, \
+ .offset = vmstate_offset_pointer(_state, _field, ptimer_state), \
+}
+
/* _f : field name
_f_n : num of elements field_name
_n : num of elements
@@ -797,12 +808,6 @@ extern const VMStateDescription vmstate_usb_device;
#define VMSTATE_TIMER_ARRAY(_f, _s, _n) \
VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *)
-#define VMSTATE_PTIMER_V(_f, _s, _v) \
- VMSTATE_POINTER(_f, _s, _v, vmstate_info_ptimer, ptimer_state *)
-
-#define VMSTATE_PTIMER(_f, _s) \
- VMSTATE_PTIMER_V(_f, _s, 0)
-
#define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v) \
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool)
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
new file mode 100644
index 000000000..fe2fb0b80
--- /dev/null
+++ b/hw/ide/atapi.c
@@ -0,0 +1,1138 @@
+/*
+ * QEMU ATAPI Emulation
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/ide/internal.h"
+#include "hw/scsi.h"
+
+static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
+
+static void padstr8(uint8_t *buf, int buf_size, const char *src)
+{
+ int i;
+ for(i = 0; i < buf_size; i++) {
+ if (*src)
+ buf[i] = *src++;
+ else
+ buf[i] = ' ';
+ }
+}
+
+static inline void cpu_to_ube16(uint8_t *buf, int val)
+{
+ buf[0] = val >> 8;
+ buf[1] = val & 0xff;
+}
+
+static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
+{
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val & 0xff;
+}
+
+static inline int ube16_to_cpu(const uint8_t *buf)
+{
+ return (buf[0] << 8) | buf[1];
+}
+
+static inline int ube32_to_cpu(const uint8_t *buf)
+{
+ return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+}
+
+static void lba_to_msf(uint8_t *buf, int lba)
+{
+ lba += 150;
+ buf[0] = (lba / 75) / 60;
+ buf[1] = (lba / 75) % 60;
+ buf[2] = lba % 75;
+}
+
+static inline int media_present(IDEState *s)
+{
+ return (s->nb_sectors > 0);
+}
+
+/* XXX: DVDs that could fit on a CD will be reported as a CD */
+static inline int media_is_dvd(IDEState *s)
+{
+ return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
+}
+
+static inline int media_is_cd(IDEState *s)
+{
+ return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
+}
+
+static void cd_data_to_raw(uint8_t *buf, int lba)
+{
+ /* sync bytes */
+ buf[0] = 0x00;
+ memset(buf + 1, 0xff, 10);
+ buf[11] = 0x00;
+ buf += 12;
+ /* MSF */
+ lba_to_msf(buf, lba);
+ buf[3] = 0x01; /* mode 1 data */
+ buf += 4;
+ /* data */
+ buf += 2048;
+ /* XXX: ECC not computed */
+ memset(buf, 0, 288);
+}
+
+static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
+ int sector_size)
+{
+ int ret;
+
+ switch(sector_size) {
+ case 2048:
+ ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
+ break;
+ case 2352:
+ ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
+ if (ret < 0)
+ return ret;
+ cd_data_to_raw(buf, lba);
+ break;
+ default:
+ ret = -EIO;
+ break;
+ }
+ return ret;
+}
+
+void ide_atapi_cmd_ok(IDEState *s)
+{
+ s->error = 0;
+ s->status = READY_STAT | SEEK_STAT;
+ s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+ ide_set_irq(s->bus);
+}
+
+void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
+{
+#ifdef DEBUG_IDE_ATAPI
+ printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
+#endif
+ s->error = sense_key << 4;
+ s->status = READY_STAT | ERR_STAT;
+ s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+ s->sense_key = sense_key;
+ s->asc = asc;
+ ide_set_irq(s->bus);
+}
+
+void ide_atapi_io_error(IDEState *s, int ret)
+{
+ /* XXX: handle more errors */
+ if (ret == -ENOMEDIUM) {
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ASC_MEDIUM_NOT_PRESENT);
+ } else {
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_LOGICAL_BLOCK_OOR);
+ }
+}
+
+/* The whole ATAPI transfer logic is handled in this function */
+void ide_atapi_cmd_reply_end(IDEState *s)
+{
+ int byte_count_limit, size, ret;
+#ifdef DEBUG_IDE_ATAPI
+ printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
+ s->packet_transfer_size,
+ s->elementary_transfer_size,
+ s->io_buffer_index);
+#endif
+ if (s->packet_transfer_size <= 0) {
+ /* end of transfer */
+ ide_transfer_stop(s);
+ s->status = READY_STAT | SEEK_STAT;
+ s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+ ide_set_irq(s->bus);
+#ifdef DEBUG_IDE_ATAPI
+ printf("status=0x%x\n", s->status);
+#endif
+ } else {
+ /* see if a new sector must be read */
+ if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
+ ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
+ if (ret < 0) {
+ ide_transfer_stop(s);
+ ide_atapi_io_error(s, ret);
+ return;
+ }
+ s->lba++;
+ s->io_buffer_index = 0;
+ }
+ if (s->elementary_transfer_size > 0) {
+ /* there are some data left to transmit in this elementary
+ transfer */
+ size = s->cd_sector_size - s->io_buffer_index;
+ if (size > s->elementary_transfer_size)
+ size = s->elementary_transfer_size;
+ s->packet_transfer_size -= size;
+ s->elementary_transfer_size -= size;
+ s->io_buffer_index += size;
+ ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
+ size, ide_atapi_cmd_reply_end);
+ } else {
+ /* a new transfer is needed */
+ s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
+ byte_count_limit = s->lcyl | (s->hcyl << 8);
+#ifdef DEBUG_IDE_ATAPI
+ printf("byte_count_limit=%d\n", byte_count_limit);
+#endif
+ if (byte_count_limit == 0xffff)
+ byte_count_limit--;
+ size = s->packet_transfer_size;
+ if (size > byte_count_limit) {
+ /* byte count limit must be even if this case */
+ if (byte_count_limit & 1)
+ byte_count_limit--;
+ size = byte_count_limit;
+ }
+ s->lcyl = size;
+ s->hcyl = size >> 8;
+ s->elementary_transfer_size = size;
+ /* we cannot transmit more than one sector at a time */
+ if (s->lba != -1) {
+ if (size > (s->cd_sector_size - s->io_buffer_index))
+ size = (s->cd_sector_size - s->io_buffer_index);
+ }
+ s->packet_transfer_size -= size;
+ s->elementary_transfer_size -= size;
+ s->io_buffer_index += size;
+ ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
+ size, ide_atapi_cmd_reply_end);
+ ide_set_irq(s->bus);
+#ifdef DEBUG_IDE_ATAPI
+ printf("status=0x%x\n", s->status);
+#endif
+ }
+ }
+}
+
+/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
+static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
+{
+ if (size > max_size)
+ size = max_size;
+ s->lba = -1; /* no sector read */
+ s->packet_transfer_size = size;
+ s->io_buffer_size = size; /* dma: send the reply data as one chunk */
+ s->elementary_transfer_size = 0;
+ s->io_buffer_index = 0;
+
+ if (s->atapi_dma) {
+ s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
+ s->bus->dma->ops->start_dma(s->bus->dma, s,
+ ide_atapi_cmd_read_dma_cb);
+ } else {
+ s->status = READY_STAT | SEEK_STAT;
+ ide_atapi_cmd_reply_end(s);
+ }
+}
+
+/* start a CD-CDROM read command */
+static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
+ int sector_size)
+{
+ s->lba = lba;
+ s->packet_transfer_size = nb_sectors * sector_size;
+ s->elementary_transfer_size = 0;
+ s->io_buffer_index = sector_size;
+ s->cd_sector_size = sector_size;
+
+ s->status = READY_STAT | SEEK_STAT;
+ ide_atapi_cmd_reply_end(s);
+}
+
+static void ide_atapi_cmd_check_status(IDEState *s)
+{
+#ifdef DEBUG_IDE_ATAPI
+ printf("atapi_cmd_check_status\n");
+#endif
+ s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4);
+ s->status = ERR_STAT;
+ s->nsector = 0;
+ ide_set_irq(s->bus);
+}
+/* ATAPI DMA support */
+
+/* XXX: handle read errors */
+static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
+{
+ IDEState *s = opaque;
+ int data_offset, n;
+
+ if (ret < 0) {
+ ide_atapi_io_error(s, ret);
+ goto eot;
+ }
+
+ if (s->io_buffer_size > 0) {
+ /*
+ * For a cdrom read sector command (s->lba != -1),
+ * adjust the lba for the next s->io_buffer_size chunk
+ * and dma the current chunk.
+ * For a command != read (s->lba == -1), just transfer
+ * the reply data.
+ */
+ if (s->lba != -1) {
+ if (s->cd_sector_size == 2352) {
+ n = 1;
+ cd_data_to_raw(s->io_buffer, s->lba);
+ } else {
+ n = s->io_buffer_size >> 11;
+ }
+ s->lba += n;
+ }
+ s->packet_transfer_size -= s->io_buffer_size;
+ if (s->bus->dma->ops->rw_buf(s->bus->dma, 1) == 0)
+ goto eot;
+ }
+
+ if (s->packet_transfer_size <= 0) {
+ s->status = READY_STAT | SEEK_STAT;
+ s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+ ide_set_irq(s->bus);
+ eot:
+ s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
+ ide_set_inactive(s);
+ return;
+ }
+
+ s->io_buffer_index = 0;
+ if (s->cd_sector_size == 2352) {
+ n = 1;
+ s->io_buffer_size = s->cd_sector_size;
+ data_offset = 16;
+ } else {
+ n = s->packet_transfer_size >> 11;
+ if (n > (IDE_DMA_BUF_SECTORS / 4))
+ n = (IDE_DMA_BUF_SECTORS / 4);
+ s->io_buffer_size = n * 2048;
+ data_offset = 0;
+ }
+#ifdef DEBUG_AIO
+ printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
+#endif
+ s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
+ s->bus->dma->iov.iov_len = n * 4 * 512;
+ qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
+ s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
+ &s->bus->dma->qiov, n * 4,
+ ide_atapi_cmd_read_dma_cb, s);
+ if (!s->bus->dma->aiocb) {
+ /* Note: media not present is the most likely case */
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ASC_MEDIUM_NOT_PRESENT);
+ goto eot;
+ }
+}
+
+/* start a CD-CDROM read command with DMA */
+/* XXX: test if DMA is available */
+static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
+ int sector_size)
+{
+ s->lba = lba;
+ s->packet_transfer_size = nb_sectors * sector_size;
+ s->io_buffer_index = 0;
+ s->io_buffer_size = 0;
+ s->cd_sector_size = sector_size;
+
+ /* XXX: check if BUSY_STAT should be set */
+ s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
+ s->bus->dma->ops->start_dma(s->bus->dma, s,
+ ide_atapi_cmd_read_dma_cb);
+}
+
+static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
+ int sector_size)
+{
+#ifdef DEBUG_IDE_ATAPI
+ printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
+ lba, nb_sectors);
+#endif
+ if (s->atapi_dma) {
+ ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
+ } else {
+ ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
+ }
+}
+
+static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
+ uint16_t profile)
+{
+ uint8_t *buf_profile = buf + 12; /* start of profiles */
+
+ buf_profile += ((*index) * 4); /* start of indexed profile */
+ cpu_to_ube16 (buf_profile, profile);
+ buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
+
+ /* each profile adds 4 bytes to the response */
+ (*index)++;
+ buf[11] += 4; /* Additional Length */
+
+ return 4;
+}
+
+static int ide_dvd_read_structure(IDEState *s, int format,
+ const uint8_t *packet, uint8_t *buf)
+{
+ switch (format) {
+ case 0x0: /* Physical format information */
+ {
+ int layer = packet[6];
+ uint64_t total_sectors;
+
+ if (layer != 0)
+ return -ASC_INV_FIELD_IN_CMD_PACKET;
+
+ total_sectors = s->nb_sectors >> 2;
+ if (total_sectors == 0) {
+ return -ASC_MEDIUM_NOT_PRESENT;
+ }
+
+ buf[4] = 1; /* DVD-ROM, part version 1 */
+ buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
+ buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */
+ buf[7] = 0; /* default densities */
+
+ /* FIXME: 0x30000 per spec? */
+ cpu_to_ube32(buf + 8, 0); /* start sector */
+ cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
+ cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
+
+ /* Size of buffer, not including 2 byte size field */
+ cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
+
+ /* 2k data + 4 byte header */
+ return (2048 + 4);
+ }
+
+ case 0x01: /* DVD copyright information */
+ buf[4] = 0; /* no copyright data */
+ buf[5] = 0; /* no region restrictions */
+
+ /* Size of buffer, not including 2 byte size field */
+ cpu_to_be16wu((uint16_t *)buf, 4 + 2);
+
+ /* 4 byte header + 4 byte data */
+ return (4 + 4);
+
+ case 0x03: /* BCA information - invalid field for no BCA info */
+ return -ASC_INV_FIELD_IN_CMD_PACKET;
+
+ case 0x04: /* DVD disc manufacturing information */
+ /* Size of buffer, not including 2 byte size field */
+ cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
+
+ /* 2k data + 4 byte header */
+ return (2048 + 4);
+
+ case 0xff:
+ /*
+ * This lists all the command capabilities above. Add new ones
+ * in order and update the length and buffer return values.
+ */
+
+ buf[4] = 0x00; /* Physical format */
+ buf[5] = 0x40; /* Not writable, is readable */
+ cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
+
+ buf[8] = 0x01; /* Copyright info */
+ buf[9] = 0x40; /* Not writable, is readable */
+ cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
+
+ buf[12] = 0x03; /* BCA info */
+ buf[13] = 0x40; /* Not writable, is readable */
+ cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
+
+ buf[16] = 0x04; /* Manufacturing info */
+ buf[17] = 0x40; /* Not writable, is readable */
+ cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
+
+ /* Size of buffer, not including 2 byte size field */
+ cpu_to_be16wu((uint16_t *)buf, 16 + 2);
+
+ /* data written + 4 byte header */
+ return (16 + 4);
+
+ default: /* TODO: formats beyond DVD-ROM requires */
+ return -ASC_INV_FIELD_IN_CMD_PACKET;
+ }
+}
+
+static unsigned int event_status_media(IDEState *s,
+ uint8_t *buf)
+{
+ enum media_event_code {
+ MEC_NO_CHANGE = 0, /* Status unchanged */
+ MEC_EJECT_REQUESTED, /* received a request from user to eject */
+ MEC_NEW_MEDIA, /* new media inserted and ready for access */
+ MEC_MEDIA_REMOVAL, /* only for media changers */
+ MEC_MEDIA_CHANGED, /* only for media changers */
+ MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */
+ MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */
+ };
+ enum media_status {
+ MS_TRAY_OPEN = 1,
+ MS_MEDIA_PRESENT = 2,
+ };
+ uint8_t event_code, media_status;
+
+ media_status = 0;
+ if (s->bs->tray_open) {
+ media_status = MS_TRAY_OPEN;
+ } else if (bdrv_is_inserted(s->bs)) {
+ media_status = MS_MEDIA_PRESENT;
+ }
+
+ /* Event notification descriptor */
+ event_code = MEC_NO_CHANGE;
+ if (media_status != MS_TRAY_OPEN && s->events.new_media) {
+ event_code = MEC_NEW_MEDIA;
+ s->events.new_media = false;
+ }
+
+ buf[4] = event_code;
+ buf[5] = media_status;
+
+ /* These fields are reserved, just clear them. */
+ buf[6] = 0;
+ buf[7] = 0;
+
+ return 8; /* We wrote to 4 extra bytes from the header */
+}
+
+static void cmd_get_event_status_notification(IDEState *s,
+ uint8_t *buf)
+{
+ const uint8_t *packet = buf;
+
+ struct {
+ uint8_t opcode;
+ uint8_t polled; /* lsb bit is polled; others are reserved */
+ uint8_t reserved2[2];
+ uint8_t class;
+ uint8_t reserved3[2];
+ uint16_t len;
+ uint8_t control;
+ } __attribute__((packed)) *gesn_cdb;
+
+ struct {
+ uint16_t len;
+ uint8_t notification_class;
+ uint8_t supported_events;
+ } __attribute((packed)) *gesn_event_header;
+
+ enum notification_class_request_type {
+ NCR_RESERVED1 = 1 << 0,
+ NCR_OPERATIONAL_CHANGE = 1 << 1,
+ NCR_POWER_MANAGEMENT = 1 << 2,
+ NCR_EXTERNAL_REQUEST = 1 << 3,
+ NCR_MEDIA = 1 << 4,
+ NCR_MULTI_HOST = 1 << 5,
+ NCR_DEVICE_BUSY = 1 << 6,
+ NCR_RESERVED2 = 1 << 7,
+ };
+ enum event_notification_class_field {
+ ENC_NO_EVENTS = 0,
+ ENC_OPERATIONAL_CHANGE,
+ ENC_POWER_MANAGEMENT,
+ ENC_EXTERNAL_REQUEST,
+ ENC_MEDIA,
+ ENC_MULTIPLE_HOSTS,
+ ENC_DEVICE_BUSY,
+ ENC_RESERVED,
+ };
+ unsigned int max_len, used_len;
+
+ gesn_cdb = (void *)packet;
+ gesn_event_header = (void *)buf;
+
+ max_len = be16_to_cpu(gesn_cdb->len);
+
+ /* It is fine by the MMC spec to not support async mode operations */
+ if (!(gesn_cdb->polled & 0x01)) { /* asynchronous mode */
+ /* Only polling is supported, asynchronous mode is not. */
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ return;
+ }
+
+ /* polling mode operation */
+
+ /*
+ * These are the supported events.
+ *
+ * We currently only support requests of the 'media' type.
+ */
+ gesn_event_header->supported_events = NCR_MEDIA;
+
+ /*
+ * We use |= below to set the class field; other bits in this byte
+ * are reserved now but this is useful to do if we have to use the
+ * reserved fields later.
+ */
+ gesn_event_header->notification_class = 0;
+
+ /*
+ * Responses to requests are to be based on request priority. The
+ * notification_class_request_type enum above specifies the
+ * priority: upper elements are higher prio than lower ones.
+ */
+ if (gesn_cdb->class & NCR_MEDIA) {
+ gesn_event_header->notification_class |= ENC_MEDIA;
+ used_len = event_status_media(s, buf);
+ } else {
+ gesn_event_header->notification_class = 0x80; /* No event available */
+ used_len = sizeof(*gesn_event_header);
+ }
+ gesn_event_header->len = cpu_to_be16(used_len
+ - sizeof(*gesn_event_header));
+ ide_atapi_cmd_reply(s, used_len, max_len);
+}
+
+static void cmd_request_sense(IDEState *s, uint8_t *buf)
+{
+ int max_len = buf[4];
+
+ memset(buf, 0, 18);
+ buf[0] = 0x70 | (1 << 7);
+ buf[2] = s->sense_key;
+ buf[7] = 10;
+ buf[12] = s->asc;
+
+ if (s->sense_key == SENSE_UNIT_ATTENTION) {
+ s->sense_key = SENSE_NONE;
+ }
+
+ ide_atapi_cmd_reply(s, 18, max_len);
+}
+
+static void cmd_inquiry(IDEState *s, uint8_t *buf)
+{
+ int max_len = buf[4];
+
+ buf[0] = 0x05; /* CD-ROM */
+ buf[1] = 0x80; /* removable */
+ buf[2] = 0x00; /* ISO */
+ buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
+ buf[4] = 31; /* additional length */
+ buf[5] = 0; /* reserved */
+ buf[6] = 0; /* reserved */
+ buf[7] = 0; /* reserved */
+ padstr8(buf + 8, 8, "QEMU");
+ padstr8(buf + 16, 16, "QEMU DVD-ROM");
+ padstr8(buf + 32, 4, s->version);
+ ide_atapi_cmd_reply(s, 36, max_len);
+}
+
+static void cmd_get_configuration(IDEState *s, uint8_t *buf)
+{
+ uint32_t len;
+ uint8_t index = 0;
+ int max_len;
+
+ /* only feature 0 is supported */
+ if (buf[2] != 0 || buf[3] != 0) {
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ return;
+ }
+
+ /* XXX: could result in alignment problems in some architectures */
+ max_len = ube16_to_cpu(buf + 7);
+
+ /*
+ * XXX: avoid overflow for io_buffer if max_len is bigger than
+ * the size of that buffer (dimensioned to max number of
+ * sectors to transfer at once)
+ *
+ * Only a problem if the feature/profiles grow.
+ */
+ if (max_len > 512) {
+ /* XXX: assume 1 sector */
+ max_len = 512;
+ }
+
+ memset(buf, 0, max_len);
+ /*
+ * the number of sectors from the media tells us which profile
+ * to use as current. 0 means there is no media
+ */
+ if (media_is_dvd(s)) {
+ cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
+ } else if (media_is_cd(s)) {
+ cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
+ }
+
+ buf[10] = 0x02 | 0x01; /* persistent and current */
+ len = 12; /* headers: 8 + 4 */
+ len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
+ len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
+ cpu_to_ube32(buf, len - 4); /* data length */
+
+ ide_atapi_cmd_reply(s, len, max_len);
+}
+
+static void cmd_mode_sense(IDEState *s, uint8_t *buf)
+{
+ int action, code;
+ int max_len;
+
+ if (buf[0] == GPCMD_MODE_SENSE_10) {
+ max_len = ube16_to_cpu(buf + 7);
+ } else {
+ max_len = buf[4];
+ }
+
+ action = buf[2] >> 6;
+ code = buf[2] & 0x3f;
+
+ switch(action) {
+ case 0: /* current values */
+ switch(code) {
+ case GPMODE_R_W_ERROR_PAGE: /* error recovery */
+ cpu_to_ube16(&buf[0], 16 + 6);
+ buf[2] = 0x70;
+ buf[3] = 0;
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = 0;
+ buf[7] = 0;
+
+ buf[8] = 0x01;
+ buf[9] = 0x06;
+ buf[10] = 0x00;
+ buf[11] = 0x05;
+ buf[12] = 0x00;
+ buf[13] = 0x00;
+ buf[14] = 0x00;
+ buf[15] = 0x00;
+ ide_atapi_cmd_reply(s, 16, max_len);
+ break;
+ case GPMODE_AUDIO_CTL_PAGE:
+ cpu_to_ube16(&buf[0], 24 + 6);
+ buf[2] = 0x70;
+ buf[3] = 0;
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = 0;
+ buf[7] = 0;
+
+ /* Fill with CDROM audio volume */
+ buf[17] = 0;
+ buf[19] = 0;
+ buf[21] = 0;
+ buf[23] = 0;
+
+ ide_atapi_cmd_reply(s, 24, max_len);
+ break;
+ case GPMODE_CAPABILITIES_PAGE:
+ cpu_to_ube16(&buf[0], 28 + 6);
+ buf[2] = 0x70;
+ buf[3] = 0;
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = 0;
+ buf[7] = 0;
+
+ buf[8] = 0x2a;
+ buf[9] = 0x12;
+ buf[10] = 0x00;
+ buf[11] = 0x00;
+
+ /* Claim PLAY_AUDIO capability (0x01) since some Linux
+ code checks for this to automount media. */
+ buf[12] = 0x71;
+ buf[13] = 3 << 5;
+ buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
+ if (bdrv_is_locked(s->bs))
+ buf[6] |= 1 << 1;
+ buf[15] = 0x00;
+ cpu_to_ube16(&buf[16], 706);
+ buf[18] = 0;
+ buf[19] = 2;
+ cpu_to_ube16(&buf[20], 512);
+ cpu_to_ube16(&buf[22], 706);
+ buf[24] = 0;
+ buf[25] = 0;
+ buf[26] = 0;
+ buf[27] = 0;
+ ide_atapi_cmd_reply(s, 28, max_len);
+ break;
+ default:
+ goto error_cmd;
+ }
+ break;
+ case 1: /* changeable values */
+ goto error_cmd;
+ case 2: /* default values */
+ goto error_cmd;
+ default:
+ case 3: /* saved values */
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
+ break;
+ }
+ return;
+
+error_cmd:
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
+}
+
+static void cmd_test_unit_ready(IDEState *s, uint8_t *buf)
+{
+ /* Not Ready Conditions are already handled in ide_atapi_cmd(), so if we
+ * come here, we know that it's ready. */
+ ide_atapi_cmd_ok(s);
+}
+
+static void cmd_prevent_allow_medium_removal(IDEState *s, uint8_t* buf)
+{
+ bdrv_set_locked(s->bs, buf[4] & 1);
+ ide_atapi_cmd_ok(s);
+}
+
+static void cmd_read(IDEState *s, uint8_t* buf)
+{
+ int nb_sectors, lba;
+
+ if (buf[0] == GPCMD_READ_10) {
+ nb_sectors = ube16_to_cpu(buf + 7);
+ } else {
+ nb_sectors = ube32_to_cpu(buf + 6);
+ }
+
+ lba = ube32_to_cpu(buf + 2);
+ if (nb_sectors == 0) {
+ ide_atapi_cmd_ok(s);
+ return;
+ }
+
+ ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+}
+
+static void cmd_read_cd(IDEState *s, uint8_t* buf)
+{
+ int nb_sectors, lba, transfer_request;
+
+ nb_sectors = (buf[6] << 16) | (buf[7] << 8) | buf[8];
+ lba = ube32_to_cpu(buf + 2);
+
+ if (nb_sectors == 0) {
+ ide_atapi_cmd_ok(s);
+ return;
+ }
+
+ transfer_request = buf[9];
+ switch(transfer_request & 0xf8) {
+ case 0x00:
+ /* nothing */
+ ide_atapi_cmd_ok(s);
+ break;
+ case 0x10:
+ /* normal read */
+ ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+ break;
+ case 0xf8:
+ /* read all data */
+ ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
+ break;
+ default:
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ break;
+ }
+}
+
+static void cmd_seek(IDEState *s, uint8_t* buf)
+{
+ unsigned int lba;
+ uint64_t total_sectors = s->nb_sectors >> 2;
+
+ lba = ube32_to_cpu(buf + 2);
+ if (lba >= total_sectors) {
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
+ return;
+ }
+
+ ide_atapi_cmd_ok(s);
+}
+
+static void cmd_start_stop_unit(IDEState *s, uint8_t* buf)
+{
+ int start, eject, sense, err = 0;
+ start = buf[4] & 1;
+ eject = (buf[4] >> 1) & 1;
+
+ if (eject) {
+ err = bdrv_eject(s->bs, !start);
+ }
+
+ switch (err) {
+ case 0:
+ ide_atapi_cmd_ok(s);
+ break;
+ case -EBUSY:
+ sense = SENSE_NOT_READY;
+ if (bdrv_is_inserted(s->bs)) {
+ sense = SENSE_ILLEGAL_REQUEST;
+ }
+ ide_atapi_cmd_error(s, sense, ASC_MEDIA_REMOVAL_PREVENTED);
+ break;
+ default:
+ ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ break;
+ }
+}
+
+static void cmd_mechanism_status(IDEState *s, uint8_t* buf)
+{
+ int max_len = ube16_to_cpu(buf + 8);
+
+ cpu_to_ube16(buf, 0);
+ /* no current LBA */
+ buf[2] = 0;
+ buf[3] = 0;
+ buf[4] = 0;
+ buf[5] = 1;
+ cpu_to_ube16(buf + 6, 0);
+ ide_atapi_cmd_reply(s, 8, max_len);
+}
+
+static void cmd_read_toc_pma_atip(IDEState *s, uint8_t* buf)
+{
+ int format, msf, start_track, len;
+ int max_len;
+ uint64_t total_sectors = s->nb_sectors >> 2;
+
+ max_len = ube16_to_cpu(buf + 7);
+ format = buf[9] >> 6;
+ msf = (buf[1] >> 1) & 1;
+ start_track = buf[6];
+
+ switch(format) {
+ case 0:
+ len = cdrom_read_toc(total_sectors, buf, msf, start_track);
+ if (len < 0)
+ goto error_cmd;
+ ide_atapi_cmd_reply(s, len, max_len);
+ break;
+ case 1:
+ /* multi session : only a single session defined */
+ memset(buf, 0, 12);
+ buf[1] = 0x0a;
+ buf[2] = 0x01;
+ buf[3] = 0x01;
+ ide_atapi_cmd_reply(s, 12, max_len);
+ break;
+ case 2:
+ len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
+ if (len < 0)
+ goto error_cmd;
+ ide_atapi_cmd_reply(s, len, max_len);
+ break;
+ default:
+ error_cmd:
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ }
+}
+
+static void cmd_read_cdvd_capacity(IDEState *s, uint8_t* buf)
+{
+ uint64_t total_sectors = s->nb_sectors >> 2;
+
+ /* NOTE: it is really the number of sectors minus 1 */
+ cpu_to_ube32(buf, total_sectors - 1);
+ cpu_to_ube32(buf + 4, 2048);
+ ide_atapi_cmd_reply(s, 8, 8);
+}
+
+static void cmd_read_dvd_structure(IDEState *s, uint8_t* buf)
+{
+ int max_len;
+ int media = buf[1];
+ int format = buf[7];
+ int ret;
+
+ max_len = ube16_to_cpu(buf + 8);
+
+ if (format < 0xff) {
+ if (media_is_cd(s)) {
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INCOMPATIBLE_FORMAT);
+ return;
+ } else if (!media_present(s)) {
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ return;
+ }
+ }
+
+ memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
+ IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
+
+ switch (format) {
+ case 0x00 ... 0x7f:
+ case 0xff:
+ if (media == 0) {
+ ret = ide_dvd_read_structure(s, format, buf, buf);
+
+ if (ret < 0) {
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
+ } else {
+ ide_atapi_cmd_reply(s, ret, max_len);
+ }
+
+ break;
+ }
+ /* TODO: BD support, fall through for now */
+
+ /* Generic disk structures */
+ case 0x80: /* TODO: AACS volume identifier */
+ case 0x81: /* TODO: AACS media serial number */
+ case 0x82: /* TODO: AACS media identifier */
+ case 0x83: /* TODO: AACS media key block */
+ case 0x90: /* TODO: List of recognized format layers */
+ case 0xc0: /* TODO: Write protection status */
+ default:
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ASC_INV_FIELD_IN_CMD_PACKET);
+ break;
+ }
+}
+
+static void cmd_set_speed(IDEState *s, uint8_t* buf)
+{
+ ide_atapi_cmd_ok(s);
+}
+
+enum {
+ /*
+ * Only commands flagged as ALLOW_UA are allowed to run under a
+ * unit attention condition. (See MMC-5, section 4.1.6.1)
+ */
+ ALLOW_UA = 0x01,
+
+ /*
+ * Commands flagged with CHECK_READY can only execute if a medium is present.
+ * Otherwise they report the Not Ready Condition. (See MMC-5, section
+ * 4.1.8)
+ */
+ CHECK_READY = 0x02,
+};
+
+static const struct {
+ void (*handler)(IDEState *s, uint8_t *buf);
+ int flags;
+} atapi_cmd_table[0x100] = {
+ [ 0x00 ] = { cmd_test_unit_ready, CHECK_READY },
+ [ 0x03 ] = { cmd_request_sense, ALLOW_UA },
+ [ 0x12 ] = { cmd_inquiry, ALLOW_UA },
+ [ 0x1a ] = { cmd_mode_sense, /* (6) */ 0 },
+ [ 0x1b ] = { cmd_start_stop_unit, 0 },
+ [ 0x1e ] = { cmd_prevent_allow_medium_removal, 0 },
+ [ 0x25 ] = { cmd_read_cdvd_capacity, CHECK_READY },
+ [ 0x28 ] = { cmd_read, /* (10) */ 0 },
+ [ 0x2b ] = { cmd_seek, CHECK_READY },
+ [ 0x43 ] = { cmd_read_toc_pma_atip, CHECK_READY },
+ [ 0x46 ] = { cmd_get_configuration, ALLOW_UA },
+ [ 0x4a ] = { cmd_get_event_status_notification, ALLOW_UA },
+ [ 0x5a ] = { cmd_mode_sense, /* (10) */ 0 },
+ [ 0xa8 ] = { cmd_read, /* (12) */ 0 },
+ [ 0xad ] = { cmd_read_dvd_structure, 0 },
+ [ 0xbb ] = { cmd_set_speed, 0 },
+ [ 0xbd ] = { cmd_mechanism_status, 0 },
+ [ 0xbe ] = { cmd_read_cd, 0 },
+};
+
+void ide_atapi_cmd(IDEState *s)
+{
+ uint8_t *buf;
+
+ buf = s->io_buffer;
+#ifdef DEBUG_IDE_ATAPI
+ {
+ int i;
+ printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
+ for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
+ printf(" %02x", buf[i]);
+ }
+ printf("\n");
+ }
+#endif
+ /*
+ * If there's a UNIT_ATTENTION condition pending, only command flagged with
+ * ALLOW_UA are allowed to complete. with other commands getting a CHECK
+ * condition response unless a higher priority status, defined by the drive
+ * here, is pending.
+ */
+ if (s->sense_key == SENSE_UNIT_ATTENTION &&
+ !(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA)) {
+ ide_atapi_cmd_check_status(s);
+ return;
+ }
+ /*
+ * When a CD gets changed, we have to report an ejected state and
+ * then a loaded state to guests so that they detect tray
+ * open/close and media change events. Guests that do not use
+ * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
+ * states rely on this behavior.
+ */
+ if (bdrv_is_inserted(s->bs) && s->cdrom_changed) {
+ ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+
+ s->cdrom_changed = 0;
+ s->sense_key = SENSE_UNIT_ATTENTION;
+ s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
+ return;
+ }
+
+ /* Report a Not Ready condition if appropriate for the command */
+ if ((atapi_cmd_table[s->io_buffer[0]].flags & CHECK_READY) &&
+ (!media_present(s) || !bdrv_is_inserted(s->bs)))
+ {
+ ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ return;
+ }
+
+ /* Execute the command */
+ if (atapi_cmd_table[s->io_buffer[0]].handler) {
+ atapi_cmd_table[s->io_buffer[0]].handler(s, buf);
+ return;
+ }
+
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE);
+}
diff --git a/hw/ide/core.c b/hw/ide/core.c
index f028ddb49..90f553b69 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -25,7 +25,6 @@
#include <hw/hw.h>
#include <hw/pc.h>
#include <hw/pci.h>
-#include <hw/scsi.h>
#include "qemu-error.h"
#include "qemu-timer.h"
#include "sysemu.h"
@@ -56,23 +55,6 @@ static const int smart_attributes[][12] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
};
-/* XXX: DVDs that could fit on a CD will be reported as a CD */
-static inline int media_present(IDEState *s)
-{
- return (s->nb_sectors > 0);
-}
-
-static inline int media_is_dvd(IDEState *s)
-{
- return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
-}
-
-static inline int media_is_cd(IDEState *s)
-{
- return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
-}
-
-static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
static int ide_handle_rw_error(IDEState *s, int error, int op);
static void padstr(char *str, const char *src, int len)
@@ -87,17 +69,6 @@ static void padstr(char *str, const char *src, int len)
}
}
-static void padstr8(uint8_t *buf, int buf_size, const char *src)
-{
- int i;
- for(i = 0; i < buf_size; i++) {
- if (*src)
- buf[i] = *src++;
- else
- buf[i] = ' ';
- }
-}
-
static void put_le16(uint16_t *p, unsigned int v)
{
*p = cpu_to_le16(v);
@@ -335,8 +306,8 @@ static inline void ide_abort_command(IDEState *s)
}
/* prepare data transfer and tell what to do after */
-static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
- EndTransferFunc *end_transfer_func)
+void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
+ EndTransferFunc *end_transfer_func)
{
s->end_transfer_func = end_transfer_func;
s->data_ptr = buf;
@@ -347,7 +318,7 @@ static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
s->bus->dma->ops->start_transfer(s->bus->dma);
}
-static void ide_transfer_stop(IDEState *s)
+void ide_transfer_stop(IDEState *s)
{
s->end_transfer_func = ide_transfer_stop;
s->data_ptr = s->io_buffer;
@@ -447,7 +418,7 @@ static void dma_buf_commit(IDEState *s, int is_write)
qemu_sglist_destroy(&s->sg);
}
-static void ide_set_inactive(IDEState *s)
+void ide_set_inactive(IDEState *s)
{
s->bus->dma->aiocb = NULL;
s->bus->dma->ops->set_inactive(s->bus->dma);
@@ -617,38 +588,6 @@ void ide_sector_write(IDEState *s)
}
}
-void ide_atapi_cmd_ok(IDEState *s)
-{
- s->error = 0;
- s->status = READY_STAT | SEEK_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s->bus);
-}
-
-void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
-{
-#ifdef DEBUG_IDE_ATAPI
- printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
-#endif
- s->error = sense_key << 4;
- s->status = READY_STAT | ERR_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- s->sense_key = sense_key;
- s->asc = asc;
- ide_set_irq(s->bus);
-}
-
-static void ide_atapi_cmd_check_status(IDEState *s)
-{
-#ifdef DEBUG_IDE_ATAPI
- printf("atapi_cmd_check_status\n");
-#endif
- s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4);
- s->status = ERR_STAT;
- s->nsector = 0;
- ide_set_irq(s->bus);
-}
-
static void ide_flush_cb(void *opaque, int ret)
{
IDEState *s = opaque;
@@ -679,995 +618,6 @@ void ide_flush_cache(IDEState *s)
}
}
-static inline void cpu_to_ube16(uint8_t *buf, int val)
-{
- buf[0] = val >> 8;
- buf[1] = val & 0xff;
-}
-
-static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
-{
- buf[0] = val >> 24;
- buf[1] = val >> 16;
- buf[2] = val >> 8;
- buf[3] = val & 0xff;
-}
-
-static inline int ube16_to_cpu(const uint8_t *buf)
-{
- return (buf[0] << 8) | buf[1];
-}
-
-static inline int ube32_to_cpu(const uint8_t *buf)
-{
- return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-}
-
-static void lba_to_msf(uint8_t *buf, int lba)
-{
- lba += 150;
- buf[0] = (lba / 75) / 60;
- buf[1] = (lba / 75) % 60;
- buf[2] = lba % 75;
-}
-
-static void cd_data_to_raw(uint8_t *buf, int lba)
-{
- /* sync bytes */
- buf[0] = 0x00;
- memset(buf + 1, 0xff, 10);
- buf[11] = 0x00;
- buf += 12;
- /* MSF */
- lba_to_msf(buf, lba);
- buf[3] = 0x01; /* mode 1 data */
- buf += 4;
- /* data */
- buf += 2048;
- /* XXX: ECC not computed */
- memset(buf, 0, 288);
-}
-
-static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
- int sector_size)
-{
- int ret;
-
- switch(sector_size) {
- case 2048:
- ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
- break;
- case 2352:
- ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
- if (ret < 0)
- return ret;
- cd_data_to_raw(buf, lba);
- break;
- default:
- ret = -EIO;
- break;
- }
- return ret;
-}
-
-void ide_atapi_io_error(IDEState *s, int ret)
-{
- /* XXX: handle more errors */
- if (ret == -ENOMEDIUM) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- } else {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_LOGICAL_BLOCK_OOR);
- }
-}
-
-/* The whole ATAPI transfer logic is handled in this function */
-static void ide_atapi_cmd_reply_end(IDEState *s)
-{
- int byte_count_limit, size, ret;
-#ifdef DEBUG_IDE_ATAPI
- printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
- s->packet_transfer_size,
- s->elementary_transfer_size,
- s->io_buffer_index);
-#endif
- if (s->packet_transfer_size <= 0) {
- /* end of transfer */
- ide_transfer_stop(s);
- s->status = READY_STAT | SEEK_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s->bus);
-#ifdef DEBUG_IDE_ATAPI
- printf("status=0x%x\n", s->status);
-#endif
- } else {
- /* see if a new sector must be read */
- if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
- ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
- if (ret < 0) {
- ide_transfer_stop(s);
- ide_atapi_io_error(s, ret);
- return;
- }
- s->lba++;
- s->io_buffer_index = 0;
- }
- if (s->elementary_transfer_size > 0) {
- /* there are some data left to transmit in this elementary
- transfer */
- size = s->cd_sector_size - s->io_buffer_index;
- if (size > s->elementary_transfer_size)
- size = s->elementary_transfer_size;
- s->packet_transfer_size -= size;
- s->elementary_transfer_size -= size;
- s->io_buffer_index += size;
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
- size, ide_atapi_cmd_reply_end);
- } else {
- /* a new transfer is needed */
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
- byte_count_limit = s->lcyl | (s->hcyl << 8);
-#ifdef DEBUG_IDE_ATAPI
- printf("byte_count_limit=%d\n", byte_count_limit);
-#endif
- if (byte_count_limit == 0xffff)
- byte_count_limit--;
- size = s->packet_transfer_size;
- if (size > byte_count_limit) {
- /* byte count limit must be even if this case */
- if (byte_count_limit & 1)
- byte_count_limit--;
- size = byte_count_limit;
- }
- s->lcyl = size;
- s->hcyl = size >> 8;
- s->elementary_transfer_size = size;
- /* we cannot transmit more than one sector at a time */
- if (s->lba != -1) {
- if (size > (s->cd_sector_size - s->io_buffer_index))
- size = (s->cd_sector_size - s->io_buffer_index);
- }
- s->packet_transfer_size -= size;
- s->elementary_transfer_size -= size;
- s->io_buffer_index += size;
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
- size, ide_atapi_cmd_reply_end);
- ide_set_irq(s->bus);
-#ifdef DEBUG_IDE_ATAPI
- printf("status=0x%x\n", s->status);
-#endif
- }
- }
-}
-
-/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
-static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
-{
- if (size > max_size)
- size = max_size;
- s->lba = -1; /* no sector read */
- s->packet_transfer_size = size;
- s->io_buffer_size = size; /* dma: send the reply data as one chunk */
- s->elementary_transfer_size = 0;
- s->io_buffer_index = 0;
-
- if (s->atapi_dma) {
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
- s->bus->dma->ops->start_dma(s->bus->dma, s,
- ide_atapi_cmd_read_dma_cb);
- } else {
- s->status = READY_STAT | SEEK_STAT;
- ide_atapi_cmd_reply_end(s);
- }
-}
-
-/* start a CD-CDROM read command */
-static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
- s->lba = lba;
- s->packet_transfer_size = nb_sectors * sector_size;
- s->elementary_transfer_size = 0;
- s->io_buffer_index = sector_size;
- s->cd_sector_size = sector_size;
-
- s->status = READY_STAT | SEEK_STAT;
- ide_atapi_cmd_reply_end(s);
-}
-
-/* ATAPI DMA support */
-
-/* XXX: handle read errors */
-static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
-{
- IDEState *s = opaque;
- int data_offset, n;
-
- if (ret < 0) {
- ide_atapi_io_error(s, ret);
- goto eot;
- }
-
- if (s->io_buffer_size > 0) {
- /*
- * For a cdrom read sector command (s->lba != -1),
- * adjust the lba for the next s->io_buffer_size chunk
- * and dma the current chunk.
- * For a command != read (s->lba == -1), just transfer
- * the reply data.
- */
- if (s->lba != -1) {
- if (s->cd_sector_size == 2352) {
- n = 1;
- cd_data_to_raw(s->io_buffer, s->lba);
- } else {
- n = s->io_buffer_size >> 11;
- }
- s->lba += n;
- }
- s->packet_transfer_size -= s->io_buffer_size;
- if (s->bus->dma->ops->rw_buf(s->bus->dma, 1) == 0)
- goto eot;
- }
-
- if (s->packet_transfer_size <= 0) {
- s->status = READY_STAT | SEEK_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s->bus);
- eot:
- s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
- ide_set_inactive(s);
- return;
- }
-
- s->io_buffer_index = 0;
- if (s->cd_sector_size == 2352) {
- n = 1;
- s->io_buffer_size = s->cd_sector_size;
- data_offset = 16;
- } else {
- n = s->packet_transfer_size >> 11;
- if (n > (IDE_DMA_BUF_SECTORS / 4))
- n = (IDE_DMA_BUF_SECTORS / 4);
- s->io_buffer_size = n * 2048;
- data_offset = 0;
- }
-#ifdef DEBUG_AIO
- printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
-#endif
- s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
- s->bus->dma->iov.iov_len = n * 4 * 512;
- qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
- s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
- &s->bus->dma->qiov, n * 4,
- ide_atapi_cmd_read_dma_cb, s);
- if (!s->bus->dma->aiocb) {
- /* Note: media not present is the most likely case */
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- goto eot;
- }
-}
-
-/* start a CD-CDROM read command with DMA */
-/* XXX: test if DMA is available */
-static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
- s->lba = lba;
- s->packet_transfer_size = nb_sectors * sector_size;
- s->io_buffer_index = 0;
- s->io_buffer_size = 0;
- s->cd_sector_size = sector_size;
-
- /* XXX: check if BUSY_STAT should be set */
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
- s->bus->dma->ops->start_dma(s->bus->dma, s,
- ide_atapi_cmd_read_dma_cb);
-}
-
-static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
-#ifdef DEBUG_IDE_ATAPI
- printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
- lba, nb_sectors);
-#endif
- if (s->atapi_dma) {
- ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
- } else {
- ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
- }
-}
-
-static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
- uint16_t profile)
-{
- uint8_t *buf_profile = buf + 12; /* start of profiles */
-
- buf_profile += ((*index) * 4); /* start of indexed profile */
- cpu_to_ube16 (buf_profile, profile);
- buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
-
- /* each profile adds 4 bytes to the response */
- (*index)++;
- buf[11] += 4; /* Additional Length */
-
- return 4;
-}
-
-static int ide_dvd_read_structure(IDEState *s, int format,
- const uint8_t *packet, uint8_t *buf)
-{
- switch (format) {
- case 0x0: /* Physical format information */
- {
- int layer = packet[6];
- uint64_t total_sectors;
-
- if (layer != 0)
- return -ASC_INV_FIELD_IN_CMD_PACKET;
-
- bdrv_get_geometry(s->bs, &total_sectors);
- total_sectors >>= 2;
- if (total_sectors == 0)
- return -ASC_MEDIUM_NOT_PRESENT;
-
- buf[4] = 1; /* DVD-ROM, part version 1 */
- buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
- buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */
- buf[7] = 0; /* default densities */
-
- /* FIXME: 0x30000 per spec? */
- cpu_to_ube32(buf + 8, 0); /* start sector */
- cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
- cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
-
- /* Size of buffer, not including 2 byte size field */
- cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
-
- /* 2k data + 4 byte header */
- return (2048 + 4);
- }
-
- case 0x01: /* DVD copyright information */
- buf[4] = 0; /* no copyright data */
- buf[5] = 0; /* no region restrictions */
-
- /* Size of buffer, not including 2 byte size field */
- cpu_to_be16wu((uint16_t *)buf, 4 + 2);
-
- /* 4 byte header + 4 byte data */
- return (4 + 4);
-
- case 0x03: /* BCA information - invalid field for no BCA info */
- return -ASC_INV_FIELD_IN_CMD_PACKET;
-
- case 0x04: /* DVD disc manufacturing information */
- /* Size of buffer, not including 2 byte size field */
- cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
-
- /* 2k data + 4 byte header */
- return (2048 + 4);
-
- case 0xff:
- /*
- * This lists all the command capabilities above. Add new ones
- * in order and update the length and buffer return values.
- */
-
- buf[4] = 0x00; /* Physical format */
- buf[5] = 0x40; /* Not writable, is readable */
- cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
-
- buf[8] = 0x01; /* Copyright info */
- buf[9] = 0x40; /* Not writable, is readable */
- cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
-
- buf[12] = 0x03; /* BCA info */
- buf[13] = 0x40; /* Not writable, is readable */
- cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
-
- buf[16] = 0x04; /* Manufacturing info */
- buf[17] = 0x40; /* Not writable, is readable */
- cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
-
- /* Size of buffer, not including 2 byte size field */
- cpu_to_be16wu((uint16_t *)buf, 16 + 2);
-
- /* data written + 4 byte header */
- return (16 + 4);
-
- default: /* TODO: formats beyond DVD-ROM requires */
- return -ASC_INV_FIELD_IN_CMD_PACKET;
- }
-}
-
-static unsigned int event_status_media(IDEState *s,
- uint8_t *buf)
-{
- enum media_event_code {
- MEC_NO_CHANGE = 0, /* Status unchanged */
- MEC_EJECT_REQUESTED, /* received a request from user to eject */
- MEC_NEW_MEDIA, /* new media inserted and ready for access */
- MEC_MEDIA_REMOVAL, /* only for media changers */
- MEC_MEDIA_CHANGED, /* only for media changers */
- MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */
- MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */
- };
- enum media_status {
- MS_TRAY_OPEN = 1,
- MS_MEDIA_PRESENT = 2,
- };
- uint8_t event_code, media_status;
-
- media_status = 0;
- if (s->bs->tray_open) {
- media_status = MS_TRAY_OPEN;
- } else if (bdrv_is_inserted(s->bs)) {
- media_status = MS_MEDIA_PRESENT;
- }
-
- /* Event notification descriptor */
- event_code = MEC_NO_CHANGE;
- if (media_status != MS_TRAY_OPEN && s->events.new_media) {
- event_code = MEC_NEW_MEDIA;
- s->events.new_media = false;
- }
-
- buf[4] = event_code;
- buf[5] = media_status;
-
- /* These fields are reserved, just clear them. */
- buf[6] = 0;
- buf[7] = 0;
-
- return 8; /* We wrote to 4 extra bytes from the header */
-}
-
-static void handle_get_event_status_notification(IDEState *s,
- uint8_t *buf,
- const uint8_t *packet)
-{
- struct {
- uint8_t opcode;
- uint8_t polled; /* lsb bit is polled; others are reserved */
- uint8_t reserved2[2];
- uint8_t class;
- uint8_t reserved3[2];
- uint16_t len;
- uint8_t control;
- } __attribute__((packed)) *gesn_cdb;
-
- struct {
- uint16_t len;
- uint8_t notification_class;
- uint8_t supported_events;
- } __attribute((packed)) *gesn_event_header;
-
- enum notification_class_request_type {
- NCR_RESERVED1 = 1 << 0,
- NCR_OPERATIONAL_CHANGE = 1 << 1,
- NCR_POWER_MANAGEMENT = 1 << 2,
- NCR_EXTERNAL_REQUEST = 1 << 3,
- NCR_MEDIA = 1 << 4,
- NCR_MULTI_HOST = 1 << 5,
- NCR_DEVICE_BUSY = 1 << 6,
- NCR_RESERVED2 = 1 << 7,
- };
- enum event_notification_class_field {
- ENC_NO_EVENTS = 0,
- ENC_OPERATIONAL_CHANGE,
- ENC_POWER_MANAGEMENT,
- ENC_EXTERNAL_REQUEST,
- ENC_MEDIA,
- ENC_MULTIPLE_HOSTS,
- ENC_DEVICE_BUSY,
- ENC_RESERVED,
- };
- unsigned int max_len, used_len;
-
- gesn_cdb = (void *)packet;
- gesn_event_header = (void *)buf;
-
- max_len = be16_to_cpu(gesn_cdb->len);
-
- /* It is fine by the MMC spec to not support async mode operations */
- if (!(gesn_cdb->polled & 0x01)) { /* asynchronous mode */
- /* Only polling is supported, asynchronous mode is not. */
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- return;
- }
-
- /* polling mode operation */
-
- /*
- * These are the supported events.
- *
- * We currently only support requests of the 'media' type.
- */
- gesn_event_header->supported_events = NCR_MEDIA;
-
- /*
- * We use |= below to set the class field; other bits in this byte
- * are reserved now but this is useful to do if we have to use the
- * reserved fields later.
- */
- gesn_event_header->notification_class = 0;
-
- /*
- * Responses to requests are to be based on request priority. The
- * notification_class_request_type enum above specifies the
- * priority: upper elements are higher prio than lower ones.
- */
- if (gesn_cdb->class & NCR_MEDIA) {
- gesn_event_header->notification_class |= ENC_MEDIA;
- used_len = event_status_media(s, buf);
- } else {
- gesn_event_header->notification_class = 0x80; /* No event available */
- used_len = sizeof(*gesn_event_header);
- }
- gesn_event_header->len = cpu_to_be16(used_len
- - sizeof(*gesn_event_header));
- ide_atapi_cmd_reply(s, used_len, max_len);
-}
-
-static void ide_atapi_cmd(IDEState *s)
-{
- const uint8_t *packet;
- uint8_t *buf;
- int max_len;
-
- packet = s->io_buffer;
- buf = s->io_buffer;
-#ifdef DEBUG_IDE_ATAPI
- {
- int i;
- printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
- for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
- printf(" %02x", packet[i]);
- }
- printf("\n");
- }
-#endif
- /*
- * If there's a UNIT_ATTENTION condition pending, only
- * REQUEST_SENSE, INQUIRY, GET_CONFIGURATION and
- * GET_EVENT_STATUS_NOTIFICATION commands are allowed to complete.
- * MMC-5, section 4.1.6.1 lists only these commands being allowed
- * to complete, with other commands getting a CHECK condition
- * response unless a higher priority status, defined by the drive
- * here, is pending.
- */
- if (s->sense_key == SENSE_UNIT_ATTENTION &&
- s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
- s->io_buffer[0] != GPCMD_INQUIRY &&
- s->io_buffer[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) {
- ide_atapi_cmd_check_status(s);
- return;
- }
- switch(s->io_buffer[0]) {
- case GPCMD_TEST_UNIT_READY:
- if (bdrv_is_inserted(s->bs) && !s->cdrom_changed) {
- ide_atapi_cmd_ok(s);
- } else {
- s->cdrom_changed = 0;
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- }
- break;
- case GPCMD_MODE_SENSE_6:
- case GPCMD_MODE_SENSE_10:
- {
- int action, code;
- if (packet[0] == GPCMD_MODE_SENSE_10)
- max_len = ube16_to_cpu(packet + 7);
- else
- max_len = packet[4];
- action = packet[2] >> 6;
- code = packet[2] & 0x3f;
- switch(action) {
- case 0: /* current values */
- switch(code) {
- case GPMODE_R_W_ERROR_PAGE: /* error recovery */
- cpu_to_ube16(&buf[0], 16 + 6);
- buf[2] = 0x70;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 0;
-
- buf[8] = 0x01;
- buf[9] = 0x06;
- buf[10] = 0x00;
- buf[11] = 0x05;
- buf[12] = 0x00;
- buf[13] = 0x00;
- buf[14] = 0x00;
- buf[15] = 0x00;
- ide_atapi_cmd_reply(s, 16, max_len);
- break;
- case GPMODE_AUDIO_CTL_PAGE:
- cpu_to_ube16(&buf[0], 24 + 6);
- buf[2] = 0x70;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 0;
-
- /* Fill with CDROM audio volume */
- buf[17] = 0;
- buf[19] = 0;
- buf[21] = 0;
- buf[23] = 0;
-
- ide_atapi_cmd_reply(s, 24, max_len);
- break;
- case GPMODE_CAPABILITIES_PAGE:
- cpu_to_ube16(&buf[0], 28 + 6);
- buf[2] = 0x70;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 0;
-
- buf[8] = 0x2a;
- buf[9] = 0x12;
- buf[10] = 0x00;
- buf[11] = 0x00;
-
- /* Claim PLAY_AUDIO capability (0x01) since some Linux
- code checks for this to automount media. */
- buf[12] = 0x71;
- buf[13] = 3 << 5;
- buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
- if (bdrv_is_locked(s->bs))
- buf[6] |= 1 << 1;
- buf[15] = 0x00;
- cpu_to_ube16(&buf[16], 706);
- buf[18] = 0;
- buf[19] = 2;
- cpu_to_ube16(&buf[20], 512);
- cpu_to_ube16(&buf[22], 706);
- buf[24] = 0;
- buf[25] = 0;
- buf[26] = 0;
- buf[27] = 0;
- ide_atapi_cmd_reply(s, 28, max_len);
- break;
- default:
- goto error_cmd;
- }
- break;
- case 1: /* changeable values */
- goto error_cmd;
- case 2: /* default values */
- goto error_cmd;
- default:
- case 3: /* saved values */
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
- break;
- }
- }
- break;
- case GPCMD_REQUEST_SENSE:
- max_len = packet[4];
- memset(buf, 0, 18);
- buf[0] = 0x70 | (1 << 7);
- buf[2] = s->sense_key;
- buf[7] = 10;
- buf[12] = s->asc;
- if (s->sense_key == SENSE_UNIT_ATTENTION)
- s->sense_key = SENSE_NONE;
- ide_atapi_cmd_reply(s, 18, max_len);
- break;
- case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
- bdrv_set_locked(s->bs, packet[4] & 1);
- ide_atapi_cmd_ok(s);
- break;
- case GPCMD_READ_10:
- case GPCMD_READ_12:
- {
- int nb_sectors, lba;
-
- if (packet[0] == GPCMD_READ_10)
- nb_sectors = ube16_to_cpu(packet + 7);
- else
- nb_sectors = ube32_to_cpu(packet + 6);
- lba = ube32_to_cpu(packet + 2);
- if (nb_sectors == 0) {
- ide_atapi_cmd_ok(s);
- break;
- }
- ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
- }
- break;
- case GPCMD_READ_CD:
- {
- int nb_sectors, lba, transfer_request;
-
- nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
- lba = ube32_to_cpu(packet + 2);
- if (nb_sectors == 0) {
- ide_atapi_cmd_ok(s);
- break;
- }
- transfer_request = packet[9];
- switch(transfer_request & 0xf8) {
- case 0x00:
- /* nothing */
- ide_atapi_cmd_ok(s);
- break;
- case 0x10:
- /* normal read */
- ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
- break;
- case 0xf8:
- /* read all data */
- ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
- break;
- default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
- break;
- case GPCMD_SEEK:
- {
- unsigned int lba;
- uint64_t total_sectors;
-
- bdrv_get_geometry(s->bs, &total_sectors);
- total_sectors >>= 2;
- if (total_sectors == 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- lba = ube32_to_cpu(packet + 2);
- if (lba >= total_sectors) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_LOGICAL_BLOCK_OOR);
- break;
- }
- ide_atapi_cmd_ok(s);
- }
- break;
- case GPCMD_START_STOP_UNIT:
- {
- int start, eject, sense, err = 0;
- start = packet[4] & 1;
- eject = (packet[4] >> 1) & 1;
-
- if (eject) {
- err = bdrv_eject(s->bs, !start);
- }
-
- switch (err) {
- case 0:
- ide_atapi_cmd_ok(s);
- break;
- case -EBUSY:
- sense = SENSE_NOT_READY;
- if (bdrv_is_inserted(s->bs)) {
- sense = SENSE_ILLEGAL_REQUEST;
- }
- ide_atapi_cmd_error(s, sense,
- ASC_MEDIA_REMOVAL_PREVENTED);
- break;
- default:
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- }
- break;
- case GPCMD_MECHANISM_STATUS:
- {
- max_len = ube16_to_cpu(packet + 8);
- cpu_to_ube16(buf, 0);
- /* no current LBA */
- buf[2] = 0;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 1;
- cpu_to_ube16(buf + 6, 0);
- ide_atapi_cmd_reply(s, 8, max_len);
- }
- break;
- case GPCMD_READ_TOC_PMA_ATIP:
- {
- int format, msf, start_track, len;
- uint64_t total_sectors;
-
- bdrv_get_geometry(s->bs, &total_sectors);
- total_sectors >>= 2;
- if (total_sectors == 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- max_len = ube16_to_cpu(packet + 7);
- format = packet[9] >> 6;
- msf = (packet[1] >> 1) & 1;
- start_track = packet[6];
- switch(format) {
- case 0:
- len = cdrom_read_toc(total_sectors, buf, msf, start_track);
- if (len < 0)
- goto error_cmd;
- ide_atapi_cmd_reply(s, len, max_len);
- break;
- case 1:
- /* multi session : only a single session defined */
- memset(buf, 0, 12);
- buf[1] = 0x0a;
- buf[2] = 0x01;
- buf[3] = 0x01;
- ide_atapi_cmd_reply(s, 12, max_len);
- break;
- case 2:
- len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
- if (len < 0)
- goto error_cmd;
- ide_atapi_cmd_reply(s, len, max_len);
- break;
- default:
- error_cmd:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
- break;
- case GPCMD_READ_CDVD_CAPACITY:
- {
- uint64_t total_sectors;
-
- bdrv_get_geometry(s->bs, &total_sectors);
- total_sectors >>= 2;
- if (total_sectors == 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- /* NOTE: it is really the number of sectors minus 1 */
- cpu_to_ube32(buf, total_sectors - 1);
- cpu_to_ube32(buf + 4, 2048);
- ide_atapi_cmd_reply(s, 8, 8);
- }
- break;
- case GPCMD_READ_DVD_STRUCTURE:
- {
- int media = packet[1];
- int format = packet[7];
- int ret;
-
- max_len = ube16_to_cpu(packet + 8);
-
- if (format < 0xff) {
- if (media_is_cd(s)) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INCOMPATIBLE_FORMAT);
- break;
- } else if (!media_present(s)) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
-
- memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
- IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
-
- switch (format) {
- case 0x00 ... 0x7f:
- case 0xff:
- if (media == 0) {
- ret = ide_dvd_read_structure(s, format, packet, buf);
-
- if (ret < 0)
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
- else
- ide_atapi_cmd_reply(s, ret, max_len);
-
- break;
- }
- /* TODO: BD support, fall through for now */
-
- /* Generic disk structures */
- case 0x80: /* TODO: AACS volume identifier */
- case 0x81: /* TODO: AACS media serial number */
- case 0x82: /* TODO: AACS media identifier */
- case 0x83: /* TODO: AACS media key block */
- case 0x90: /* TODO: List of recognized format layers */
- case 0xc0: /* TODO: Write protection status */
- default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
- break;
- case GPCMD_SET_SPEED:
- ide_atapi_cmd_ok(s);
- break;
- case GPCMD_INQUIRY:
- max_len = packet[4];
- buf[0] = 0x05; /* CD-ROM */
- buf[1] = 0x80; /* removable */
- buf[2] = 0x00; /* ISO */
- buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
- buf[4] = 31; /* additional length */
- buf[5] = 0; /* reserved */
- buf[6] = 0; /* reserved */
- buf[7] = 0; /* reserved */
- padstr8(buf + 8, 8, "QEMU");
- padstr8(buf + 16, 16, "QEMU DVD-ROM");
- padstr8(buf + 32, 4, s->version);
- ide_atapi_cmd_reply(s, 36, max_len);
- break;
- case GPCMD_GET_CONFIGURATION:
- {
- uint32_t len;
- uint8_t index = 0;
-
- /* only feature 0 is supported */
- if (packet[2] != 0 || packet[3] != 0) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
-
- /* XXX: could result in alignment problems in some architectures */
- max_len = ube16_to_cpu(packet + 7);
-
- /*
- * XXX: avoid overflow for io_buffer if max_len is bigger than
- * the size of that buffer (dimensioned to max number of
- * sectors to transfer at once)
- *
- * Only a problem if the feature/profiles grow.
- */
- if (max_len > 512) /* XXX: assume 1 sector */
- max_len = 512;
-
- memset(buf, 0, max_len);
- /*
- * the number of sectors from the media tells us which profile
- * to use as current. 0 means there is no media
- */
- if (media_is_dvd(s))
- cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
- else if (media_is_cd(s))
- cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
-
- buf[10] = 0x02 | 0x01; /* persistent and current */
- len = 12; /* headers: 8 + 4 */
- len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
- len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
- cpu_to_ube32(buf, len - 4); /* data length */
-
- ide_atapi_cmd_reply(s, len, max_len);
- break;
- }
- case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
- handle_get_event_status_notification(s, buf, packet);
- break;
- default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_ILLEGAL_OPCODE);
- break;
- }
-}
-
static void ide_cfata_metadata_inquiry(IDEState *s)
{
uint16_t *p;
@@ -1734,8 +684,13 @@ static void cdrom_change_cb(void *opaque, int reason)
bdrv_get_geometry(s->bs, &nb_sectors);
s->nb_sectors = nb_sectors;
- s->sense_key = SENSE_UNIT_ATTENTION;
- s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
+ /*
+ * First indicate to the guest that a CD has been removed. That's
+ * done on the next command the guest sends us.
+ *
+ * Then we set SENSE_UNIT_ATTENTION, by which the guest will
+ * detect a new CD in the drive. See ide_atapi_cmd() for details.
+ */
s->cdrom_changed = 1;
s->events.new_media = true;
ide_set_irq(s->bus);
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index f242d7a81..a3d475c59 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -67,7 +67,6 @@
#include <hw/isa.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/pci.h>
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index ba7e9a8ee..aa198b6b1 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -9,6 +9,7 @@
#include <hw/ide.h>
#include "block_int.h"
#include "iorange.h"
+#include "dma.h"
/* debug IDE devices */
//#define DEBUG_IDE
@@ -570,6 +571,15 @@ void ide_sector_write(IDEState *s);
void ide_sector_read(IDEState *s);
void ide_flush_cache(IDEState *s);
+void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
+ EndTransferFunc *end_transfer_func);
+void ide_transfer_stop(IDEState *s);
+void ide_set_inactive(IDEState *s);
+
+/* hw/ide/atapi.c */
+void ide_atapi_cmd(IDEState *s);
+void ide_atapi_cmd_reply_end(IDEState *s);
+
/* hw/ide/qdev.c */
void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id);
IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 8c59c5a47..4ac745324 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -27,7 +27,6 @@
#include <hw/isa.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index c1b4caab5..7107f6b3c 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -27,7 +27,6 @@
#include <hw/mac_dbdma.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index 2ceeb87c0..9fbbf0e78 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -27,7 +27,6 @@
#include <hw/pcmcia.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index 82b24b673..10f6f4063 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -25,7 +25,6 @@
#include <hw/hw.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 35168cb46..65cb56c38 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -28,7 +28,6 @@
#include <hw/isa.h>
#include "block.h"
#include "block_int.h"
-#include "sysemu.h"
#include "dma.h"
#include <hw/ide/pci.h>
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index b04994082..a6c27be82 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -10,7 +10,6 @@
#include "sysbus.h"
#include "primecell.h"
#include "devices.h"
-#include "sysemu.h"
#include "boards.h"
#include "arm-misc.h"
#include "net.h"
diff --git a/hw/ioapic.c b/hw/ioapic.c
index e806822d9..2ac612711 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -163,8 +163,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
s->irr &= ~mask;
}
} else {
- /* edge triggered */
- if (level) {
+ /* According to the 82093AA manual, we must ignore edge requests
+ * if the input pin is masked. */
+ if (level && !(entry & IOAPIC_LVT_MASKED)) {
s->irr |= mask;
ioapic_service(s);
}
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index d07aa410f..27655436a 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -17,7 +17,6 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw.h"
-#include "sysemu.h"
#include "monitor.h"
#include "sysbus.h"
#include "isa.h"
diff --git a/hw/kvmclock.c b/hw/kvmclock.c
index b6ceddfba..004c4add8 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -103,7 +103,11 @@ static SysBusDeviceInfo kvmclock_info = {
void kvmclock_create(void)
{
if (kvm_enabled() &&
- first_cpu->cpuid_kvm_features & (1ULL << KVM_FEATURE_CLOCKSOURCE)) {
+ first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE)
+#ifdef KVM_FEATURE_CLOCKSOURCE2
+ || (1ULL << KVM_FEATURE_CLOCKSOURCE2)
+#endif
+ )) {
sysbus_create_simple("kvmclock", -1, NULL);
}
}
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index 85190f0bf..64629230c 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -21,7 +21,6 @@
#include "hw.h"
#include "net.h"
#include "flash.h"
-#include "sysemu.h"
#include "devices.h"
#include "boards.h"
#include "loader.h"
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 9f39d6bbf..537c0f7b1 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -585,28 +585,18 @@ static CPUReadMemoryFunc * const nvram_read[] = {
&nvram_readl,
};
-static void m48t59_save(QEMUFile *f, void *opaque)
-{
- M48t59State *s = opaque;
-
- qemu_put_8s(f, &s->lock);
- qemu_put_be16s(f, &s->addr);
- qemu_put_buffer(f, s->buffer, s->size);
-}
-
-static int m48t59_load(QEMUFile *f, void *opaque, int version_id)
-{
- M48t59State *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_8s(f, &s->lock);
- qemu_get_be16s(f, &s->addr);
- qemu_get_buffer(f, s->buffer, s->size);
-
- return 0;
-}
+static const VMStateDescription vmstate_m48t59 = {
+ .name = "m48t59",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(lock, M48t59State),
+ VMSTATE_UINT16(addr, M48t59State),
+ VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, 0, size),
+ VMSTATE_END_OF_LIST()
+ }
+};
static void m48t59_reset_common(M48t59State *NVRAM)
{
@@ -696,7 +686,7 @@ static void m48t59_init_common(M48t59State *s)
}
qemu_get_timedate(&s->alarm, 0);
- register_savevm(NULL, "m48t59", -1, 1, m48t59_save, m48t59_load, s);
+ vmstate_register(NULL, -1, &vmstate_m48t59, s);
}
static int m48t59_init_isa1(ISADevice *dev)
diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index 5680fa9c1..ed4458e3b 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -165,6 +165,10 @@ typedef struct DBDMA_channel {
int processing;
} DBDMA_channel;
+typedef struct {
+ DBDMA_channel channels[DBDMA_CHANNELS];
+} DBDMAState;
+
#ifdef DEBUG_DBDMA
static void dump_dbdma_cmd(dbdma_cmd *cmd)
{
@@ -617,31 +621,34 @@ static void channel_run(DBDMA_channel *ch)
}
}
-static void DBDMA_run (DBDMA_channel *ch)
+static void DBDMA_run(DBDMAState *s)
{
int channel;
- for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {
- uint32_t status = ch->regs[DBDMA_STATUS];
- if (!ch->processing && (status & RUN) && (status & ACTIVE))
- channel_run(ch);
+ for (channel = 0; channel < DBDMA_CHANNELS; channel++) {
+ DBDMA_channel *ch = &s->channels[channel];
+ uint32_t status = ch->regs[DBDMA_STATUS];
+ if (!ch->processing && (status & RUN) && (status & ACTIVE)) {
+ channel_run(ch);
+ }
}
}
static void DBDMA_run_bh(void *opaque)
{
- DBDMA_channel *ch = opaque;
+ DBDMAState *s = opaque;
DBDMA_DPRINTF("DBDMA_run_bh\n");
- DBDMA_run(ch);
+ DBDMA_run(s);
}
void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
DBDMA_rw rw, DBDMA_flush flush,
void *opaque)
{
- DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan;
+ DBDMAState *s = dbdma;
+ DBDMA_channel *ch = &s->channels[nchan];
DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);
@@ -700,7 +707,8 @@ static void dbdma_writel (void *opaque,
target_phys_addr_t addr, uint32_t value)
{
int channel = addr >> DBDMA_CHANNEL_SHIFT;
- DBDMA_channel *ch = (DBDMA_channel *)opaque + channel;
+ DBDMAState *s = opaque;
+ DBDMA_channel *ch = &s->channels[channel];
int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value);
@@ -749,7 +757,8 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
{
uint32_t value;
int channel = addr >> DBDMA_CHANNEL_SHIFT;
- DBDMA_channel *ch = (DBDMA_channel *)opaque + channel;
+ DBDMAState *s = opaque;
+ DBDMA_channel *ch = &s->channels[channel];
int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
value = ch->regs[reg];
@@ -801,49 +810,47 @@ static CPUReadMemoryFunc * const dbdma_read[] = {
dbdma_readl,
};
-static void dbdma_save(QEMUFile *f, void *opaque)
-{
- DBDMA_channel *s = opaque;
- unsigned int i, j;
-
- for (i = 0; i < DBDMA_CHANNELS; i++)
- for (j = 0; j < DBDMA_REGS; j++)
- qemu_put_be32s(f, &s[i].regs[j]);
-}
-
-static int dbdma_load(QEMUFile *f, void *opaque, int version_id)
-{
- DBDMA_channel *s = opaque;
- unsigned int i, j;
-
- if (version_id != 2)
- return -EINVAL;
-
- for (i = 0; i < DBDMA_CHANNELS; i++)
- for (j = 0; j < DBDMA_REGS; j++)
- qemu_get_be32s(f, &s[i].regs[j]);
+static const VMStateDescription vmstate_dbdma_channel = {
+ .name = "dbdma_channel",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS),
+ VMSTATE_END_OF_LIST()
+ }
+};
- return 0;
-}
+static const VMStateDescription vmstate_dbdma = {
+ .name = "dbdma",
+ .version_id = 2,
+ .minimum_version_id = 2,
+ .minimum_version_id_old = 2,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1,
+ vmstate_dbdma_channel, DBDMA_channel),
+ VMSTATE_END_OF_LIST()
+ }
+};
static void dbdma_reset(void *opaque)
{
- DBDMA_channel *s = opaque;
+ DBDMAState *s = opaque;
int i;
for (i = 0; i < DBDMA_CHANNELS; i++)
- memset(s[i].regs, 0, DBDMA_SIZE);
+ memset(s->channels[i].regs, 0, DBDMA_SIZE);
}
void* DBDMA_init (int *dbdma_mem_index)
{
- DBDMA_channel *s;
+ DBDMAState *s;
- s = qemu_mallocz(sizeof(DBDMA_channel) * DBDMA_CHANNELS);
+ s = qemu_mallocz(sizeof(DBDMAState));
*dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s,
DEVICE_LITTLE_ENDIAN);
- register_savevm(NULL, "dbdma", -1, 1, dbdma_save, dbdma_load, s);
+ vmstate_register(NULL, -1, &vmstate_dbdma, s);
qemu_register_reset(dbdma_reset, s);
dbdma_bh = qemu_bh_new(DBDMA_run_bh, s);
diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index c2a2fc21e..61e53d28b 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -38,7 +38,7 @@
#endif
struct MacIONVRAMState {
- target_phys_addr_t size;
+ uint32_t size;
int mem_index;
unsigned int it_shift;
uint8_t *data;
@@ -105,24 +105,17 @@ static CPUReadMemoryFunc * const nvram_read[] = {
&macio_nvram_readb,
};
-static void macio_nvram_save(QEMUFile *f, void *opaque)
-{
- MacIONVRAMState *s = (MacIONVRAMState *)opaque;
-
- qemu_put_buffer(f, s->data, s->size);
-}
-
-static int macio_nvram_load(QEMUFile *f, void *opaque, int version_id)
-{
- MacIONVRAMState *s = (MacIONVRAMState *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_buffer(f, s->data, s->size);
+static const VMStateDescription vmstate_macio_nvram = {
+ .name = "macio_nvram",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_VBUFFER_UINT32(data, MacIONVRAMState, 0, NULL, 0, size),
+ VMSTATE_END_OF_LIST()
+ }
+};
- return 0;
-}
static void macio_nvram_reset(void *opaque)
{
@@ -141,8 +134,7 @@ MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s,
DEVICE_NATIVE_ENDIAN);
*mem_index = s->mem_index;
- register_savevm(NULL, "macio_nvram", -1, 1, macio_nvram_save,
- macio_nvram_load, s);
+ vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
qemu_register_reset(macio_nvram_reset, s);
return s;
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 50691ca41..4792f0e3e 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -14,7 +14,6 @@
#include "net.h"
#include "devices.h"
#include "boards.h"
-#include "sysemu.h"
#include "flash.h"
#include "blockdev.h"
#include "sysbus.h"
diff --git a/hw/max111x.c b/hw/max111x.c
index 2844665ba..70cd1af24 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -15,7 +15,7 @@ typedef struct {
uint8_t tb1, rb2, rb3;
int cycle;
- int input[8];
+ uint8_t input[8];
int inputs, com;
} MAX111xState;
@@ -94,36 +94,22 @@ static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
return max111x_read(s);
}
-static void max111x_save(QEMUFile *f, void *opaque)
-{
- MAX111xState *s = (MAX111xState *) opaque;
- int i;
-
- qemu_put_8s(f, &s->tb1);
- qemu_put_8s(f, &s->rb2);
- qemu_put_8s(f, &s->rb3);
- qemu_put_be32(f, s->inputs);
- qemu_put_be32(f, s->com);
- for (i = 0; i < s->inputs; i ++)
- qemu_put_byte(f, s->input[i]);
-}
-
-static int max111x_load(QEMUFile *f, void *opaque, int version_id)
-{
- MAX111xState *s = (MAX111xState *) opaque;
- int i;
-
- qemu_get_8s(f, &s->tb1);
- qemu_get_8s(f, &s->rb2);
- qemu_get_8s(f, &s->rb3);
- if (s->inputs != qemu_get_be32(f))
- return -EINVAL;
- s->com = qemu_get_be32(f);
- for (i = 0; i < s->inputs; i ++)
- s->input[i] = qemu_get_byte(f);
-
- return 0;
-}
+static const VMStateDescription vmstate_max111x = {
+ .name = "max111x",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(tb1, MAX111xState),
+ VMSTATE_UINT8(rb2, MAX111xState),
+ VMSTATE_UINT8(rb3, MAX111xState),
+ VMSTATE_INT32_EQUAL(inputs, MAX111xState),
+ VMSTATE_INT32(com, MAX111xState),
+ VMSTATE_ARRAY_INT32_UNSAFE(input, MAX111xState, inputs,
+ vmstate_info_uint8, uint8_t),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int max111x_init(SSISlave *dev, int inputs)
{
@@ -143,8 +129,7 @@ static int max111x_init(SSISlave *dev, int inputs)
s->input[7] = 0x80;
s->com = 0;
- register_savevm(&dev->qdev, "max111x", -1, 0,
- max111x_save, max111x_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_max111x, s);
return 0;
}
diff --git a/hw/milkymist-hw.h b/hw/milkymist-hw.h
index 15acdbccd..20de68ecc 100644
--- a/hw/milkymist-hw.h
+++ b/hw/milkymist-hw.h
@@ -1,6 +1,9 @@
#ifndef QEMU_HW_MILKYMIST_H
#define QEMU_HW_MILKYMIST_H
+#include "qdev.h"
+#include "qdev-addr.h"
+
static inline DeviceState *milkymist_uart_create(target_phys_addr_t base,
qemu_irq rx_irq, qemu_irq tx_irq)
{
@@ -183,6 +186,23 @@ static inline DeviceState *milkymist_minimac_create(target_phys_addr_t base,
return dev;
}
+static inline DeviceState *milkymist_minimac2_create(target_phys_addr_t base,
+ target_phys_addr_t buffers_base, qemu_irq rx_irq, qemu_irq tx_irq)
+{
+ DeviceState *dev;
+
+ qemu_check_nic_model(&nd_table[0], "minimac2");
+ dev = qdev_create(NULL, "milkymist-minimac2");
+ qdev_prop_set_taddr(dev, "buffers_base", buffers_base);
+ qdev_set_nic_properties(dev, &nd_table[0]);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+ sysbus_connect_irq(sysbus_from_qdev(dev), 0, rx_irq);
+ sysbus_connect_irq(sysbus_from_qdev(dev), 1, tx_irq);
+
+ return dev;
+}
+
static inline DeviceState *milkymist_softusb_create(target_phys_addr_t base,
qemu_irq irq, uint32_t pmem_base, uint32_t pmem_size,
uint32_t dmem_base, uint32_t dmem_size)
diff --git a/hw/milkymist-minimac.c b/hw/milkymist-minimac2.c
index b07f18d8a..c4e28187b 100644
--- a/hw/milkymist-minimac.c
+++ b/hw/milkymist-minimac2.c
@@ -1,7 +1,7 @@
/*
- * QEMU model of the Milkymist minimac block.
+ * QEMU model of the Milkymist minimac2 block.
*
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ * Copyright (c) 2011 Michael Walle <michael@walle.cc>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,7 +18,7 @@
*
*
* Specification available at:
- * http://www.milkymist.org/socdoc/minimac.pdf
+ * not available yet
*
*/
@@ -27,6 +27,7 @@
#include "trace.h"
#include "net.h"
#include "qemu-error.h"
+#include "qdev-addr.h"
#include <zlib.h>
@@ -34,25 +35,15 @@ enum {
R_SETUP = 0,
R_MDIO,
R_STATE0,
- R_ADDR0,
R_COUNT0,
R_STATE1,
- R_ADDR1,
R_COUNT1,
- R_STATE2,
- R_ADDR2,
- R_COUNT2,
- R_STATE3,
- R_ADDR3,
- R_COUNT3,
- R_TXADDR,
R_TXCOUNT,
R_MAX
};
enum {
- SETUP_RX_RST = (1<<0),
- SETUP_TX_RST = (1<<2),
+ SETUP_PHY_RST = (1<<0),
};
enum {
@@ -85,9 +76,10 @@ enum {
R_PHY_MAX = 32
};
-#define MINIMAC_MTU 1530
+#define MINIMAC2_MTU 1530
+#define MINIMAC2_BUFFER_SIZE 2048
-struct MilkymistMinimacMdioState {
+struct MilkymistMinimac2MdioState {
int last_clk;
int count;
uint32_t data;
@@ -97,50 +89,55 @@ struct MilkymistMinimacMdioState {
uint8_t phy_addr;
uint8_t reg_addr;
};
-typedef struct MilkymistMinimacMdioState MilkymistMinimacMdioState;
+typedef struct MilkymistMinimac2MdioState MilkymistMinimac2MdioState;
-struct MilkymistMinimacState {
+struct MilkymistMinimac2State {
SysBusDevice busdev;
NICState *nic;
NICConf conf;
char *phy_model;
+ target_phys_addr_t buffers_base;
qemu_irq rx_irq;
qemu_irq tx_irq;
uint32_t regs[R_MAX];
- MilkymistMinimacMdioState mdio;
+ MilkymistMinimac2MdioState mdio;
uint16_t phy_regs[R_PHY_MAX];
+
+ uint8_t *rx0_buf;
+ uint8_t *rx1_buf;
+ uint8_t *tx_buf;
};
-typedef struct MilkymistMinimacState MilkymistMinimacState;
+typedef struct MilkymistMinimac2State MilkymistMinimac2State;
static const uint8_t preamble_sfd[] = {
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5
};
-static void minimac_mdio_write_reg(MilkymistMinimacState *s,
+static void minimac2_mdio_write_reg(MilkymistMinimac2State *s,
uint8_t phy_addr, uint8_t reg_addr, uint16_t value)
{
- trace_milkymist_minimac_mdio_write(phy_addr, reg_addr, value);
+ trace_milkymist_minimac2_mdio_write(phy_addr, reg_addr, value);
/* nop */
}
-static uint16_t minimac_mdio_read_reg(MilkymistMinimacState *s,
+static uint16_t minimac2_mdio_read_reg(MilkymistMinimac2State *s,
uint8_t phy_addr, uint8_t reg_addr)
{
uint16_t r = s->phy_regs[reg_addr];
- trace_milkymist_minimac_mdio_read(phy_addr, reg_addr, r);
+ trace_milkymist_minimac2_mdio_read(phy_addr, reg_addr, r);
return r;
}
-static void minimac_update_mdio(MilkymistMinimacState *s)
+static void minimac2_update_mdio(MilkymistMinimac2State *s)
{
- MilkymistMinimacMdioState *m = &s->mdio;
+ MilkymistMinimac2MdioState *m = &s->mdio;
/* detect rising clk edge */
if (m->last_clk == 0 && (s->regs[R_MDIO] & MDIO_CLK)) {
@@ -173,7 +170,7 @@ static void minimac_update_mdio(MilkymistMinimacState *s)
}
if (m->state == MDIO_STATE_READING) {
- m->data_out = minimac_mdio_read_reg(s, m->phy_addr,
+ m->data_out = minimac2_mdio_read_reg(s, m->phy_addr,
m->reg_addr);
}
}
@@ -192,7 +189,7 @@ static void minimac_update_mdio(MilkymistMinimacState *s)
if (m->count == 0 && m->state) {
if (m->state == MDIO_STATE_WRITING) {
uint16_t data = m->data & 0xffff;
- minimac_mdio_write_reg(s, m->phy_addr, m->reg_addr, data);
+ minimac2_mdio_write_reg(s, m->phy_addr, m->reg_addr, data);
}
m->state = MDIO_STATE_IDLE;
}
@@ -208,7 +205,7 @@ static size_t assemble_frame(uint8_t *buf, size_t size,
uint32_t crc;
if (size < payload_size + 12) {
- error_report("milkymist_minimac: received too big ethernet frame");
+ error_report("milkymist_minimac2: received too big ethernet frame");
return 0;
}
@@ -231,115 +228,102 @@ static size_t assemble_frame(uint8_t *buf, size_t size,
return payload_size + 12;
}
-static void minimac_tx(MilkymistMinimacState *s)
+static void minimac2_tx(MilkymistMinimac2State *s)
{
- uint8_t buf[MINIMAC_MTU];
uint32_t txcount = s->regs[R_TXCOUNT];
-
- /* do nothing if transmission logic is in reset */
- if (s->regs[R_SETUP] & SETUP_TX_RST) {
- return;
- }
+ uint8_t *buf = s->tx_buf;
if (txcount < 64) {
- error_report("milkymist_minimac: ethernet frame too small (%u < %u)\n",
+ error_report("milkymist_minimac2: ethernet frame too small (%u < %u)\n",
txcount, 64);
- return;
+ goto err;
}
- if (txcount > MINIMAC_MTU) {
- error_report("milkymist_minimac: MTU exceeded (%u > %u)\n",
- txcount, MINIMAC_MTU);
- return;
+ if (txcount > MINIMAC2_MTU) {
+ error_report("milkymist_minimac2: MTU exceeded (%u > %u)\n",
+ txcount, MINIMAC2_MTU);
+ goto err;
}
- /* dma */
- cpu_physical_memory_read(s->regs[R_TXADDR], buf, txcount);
-
if (memcmp(buf, preamble_sfd, 8) != 0) {
- error_report("milkymist_minimac: frame doesn't contain the preamble "
+ error_report("milkymist_minimac2: frame doesn't contain the preamble "
"and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
- return;
+ goto err;
}
- trace_milkymist_minimac_tx_frame(txcount - 12);
+ trace_milkymist_minimac2_tx_frame(txcount - 12);
/* send packet, skipping preamble and sfd */
qemu_send_packet_raw(&s->nic->nc, buf + 8, txcount - 12);
s->regs[R_TXCOUNT] = 0;
- trace_milkymist_minimac_pulse_irq_tx();
+err:
+ trace_milkymist_minimac2_pulse_irq_tx();
qemu_irq_pulse(s->tx_irq);
}
-static ssize_t minimac_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
+static void update_rx_interrupt(MilkymistMinimac2State *s)
+{
+ if (s->regs[R_STATE0] == STATE_PENDING
+ || s->regs[R_STATE1] == STATE_PENDING) {
+ trace_milkymist_minimac2_raise_irq_rx();
+ qemu_irq_raise(s->rx_irq);
+ } else {
+ trace_milkymist_minimac2_lower_irq_rx();
+ qemu_irq_lower(s->rx_irq);
+ }
+}
+
+static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
{
- MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+ MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
- uint32_t r_addr;
uint32_t r_count;
uint32_t r_state;
+ uint8_t *rx_buf;
- uint8_t frame_buf[MINIMAC_MTU];
size_t frame_size;
- trace_milkymist_minimac_rx_frame(buf, size);
-
- /* discard frames if nic is in reset */
- if (s->regs[R_SETUP] & SETUP_RX_RST) {
- return size;
- }
+ trace_milkymist_minimac2_rx_frame(buf, size);
/* choose appropriate slot */
if (s->regs[R_STATE0] == STATE_LOADED) {
- r_addr = R_ADDR0;
r_count = R_COUNT0;
r_state = R_STATE0;
+ rx_buf = s->rx0_buf;
} else if (s->regs[R_STATE1] == STATE_LOADED) {
- r_addr = R_ADDR1;
r_count = R_COUNT1;
r_state = R_STATE1;
- } else if (s->regs[R_STATE2] == STATE_LOADED) {
- r_addr = R_ADDR2;
- r_count = R_COUNT2;
- r_state = R_STATE2;
- } else if (s->regs[R_STATE3] == STATE_LOADED) {
- r_addr = R_ADDR3;
- r_count = R_COUNT3;
- r_state = R_STATE3;
+ rx_buf = s->rx1_buf;
} else {
- trace_milkymist_minimac_drop_rx_frame(buf);
+ trace_milkymist_minimac2_drop_rx_frame(buf);
return size;
}
/* assemble frame */
- frame_size = assemble_frame(frame_buf, sizeof(frame_buf), buf, size);
+ frame_size = assemble_frame(rx_buf, MINIMAC2_BUFFER_SIZE, buf, size);
if (frame_size == 0) {
return size;
}
- trace_milkymist_minimac_rx_transfer(buf, frame_size);
-
- /* do dma */
- cpu_physical_memory_write(s->regs[r_addr], frame_buf, frame_size);
+ trace_milkymist_minimac2_rx_transfer(rx_buf, frame_size);
/* update slot */
s->regs[r_count] = frame_size;
s->regs[r_state] = STATE_PENDING;
- trace_milkymist_minimac_pulse_irq_rx();
- qemu_irq_pulse(s->rx_irq);
+ update_rx_interrupt(s);
return size;
}
static uint32_t
-minimac_read(void *opaque, target_phys_addr_t addr)
+minimac2_read(void *opaque, target_phys_addr_t addr)
{
- MilkymistMinimacState *s = opaque;
+ MilkymistMinimac2State *s = opaque;
uint32_t r = 0;
addr >>= 2;
@@ -347,39 +331,30 @@ minimac_read(void *opaque, target_phys_addr_t addr)
case R_SETUP:
case R_MDIO:
case R_STATE0:
- case R_ADDR0:
case R_COUNT0:
case R_STATE1:
- case R_ADDR1:
case R_COUNT1:
- case R_STATE2:
- case R_ADDR2:
- case R_COUNT2:
- case R_STATE3:
- case R_ADDR3:
- case R_COUNT3:
- case R_TXADDR:
case R_TXCOUNT:
r = s->regs[addr];
break;
default:
- error_report("milkymist_minimac: read access to unknown register 0x"
+ error_report("milkymist_minimac2: read access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
- trace_milkymist_minimac_memory_read(addr << 2, r);
+ trace_milkymist_minimac2_memory_read(addr << 2, r);
return r;
}
static void
-minimac_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
{
- MilkymistMinimacState *s = opaque;
+ MilkymistMinimac2State *s = opaque;
- trace_milkymist_minimac_memory_read(addr, value);
+ trace_milkymist_minimac2_memory_read(addr, value);
addr >>= 2;
switch (addr) {
@@ -394,58 +369,47 @@ minimac_write(void *opaque, target_phys_addr_t addr, uint32_t value)
s->regs[R_MDIO] &= ~mdio_di;
}
- minimac_update_mdio(s);
+ minimac2_update_mdio(s);
} break;
case R_TXCOUNT:
s->regs[addr] = value;
if (value > 0) {
- minimac_tx(s);
+ minimac2_tx(s);
}
break;
- case R_SETUP:
case R_STATE0:
- case R_ADDR0:
- case R_COUNT0:
case R_STATE1:
- case R_ADDR1:
+ s->regs[addr] = value;
+ update_rx_interrupt(s);
+ break;
+ case R_SETUP:
+ case R_COUNT0:
case R_COUNT1:
- case R_STATE2:
- case R_ADDR2:
- case R_COUNT2:
- case R_STATE3:
- case R_ADDR3:
- case R_COUNT3:
- case R_TXADDR:
s->regs[addr] = value;
break;
default:
- error_report("milkymist_minimac: write access to unknown register 0x"
+ error_report("milkymist_minimac2: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
}
-static CPUReadMemoryFunc * const minimac_read_fn[] = {
+static CPUReadMemoryFunc * const minimac2_read_fn[] = {
NULL,
NULL,
- &minimac_read,
+ &minimac2_read,
};
-static CPUWriteMemoryFunc * const minimac_write_fn[] = {
+static CPUWriteMemoryFunc * const minimac2_write_fn[] = {
NULL,
NULL,
- &minimac_write,
+ &minimac2_write,
};
-static int minimac_can_rx(VLANClientState *nc)
+static int minimac2_can_rx(VLANClientState *nc)
{
- MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
-
- /* discard frames if nic is in reset */
- if (s->regs[R_SETUP] & SETUP_RX_RST) {
- return 1;
- }
+ MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
if (s->regs[R_STATE0] == STATE_LOADED) {
return 1;
@@ -453,27 +417,21 @@ static int minimac_can_rx(VLANClientState *nc)
if (s->regs[R_STATE1] == STATE_LOADED) {
return 1;
}
- if (s->regs[R_STATE2] == STATE_LOADED) {
- return 1;
- }
- if (s->regs[R_STATE3] == STATE_LOADED) {
- return 1;
- }
return 0;
}
-static void minimac_cleanup(VLANClientState *nc)
+static void minimac2_cleanup(VLANClientState *nc)
{
- MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+ MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
s->nic = NULL;
}
-static void milkymist_minimac_reset(DeviceState *d)
+static void milkymist_minimac2_reset(DeviceState *d)
{
- MilkymistMinimacState *s =
- container_of(d, MilkymistMinimacState, busdev.qdev);
+ MilkymistMinimac2State *s =
+ container_of(d, MilkymistMinimac2State, busdev.qdev);
int i;
for (i = 0; i < R_MAX; i++) {
@@ -488,81 +446,94 @@ static void milkymist_minimac_reset(DeviceState *d)
s->phy_regs[R_PHY_ID2] = 0x161a;
}
-static NetClientInfo net_milkymist_minimac_info = {
+static NetClientInfo net_milkymist_minimac2_info = {
.type = NET_CLIENT_TYPE_NIC,
.size = sizeof(NICState),
- .can_receive = minimac_can_rx,
- .receive = minimac_rx,
- .cleanup = minimac_cleanup,
+ .can_receive = minimac2_can_rx,
+ .receive = minimac2_rx,
+ .cleanup = minimac2_cleanup,
};
-static int milkymist_minimac_init(SysBusDevice *dev)
+static int milkymist_minimac2_init(SysBusDevice *dev)
{
- MilkymistMinimacState *s = FROM_SYSBUS(typeof(*s), dev);
+ MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev);
int regs;
+ ram_addr_t buffers;
+ size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
sysbus_init_irq(dev, &s->rx_irq);
sysbus_init_irq(dev, &s->tx_irq);
- regs = cpu_register_io_memory(minimac_read_fn, minimac_write_fn, s,
+ regs = cpu_register_io_memory(minimac2_read_fn, minimac2_write_fn, s,
DEVICE_NATIVE_ENDIAN);
sysbus_init_mmio(dev, R_MAX * 4, regs);
+ /* register buffers memory */
+ buffers = qemu_ram_alloc(NULL, "milkymist_minimac2.buffers", buffers_size);
+ s->rx0_buf = qemu_get_ram_ptr(buffers);
+ s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
+ s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
+
+ cpu_register_physical_memory(s->buffers_base, buffers_size,
+ buffers | IO_MEM_RAM);
+
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_milkymist_minimac_info, &s->conf,
+ s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
dev->qdev.info->name, dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
return 0;
}
-static const VMStateDescription vmstate_milkymist_minimac_mdio = {
- .name = "milkymist_minimac_mdio",
+static const VMStateDescription vmstate_milkymist_minimac2_mdio = {
+ .name = "milkymist-minimac2-mdio",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
- VMSTATE_INT32(last_clk, MilkymistMinimacMdioState),
- VMSTATE_INT32(count, MilkymistMinimacMdioState),
- VMSTATE_UINT32(data, MilkymistMinimacMdioState),
- VMSTATE_UINT16(data_out, MilkymistMinimacMdioState),
- VMSTATE_INT32(state, MilkymistMinimacMdioState),
- VMSTATE_UINT8(phy_addr, MilkymistMinimacMdioState),
- VMSTATE_UINT8(reg_addr, MilkymistMinimacMdioState),
+ VMSTATE_INT32(last_clk, MilkymistMinimac2MdioState),
+ VMSTATE_INT32(count, MilkymistMinimac2MdioState),
+ VMSTATE_UINT32(data, MilkymistMinimac2MdioState),
+ VMSTATE_UINT16(data_out, MilkymistMinimac2MdioState),
+ VMSTATE_INT32(state, MilkymistMinimac2MdioState),
+ VMSTATE_UINT8(phy_addr, MilkymistMinimac2MdioState),
+ VMSTATE_UINT8(reg_addr, MilkymistMinimac2MdioState),
VMSTATE_END_OF_LIST()
}
};
-static const VMStateDescription vmstate_milkymist_minimac = {
- .name = "milkymist-minimac",
+static const VMStateDescription vmstate_milkymist_minimac2 = {
+ .name = "milkymist-minimac2",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistMinimacState, R_MAX),
- VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimacState, R_PHY_MAX),
- VMSTATE_STRUCT(mdio, MilkymistMinimacState, 0,
- vmstate_milkymist_minimac_mdio, MilkymistMinimacMdioState),
+ VMSTATE_UINT32_ARRAY(regs, MilkymistMinimac2State, R_MAX),
+ VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimac2State, R_PHY_MAX),
+ VMSTATE_STRUCT(mdio, MilkymistMinimac2State, 0,
+ vmstate_milkymist_minimac2_mdio, MilkymistMinimac2MdioState),
VMSTATE_END_OF_LIST()
}
};
-static SysBusDeviceInfo milkymist_minimac_info = {
- .init = milkymist_minimac_init,
- .qdev.name = "milkymist-minimac",
- .qdev.size = sizeof(MilkymistMinimacState),
- .qdev.vmsd = &vmstate_milkymist_minimac,
- .qdev.reset = milkymist_minimac_reset,
+static SysBusDeviceInfo milkymist_minimac2_info = {
+ .init = milkymist_minimac2_init,
+ .qdev.name = "milkymist-minimac2",
+ .qdev.size = sizeof(MilkymistMinimac2State),
+ .qdev.vmsd = &vmstate_milkymist_minimac2,
+ .qdev.reset = milkymist_minimac2_reset,
.qdev.props = (Property[]) {
- DEFINE_NIC_PROPERTIES(MilkymistMinimacState, conf),
- DEFINE_PROP_STRING("phy_model", MilkymistMinimacState, phy_model),
+ DEFINE_PROP_TADDR("buffers_base", MilkymistMinimac2State,
+ buffers_base, 0),
+ DEFINE_NIC_PROPERTIES(MilkymistMinimac2State, conf),
+ DEFINE_PROP_STRING("phy_model", MilkymistMinimac2State, phy_model),
DEFINE_PROP_END_OF_LIST(),
}
};
-static void milkymist_minimac_register(void)
+static void milkymist_minimac2_register(void)
{
- sysbus_register_withprop(&milkymist_minimac_info);
+ sysbus_register_withprop(&milkymist_minimac2_info);
}
-device_init(milkymist_minimac_register)
+device_init(milkymist_minimac2_register)
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index eaea543bf..6bd0cb974 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -140,24 +140,8 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
case R_GPIO_OUT:
case R_GPIO_INTEN:
case R_TIMER0_COUNTER:
- if (value > s->regs[R_TIMER0_COUNTER]) {
- value = s->regs[R_TIMER0_COUNTER];
- error_report("milkymist_sysctl: timer0: trying to write a "
- "value greater than the limit. Clipping.");
- }
- /* milkymist timer counts up */
- value = s->regs[R_TIMER0_COUNTER] - value;
- ptimer_set_count(s->ptimer0, value);
- break;
case R_TIMER1_COUNTER:
- if (value > s->regs[R_TIMER1_COUNTER]) {
- value = s->regs[R_TIMER1_COUNTER];
- error_report("milkymist_sysctl: timer1: trying to write a "
- "value greater than the limit. Clipping.");
- }
- /* milkymist timer counts up */
- value = s->regs[R_TIMER1_COUNTER] - value;
- ptimer_set_count(s->ptimer1, value);
+ s->regs[addr] = value;
break;
case R_TIMER0_COMPARE:
ptimer_set_limit(s->ptimer0, value, 0);
@@ -170,10 +154,12 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
case R_TIMER0_CONTROL:
s->regs[addr] = value;
if (s->regs[R_TIMER0_CONTROL] & CTRL_ENABLE) {
- trace_milkymist_sysctl_start_timer1();
+ trace_milkymist_sysctl_start_timer0();
+ ptimer_set_count(s->ptimer0,
+ s->regs[R_TIMER0_COMPARE] - s->regs[R_TIMER0_COUNTER]);
ptimer_run(s->ptimer0, 0);
} else {
- trace_milkymist_sysctl_stop_timer1();
+ trace_milkymist_sysctl_stop_timer0();
ptimer_stop(s->ptimer0);
}
break;
@@ -181,6 +167,8 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
s->regs[addr] = value;
if (s->regs[R_TIMER1_CONTROL] & CTRL_ENABLE) {
trace_milkymist_sysctl_start_timer1();
+ ptimer_set_count(s->ptimer1,
+ s->regs[R_TIMER1_COMPARE] - s->regs[R_TIMER1_COUNTER]);
ptimer_run(s->ptimer1, 0);
} else {
trace_milkymist_sysctl_stop_timer1();
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 892273151..2e55e42e3 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -199,6 +199,9 @@ vgafb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
addr >>= 2;
switch (addr) {
case R_CTRL:
+ s->regs[addr] = value;
+ vgafb_resize(s);
+ break;
case R_HSYNC_START:
case R_HSYNC_END:
case R_HSCAN:
diff --git a/hw/milkymist.c b/hw/milkymist.c
index 8defad802..787984040 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -156,7 +156,7 @@ milkymist_init(ram_addr_t ram_size_not_used,
milkymist_ac97_create(0x60005000, irq[5], irq[6], irq[7], irq[8]);
milkymist_pfpu_create(0x60006000, irq[9]);
milkymist_tmu2_create(0x60007000, irq[10]);
- milkymist_minimac_create(0x60008000, irq[11], irq[12]);
+ milkymist_minimac2_create(0x60008000, 0x30000000, irq[11], irq[12]);
milkymist_softusb_create(0x6000f000, irq[17],
0x20000000, 0x1000, 0x20020000, 0x2000);
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index c5e54ffc3..26aad51ea 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -202,44 +202,29 @@ static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val)
}
}
-static void mipsnet_save(QEMUFile *f, void *opaque)
-{
- MIPSnetState *s = opaque;
-
- qemu_put_be32s(f, &s->busy);
- qemu_put_be32s(f, &s->rx_count);
- qemu_put_be32s(f, &s->rx_read);
- qemu_put_be32s(f, &s->tx_count);
- qemu_put_be32s(f, &s->tx_written);
- qemu_put_be32s(f, &s->intctl);
- qemu_put_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);
- qemu_put_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);
-}
-
-static int mipsnet_load(QEMUFile *f, void *opaque, int version_id)
-{
- MIPSnetState *s = opaque;
-
- if (version_id > 0)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->busy);
- qemu_get_be32s(f, &s->rx_count);
- qemu_get_be32s(f, &s->rx_read);
- qemu_get_be32s(f, &s->tx_count);
- qemu_get_be32s(f, &s->tx_written);
- qemu_get_be32s(f, &s->intctl);
- qemu_get_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);
- qemu_get_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);
-
- return 0;
-}
+static const VMStateDescription vmstate_mipsnet = {
+ .name = "mipsnet",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(busy, MIPSnetState),
+ VMSTATE_UINT32(rx_count, MIPSnetState),
+ VMSTATE_UINT32(rx_read, MIPSnetState),
+ VMSTATE_UINT32(tx_count, MIPSnetState),
+ VMSTATE_UINT32(tx_written, MIPSnetState),
+ VMSTATE_UINT32(intctl, MIPSnetState),
+ VMSTATE_BUFFER(rx_buffer, MIPSnetState),
+ VMSTATE_BUFFER(tx_buffer, MIPSnetState),
+ VMSTATE_END_OF_LIST()
+ }
+};
static void mipsnet_cleanup(VLANClientState *nc)
{
MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
- unregister_savevm(NULL, "mipsnet", s);
+ vmstate_unregister(NULL, &vmstate_mipsnet, s);
isa_unassign_ioport(s->io_base, 36);
@@ -284,5 +269,5 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
}
mipsnet_reset(s);
- register_savevm(NULL, "mipsnet", 0, 0, mipsnet_save, mipsnet_load, s);
+ vmstate_register(NULL, 0, &vmstate_mipsnet, s);
}
diff --git a/hw/nand.c b/hw/nand.c
index f414aa139..37e51d714 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -52,7 +52,7 @@ struct NANDFlashState {
BlockDriverState *bdrv;
int mem_oob;
- int cle, ale, ce, wp, gnd;
+ uint8_t cle, ale, ce, wp, gnd;
uint8_t io[MAX_PAGE + MAX_OOB + 0x400];
uint8_t *ioaddr;
@@ -66,6 +66,8 @@ struct NANDFlashState {
void (*blk_write)(NANDFlashState *s);
void (*blk_erase)(NANDFlashState *s);
void (*blk_load)(NANDFlashState *s, uint32_t addr, int offset);
+
+ uint32_t ioaddr_vmstate;
};
# define NAND_NO_AUTOINCR 0x00000001
@@ -281,56 +283,59 @@ static void nand_command(NANDFlashState *s)
}
}
-static void nand_save(QEMUFile *f, void *opaque)
+static void nand_pre_save(void *opaque)
{
- NANDFlashState *s = (NANDFlashState *) opaque;
- qemu_put_byte(f, s->cle);
- qemu_put_byte(f, s->ale);
- qemu_put_byte(f, s->ce);
- qemu_put_byte(f, s->wp);
- qemu_put_byte(f, s->gnd);
- qemu_put_buffer(f, s->io, sizeof(s->io));
- qemu_put_be32(f, s->ioaddr - s->io);
- qemu_put_be32(f, s->iolen);
-
- qemu_put_be32s(f, &s->cmd);
- qemu_put_be32s(f, &s->addr);
- qemu_put_be32(f, s->addrlen);
- qemu_put_be32(f, s->status);
- qemu_put_be32(f, s->offset);
- /* XXX: do we want to save s->storage too? */
+ NANDFlashState *s = opaque;
+
+ s->ioaddr_vmstate = s->ioaddr - s->io;
}
-static int nand_load(QEMUFile *f, void *opaque, int version_id)
+static int nand_post_load(void *opaque, int version_id)
{
- NANDFlashState *s = (NANDFlashState *) opaque;
- s->cle = qemu_get_byte(f);
- s->ale = qemu_get_byte(f);
- s->ce = qemu_get_byte(f);
- s->wp = qemu_get_byte(f);
- s->gnd = qemu_get_byte(f);
- qemu_get_buffer(f, s->io, sizeof(s->io));
- s->ioaddr = s->io + qemu_get_be32(f);
- s->iolen = qemu_get_be32(f);
- if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io)
+ NANDFlashState *s = opaque;
+
+ if (s->ioaddr_vmstate > sizeof(s->io)) {
return -EINVAL;
+ }
+ s->ioaddr = s->io + s->ioaddr_vmstate;
- qemu_get_be32s(f, &s->cmd);
- qemu_get_be32s(f, &s->addr);
- s->addrlen = qemu_get_be32(f);
- s->status = qemu_get_be32(f);
- s->offset = qemu_get_be32(f);
return 0;
}
+static const VMStateDescription vmstate_nand = {
+ .name = "nand",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .pre_save = nand_pre_save,
+ .post_load = nand_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(cle, NANDFlashState),
+ VMSTATE_UINT8(ale, NANDFlashState),
+ VMSTATE_UINT8(ce, NANDFlashState),
+ VMSTATE_UINT8(wp, NANDFlashState),
+ VMSTATE_UINT8(gnd, NANDFlashState),
+ VMSTATE_BUFFER(io, NANDFlashState),
+ VMSTATE_UINT32(ioaddr_vmstate, NANDFlashState),
+ VMSTATE_INT32(iolen, NANDFlashState),
+ VMSTATE_UINT32(cmd, NANDFlashState),
+ VMSTATE_UINT32(addr, NANDFlashState),
+ VMSTATE_INT32(addrlen, NANDFlashState),
+ VMSTATE_INT32(status, NANDFlashState),
+ VMSTATE_INT32(offset, NANDFlashState),
+ /* XXX: do we want to save s->storage too? */
+ VMSTATE_END_OF_LIST()
+ }
+};
+
/*
* Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins. Chip
* outputs are R/B and eight I/O pins.
*
* CE, WP and R/B are active low.
*/
-void nand_setpins(NANDFlashState *s,
- int cle, int ale, int ce, int wp, int gnd)
+void nand_setpins(NANDFlashState *s, uint8_t cle, uint8_t ale,
+ uint8_t ce, uint8_t wp, uint8_t gnd)
{
s->cle = cle;
s->ale = ale;
@@ -502,7 +507,7 @@ NANDFlashState *nand_init(int manf_id, int chip_id)
is used. */
s->ioaddr = s->io;
- register_savevm(NULL, "nand", -1, 0, nand_save, nand_load, s);
+ vmstate_register(NULL, -1, &vmstate_nand, s);
return s;
}
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 596635985..b668ad107 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -742,7 +742,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
if (!pci_dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
- rom_add_option("pxe-ne2k_pci.bin", -1);
+ rom_add_option("pxe-ne2k_pci.rom", -1);
loaded = 1;
}
}
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 06bccbdc4..a7b687bc4 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -26,7 +26,6 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw.h"
-#include "sysemu.h"
#include "console.h"
#include "omap.h"
#include "boards.h"
diff --git a/hw/pcie.c b/hw/pcie.c
index 6a113a932..9de614904 100644
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -18,8 +18,7 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "sysemu.h"
-#include "range.h"
+#include "qemu-common.h"
#include "pci_bridge.h"
#include "pcie.h"
#include "msix.h"
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 339a40196..40ee29d38 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -310,7 +310,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
if (!pci_dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
- rom_add_option("pxe-pcnet.bin", -1);
+ rom_add_option("pxe-pcnet.rom", -1);
loaded = 1;
}
}
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index 370c5eef7..14bbc34e1 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -50,6 +50,8 @@ do { \
#define DPRINTF(fmt, ...) do { } while (0)
#endif
+#define PFLASH_LAZY_ROMD_THRESHOLD 42
+
struct pflash_t {
BlockDriverState *bs;
target_phys_addr_t base;
@@ -70,6 +72,7 @@ struct pflash_t {
ram_addr_t off;
int fl_mem;
int rom_mode;
+ int read_counter; /* used for lazy switch-back to rom mode */
void *storage;
};
@@ -112,10 +115,10 @@ static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset,
DPRINTF("%s: offset " TARGET_FMT_plx "\n", __func__, offset);
ret = -1;
- if (!pfl->rom_mode) {
- /* Lazy reset of to ROMD mode */
- if (pfl->wcycle == 0)
- pflash_register_memory(pfl, 1);
+ /* Lazy reset to ROMD mode after a certain amount of read accesses */
+ if (!pfl->rom_mode && pfl->wcycle == 0 &&
+ ++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) {
+ pflash_register_memory(pfl, 1);
}
offset &= pfl->chip_len - 1;
boff = offset & 0xFF;
@@ -254,6 +257,7 @@ static void pflash_write (pflash_t *pfl, target_phys_addr_t offset,
/* Set the device in I/O access mode if required */
if (pfl->rom_mode)
pflash_register_memory(pfl, 0);
+ pfl->read_counter = 0;
/* We're in read mode */
check_unlock0:
if (boff == 0x55 && cmd == 0x98) {
diff --git a/hw/piix4.c b/hw/piix4.c
index 72073cd0a..71f1f84dc 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -30,10 +30,14 @@
PCIDevice *piix4_dev;
+typedef struct PIIX4State {
+ PCIDevice dev;
+} PIIX4State;
+
static void piix4_reset(void *opaque)
{
- PCIDevice *d = opaque;
- uint8_t *pci_conf = d->config;
+ PIIX4State *d = opaque;
+ uint8_t *pci_conf = d->dev.config;
pci_conf[0x04] = 0x07; // master, memory and I/O
pci_conf[0x05] = 0x00;
@@ -68,33 +72,30 @@ static void piix4_reset(void *opaque)
pci_conf[0xae] = 0x00;
}
-static void piix_save(QEMUFile* f, void *opaque)
-{
- PCIDevice *d = opaque;
- pci_device_save(d, f);
-}
-
-static int piix_load(QEMUFile* f, void *opaque, int version_id)
-{
- PCIDevice *d = opaque;
- if (version_id != 2)
- return -EINVAL;
- return pci_device_load(d, f);
-}
+static const VMStateDescription vmstate_piix4 = {
+ .name = "PIIX4",
+ .version_id = 2,
+ .minimum_version_id = 2,
+ .minimum_version_id_old = 2,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE(dev, PIIX4State),
+ VMSTATE_END_OF_LIST()
+ }
+};
-static int piix4_initfn(PCIDevice *d)
+static int piix4_initfn(PCIDevice *dev)
{
+ PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev);
uint8_t *pci_conf;
- isa_bus_new(&d->qdev);
- register_savevm(&d->qdev, "PIIX4", 0, 2, piix_save, piix_load, d);
+ isa_bus_new(&d->dev.qdev);
- pci_conf = d->config;
+ pci_conf = d->dev.config;
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
- piix4_dev = d;
+ piix4_dev = &d->dev;
qemu_register_reset(piix4_reset, d);
return 0;
}
@@ -111,7 +112,8 @@ static PCIDeviceInfo piix4_info[] = {
{
.qdev.name = "PIIX4",
.qdev.desc = "ISA bridge",
- .qdev.size = sizeof(PCIDevice),
+ .qdev.size = sizeof(PIIX4State),
+ .qdev.vmsd = &vmstate_piix4,
.qdev.no_user = 1,
.no_hotplug = 1,
.init = piix4_initfn,
diff --git a/hw/pl011.c b/hw/pl011.c
index 77f0dbf13..3b94b14cb 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -235,56 +235,30 @@ static CPUWriteMemoryFunc * const pl011_writefn[] = {
pl011_write
};
-static void pl011_save(QEMUFile *f, void *opaque)
-{
- pl011_state *s = (pl011_state *)opaque;
- int i;
-
- qemu_put_be32(f, s->readbuff);
- qemu_put_be32(f, s->flags);
- qemu_put_be32(f, s->lcr);
- qemu_put_be32(f, s->cr);
- qemu_put_be32(f, s->dmacr);
- qemu_put_be32(f, s->int_enabled);
- qemu_put_be32(f, s->int_level);
- for (i = 0; i < 16; i++)
- qemu_put_be32(f, s->read_fifo[i]);
- qemu_put_be32(f, s->ilpr);
- qemu_put_be32(f, s->ibrd);
- qemu_put_be32(f, s->fbrd);
- qemu_put_be32(f, s->ifl);
- qemu_put_be32(f, s->read_pos);
- qemu_put_be32(f, s->read_count);
- qemu_put_be32(f, s->read_trigger);
-}
-
-static int pl011_load(QEMUFile *f, void *opaque, int version_id)
-{
- pl011_state *s = (pl011_state *)opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->readbuff = qemu_get_be32(f);
- s->flags = qemu_get_be32(f);
- s->lcr = qemu_get_be32(f);
- s->cr = qemu_get_be32(f);
- s->dmacr = qemu_get_be32(f);
- s->int_enabled = qemu_get_be32(f);
- s->int_level = qemu_get_be32(f);
- for (i = 0; i < 16; i++)
- s->read_fifo[i] = qemu_get_be32(f);
- s->ilpr = qemu_get_be32(f);
- s->ibrd = qemu_get_be32(f);
- s->fbrd = qemu_get_be32(f);
- s->ifl = qemu_get_be32(f);
- s->read_pos = qemu_get_be32(f);
- s->read_count = qemu_get_be32(f);
- s->read_trigger = qemu_get_be32(f);
-
- return 0;
-}
+static const VMStateDescription vmstate_pl011 = {
+ .name = "pl011",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(readbuff, pl011_state),
+ VMSTATE_UINT32(flags, pl011_state),
+ VMSTATE_UINT32(lcr, pl011_state),
+ VMSTATE_UINT32(cr, pl011_state),
+ VMSTATE_UINT32(dmacr, pl011_state),
+ VMSTATE_UINT32(int_enabled, pl011_state),
+ VMSTATE_UINT32(int_level, pl011_state),
+ VMSTATE_UINT32_ARRAY(read_fifo, pl011_state, 16),
+ VMSTATE_UINT32(ilpr, pl011_state),
+ VMSTATE_UINT32(ibrd, pl011_state),
+ VMSTATE_UINT32(fbrd, pl011_state),
+ VMSTATE_UINT32(ifl, pl011_state),
+ VMSTATE_INT32(read_pos, pl011_state),
+ VMSTATE_INT32(read_count, pl011_state),
+ VMSTATE_INT32(read_trigger, pl011_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int pl011_init(SysBusDevice *dev, const unsigned char *id)
{
@@ -307,7 +281,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
pl011_event, s);
}
- register_savevm(&dev->qdev, "pl011_uart", -1, 1, pl011_save, pl011_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_pl011, s);
return 0;
}
diff --git a/hw/pl022.c b/hw/pl022.c
index ffe05ab74..00e494a0d 100644
--- a/hw/pl022.c
+++ b/hw/pl022.c
@@ -239,54 +239,42 @@ static CPUWriteMemoryFunc * const pl022_writefn[] = {
pl022_write
};
-static void pl022_save(QEMUFile *f, void *opaque)
-{
- pl022_state *s = (pl022_state *)opaque;
- int i;
-
- qemu_put_be32(f, s->cr0);
- qemu_put_be32(f, s->cr1);
- qemu_put_be32(f, s->bitmask);
- qemu_put_be32(f, s->sr);
- qemu_put_be32(f, s->cpsr);
- qemu_put_be32(f, s->is);
- qemu_put_be32(f, s->im);
- qemu_put_be32(f, s->tx_fifo_head);
- qemu_put_be32(f, s->rx_fifo_head);
- qemu_put_be32(f, s->tx_fifo_len);
- qemu_put_be32(f, s->rx_fifo_len);
- for (i = 0; i < 8; i++) {
- qemu_put_be16(f, s->tx_fifo[i]);
- qemu_put_be16(f, s->rx_fifo[i]);
- }
-}
-
-static int pl022_load(QEMUFile *f, void *opaque, int version_id)
-{
- pl022_state *s = (pl022_state *)opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->cr0 = qemu_get_be32(f);
- s->cr1 = qemu_get_be32(f);
- s->bitmask = qemu_get_be32(f);
- s->sr = qemu_get_be32(f);
- s->cpsr = qemu_get_be32(f);
- s->is = qemu_get_be32(f);
- s->im = qemu_get_be32(f);
- s->tx_fifo_head = qemu_get_be32(f);
- s->rx_fifo_head = qemu_get_be32(f);
- s->tx_fifo_len = qemu_get_be32(f);
- s->rx_fifo_len = qemu_get_be32(f);
- for (i = 0; i < 8; i++) {
- s->tx_fifo[i] = qemu_get_be16(f);
- s->rx_fifo[i] = qemu_get_be16(f);
+static const VMStateDescription vmstate_pl022 = {
+ .name = "pl022_ssp",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(cr0, pl022_state),
+ VMSTATE_UINT32(cr1, pl022_state),
+ VMSTATE_UINT32(bitmask, pl022_state),
+ VMSTATE_UINT32(sr, pl022_state),
+ VMSTATE_UINT32(cpsr, pl022_state),
+ VMSTATE_UINT32(is, pl022_state),
+ VMSTATE_UINT32(im, pl022_state),
+ VMSTATE_INT32(tx_fifo_head, pl022_state),
+ VMSTATE_INT32(rx_fifo_head, pl022_state),
+ VMSTATE_INT32(tx_fifo_len, pl022_state),
+ VMSTATE_INT32(rx_fifo_len, pl022_state),
+ VMSTATE_UINT16(tx_fifo[0], pl022_state),
+ VMSTATE_UINT16(rx_fifo[0], pl022_state),
+ VMSTATE_UINT16(tx_fifo[1], pl022_state),
+ VMSTATE_UINT16(rx_fifo[1], pl022_state),
+ VMSTATE_UINT16(tx_fifo[2], pl022_state),
+ VMSTATE_UINT16(rx_fifo[2], pl022_state),
+ VMSTATE_UINT16(tx_fifo[3], pl022_state),
+ VMSTATE_UINT16(rx_fifo[3], pl022_state),
+ VMSTATE_UINT16(tx_fifo[4], pl022_state),
+ VMSTATE_UINT16(rx_fifo[4], pl022_state),
+ VMSTATE_UINT16(tx_fifo[5], pl022_state),
+ VMSTATE_UINT16(rx_fifo[5], pl022_state),
+ VMSTATE_UINT16(tx_fifo[6], pl022_state),
+ VMSTATE_UINT16(rx_fifo[6], pl022_state),
+ VMSTATE_UINT16(tx_fifo[7], pl022_state),
+ VMSTATE_UINT16(rx_fifo[7], pl022_state),
+ VMSTATE_END_OF_LIST()
}
-
- return 0;
-}
+};
static int pl022_init(SysBusDevice *dev)
{
@@ -300,7 +288,7 @@ static int pl022_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
s->ssi = ssi_create_bus(&dev->qdev, "ssi");
pl022_reset(s);
- register_savevm(&dev->qdev, "pl022_ssp", -1, 1, pl022_save, pl022_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_pl022, s);
return 0;
}
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index db1f84abe..6627cd8aa 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -17,7 +17,6 @@
#include "hw.h"
#include "pci.h"
#include "boards.h"
-#include "sysemu.h"
#include "ppc440.h"
#include "kvm.h"
#include "kvm_ppc.h"
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index 5f581fe2c..7f9ed1713 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -24,7 +24,6 @@
#include "hw.h"
#include "ppc.h"
#include "ppc4xx.h"
-#include "sysemu.h"
#include "qemu-log.h"
//#define DEBUG_MMIO
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index f62f1f91d..299473c4b 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -285,50 +285,48 @@ static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pci_irqs[irq_num], level);
}
-static void ppc4xx_pci_save(QEMUFile *f, void *opaque)
-{
- PPC4xxPCIState *controller = opaque;
- int i;
-
- pci_device_save(controller->pci_dev, f);
-
- for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) {
- qemu_put_be32s(f, &controller->pmm[i].la);
- qemu_put_be32s(f, &controller->pmm[i].ma);
- qemu_put_be32s(f, &controller->pmm[i].pcila);
- qemu_put_be32s(f, &controller->pmm[i].pciha);
- }
-
- for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) {
- qemu_put_be32s(f, &controller->ptm[i].ms);
- qemu_put_be32s(f, &controller->ptm[i].la);
+static const VMStateDescription vmstate_pci_master_map = {
+ .name = "pci_master_map",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(la, struct PCIMasterMap),
+ VMSTATE_UINT32(ma, struct PCIMasterMap),
+ VMSTATE_UINT32(pcila, struct PCIMasterMap),
+ VMSTATE_UINT32(pciha, struct PCIMasterMap),
+ VMSTATE_END_OF_LIST()
}
-}
-
-static int ppc4xx_pci_load(QEMUFile *f, void *opaque, int version_id)
-{
- PPC4xxPCIState *controller = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- pci_device_load(controller->pci_dev, f);
+};
- for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) {
- qemu_get_be32s(f, &controller->pmm[i].la);
- qemu_get_be32s(f, &controller->pmm[i].ma);
- qemu_get_be32s(f, &controller->pmm[i].pcila);
- qemu_get_be32s(f, &controller->pmm[i].pciha);
+static const VMStateDescription vmstate_pci_target_map = {
+ .name = "pci_target_map",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(ms, struct PCITargetMap),
+ VMSTATE_UINT32(la, struct PCITargetMap),
+ VMSTATE_END_OF_LIST()
}
+};
- for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) {
- qemu_get_be32s(f, &controller->ptm[i].ms);
- qemu_get_be32s(f, &controller->ptm[i].la);
+static const VMStateDescription vmstate_ppc4xx_pci = {
+ .name = "ppc4xx_pci",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState),
+ VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1,
+ vmstate_pci_master_map,
+ struct PCIMasterMap),
+ VMSTATE_STRUCT_ARRAY(ptm, PPC4xxPCIState, PPC4xx_PCI_NR_PTMS, 1,
+ vmstate_pci_target_map,
+ struct PCITargetMap),
+ VMSTATE_END_OF_LIST()
}
-
- return 0;
-}
+};
/* XXX Interrupt acknowledge cycles not supported. */
PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
@@ -381,8 +379,8 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
qemu_register_reset(ppc4xx_pci_reset, controller);
/* XXX load/save code not tested. */
- register_savevm(&controller->pci_dev->qdev, "ppc4xx_pci", ppc4xx_pci_id++,
- 1, ppc4xx_pci_save, ppc4xx_pci_load, controller);
+ vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++,
+ &vmstate_ppc4xx_pci, controller);
return controller->pci_state.bus;
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 2fc879236..83a20e462 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -216,56 +216,49 @@ static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num], level);
}
-static void ppce500_pci_save(QEMUFile *f, void *opaque)
-{
- PPCE500PCIState *controller = opaque;
- int i;
-
- pci_device_save(controller->pci_dev, f);
-
- for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
- qemu_put_be32s(f, &controller->pob[i].potar);
- qemu_put_be32s(f, &controller->pob[i].potear);
- qemu_put_be32s(f, &controller->pob[i].powbar);
- qemu_put_be32s(f, &controller->pob[i].powar);
- }
-
- for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
- qemu_put_be32s(f, &controller->pib[i].pitar);
- qemu_put_be32s(f, &controller->pib[i].piwbar);
- qemu_put_be32s(f, &controller->pib[i].piwbear);
- qemu_put_be32s(f, &controller->pib[i].piwar);
+static const VMStateDescription vmstate_pci_outbound = {
+ .name = "pci_outbound",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(potar, struct pci_outbound),
+ VMSTATE_UINT32(potear, struct pci_outbound),
+ VMSTATE_UINT32(powbar, struct pci_outbound),
+ VMSTATE_UINT32(powar, struct pci_outbound),
+ VMSTATE_END_OF_LIST()
}
- qemu_put_be32s(f, &controller->gasket_time);
-}
-
-static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
-{
- PPCE500PCIState *controller = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- pci_device_load(controller->pci_dev, f);
+};
- for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
- qemu_get_be32s(f, &controller->pob[i].potar);
- qemu_get_be32s(f, &controller->pob[i].potear);
- qemu_get_be32s(f, &controller->pob[i].powbar);
- qemu_get_be32s(f, &controller->pob[i].powar);
+static const VMStateDescription vmstate_pci_inbound = {
+ .name = "pci_inbound",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(pitar, struct pci_inbound),
+ VMSTATE_UINT32(piwbar, struct pci_inbound),
+ VMSTATE_UINT32(piwbear, struct pci_inbound),
+ VMSTATE_UINT32(piwar, struct pci_inbound),
+ VMSTATE_END_OF_LIST()
}
+};
- for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
- qemu_get_be32s(f, &controller->pib[i].pitar);
- qemu_get_be32s(f, &controller->pib[i].piwbar);
- qemu_get_be32s(f, &controller->pib[i].piwbear);
- qemu_get_be32s(f, &controller->pib[i].piwar);
+static const VMStateDescription vmstate_ppce500_pci = {
+ .name = "ppce500_pci",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPCE500PCIState),
+ VMSTATE_STRUCT_ARRAY(pob, PPCE500PCIState, PPCE500_PCI_NR_POBS, 1,
+ vmstate_pci_outbound, struct pci_outbound),
+ VMSTATE_STRUCT_ARRAY(pib, PPCE500PCIState, PPCE500_PCI_NR_PIBS, 1,
+ vmstate_pci_outbound, struct pci_inbound),
+ VMSTATE_UINT32(gasket_time, PPCE500PCIState),
+ VMSTATE_END_OF_LIST()
}
- qemu_get_be32s(f, &controller->gasket_time);
-
- return 0;
-}
+};
PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
{
@@ -314,8 +307,8 @@ PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
PCIE500_REG_SIZE, index);
/* XXX load/save code not tested. */
- register_savevm(&d->qdev, "ppce500_pci", ppce500_pci_id++,
- 1, ppce500_pci_save, ppce500_pci_load, controller);
+ vmstate_register(&d->qdev, ppce500_pci_id++, &vmstate_ppce500_pci,
+ controller);
return controller->pci_state.bus;
diff --git a/hw/ptimer.c b/hw/ptimer.c
index e68c1d141..47964a67e 100644
--- a/hw/ptimer.c
+++ b/hw/ptimer.c
@@ -11,7 +11,7 @@
struct ptimer_state
{
- int enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */
+ uint8_t enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */
uint64_t limit;
uint64_t delta;
uint32_t period_frac;
@@ -188,49 +188,22 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
}
}
-void qemu_put_ptimer(QEMUFile *f, ptimer_state *s)
-{
- qemu_put_byte(f, s->enabled);
- qemu_put_be64s(f, &s->limit);
- qemu_put_be64s(f, &s->delta);
- qemu_put_be32s(f, &s->period_frac);
- qemu_put_sbe64s(f, &s->period);
- qemu_put_sbe64s(f, &s->last_event);
- qemu_put_sbe64s(f, &s->next_event);
- qemu_put_timer(f, s->timer);
-}
-
-void qemu_get_ptimer(QEMUFile *f, ptimer_state *s)
-{
- s->enabled = qemu_get_byte(f);
- qemu_get_be64s(f, &s->limit);
- qemu_get_be64s(f, &s->delta);
- qemu_get_be32s(f, &s->period_frac);
- qemu_get_sbe64s(f, &s->period);
- qemu_get_sbe64s(f, &s->last_event);
- qemu_get_sbe64s(f, &s->next_event);
- qemu_get_timer(f, s->timer);
-}
-
-static int get_ptimer(QEMUFile *f, void *pv, size_t size)
-{
- ptimer_state *v = pv;
-
- qemu_get_ptimer(f, v);
- return 0;
-}
-
-static void put_ptimer(QEMUFile *f, void *pv, size_t size)
-{
- ptimer_state *v = pv;
-
- qemu_put_ptimer(f, v);
-}
-
-const VMStateInfo vmstate_info_ptimer = {
+const VMStateDescription vmstate_ptimer = {
.name = "ptimer",
- .get = get_ptimer,
- .put = put_ptimer,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(enabled, ptimer_state),
+ VMSTATE_UINT64(limit, ptimer_state),
+ VMSTATE_UINT64(delta, ptimer_state),
+ VMSTATE_UINT32(period_frac, ptimer_state),
+ VMSTATE_INT64(period, ptimer_state),
+ VMSTATE_INT64(last_event, ptimer_state),
+ VMSTATE_INT64(next_event, ptimer_state),
+ VMSTATE_TIMER(timer, ptimer_state),
+ VMSTATE_END_OF_LIST()
+ }
};
ptimer_state *ptimer_init(QEMUBH *bh)
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 9b95e2c8e..ac5d95d71 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -146,25 +146,16 @@ static CPUWriteMemoryFunc * const pxa2xx_pm_writefn[] = {
pxa2xx_pm_write,
};
-static void pxa2xx_pm_save(QEMUFile *f, void *opaque)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
- int i;
-
- for (i = 0; i < 0x40; i ++)
- qemu_put_be32s(f, &s->pm_regs[i]);
-}
-
-static int pxa2xx_pm_load(QEMUFile *f, void *opaque, int version_id)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
- int i;
-
- for (i = 0; i < 0x40; i ++)
- qemu_get_be32s(f, &s->pm_regs[i]);
-
- return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_pm = {
+ .name = "pxa2xx_pm",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40),
+ VMSTATE_END_OF_LIST()
+ }
+};
#define CCCR 0x00 /* Core Clock Configuration register */
#define CKEN 0x04 /* Clock Enable register */
@@ -227,29 +218,18 @@ static CPUWriteMemoryFunc * const pxa2xx_cm_writefn[] = {
pxa2xx_cm_write,
};
-static void pxa2xx_cm_save(QEMUFile *f, void *opaque)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
- int i;
-
- for (i = 0; i < 4; i ++)
- qemu_put_be32s(f, &s->cm_regs[i]);
- qemu_put_be32s(f, &s->clkcfg);
- qemu_put_be32s(f, &s->pmnc);
-}
-
-static int pxa2xx_cm_load(QEMUFile *f, void *opaque, int version_id)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
- int i;
-
- for (i = 0; i < 4; i ++)
- qemu_get_be32s(f, &s->cm_regs[i]);
- qemu_get_be32s(f, &s->clkcfg);
- qemu_get_be32s(f, &s->pmnc);
-
- return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_cm = {
+ .name = "pxa2xx_cm",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4),
+ VMSTATE_UINT32(clkcfg, PXA2xxState),
+ VMSTATE_UINT32(pmnc, PXA2xxState),
+ VMSTATE_END_OF_LIST()
+ }
+};
static uint32_t pxa2xx_clkpwr_read(void *opaque, int op2, int reg, int crm)
{
@@ -527,25 +507,16 @@ static CPUWriteMemoryFunc * const pxa2xx_mm_writefn[] = {
pxa2xx_mm_write,
};
-static void pxa2xx_mm_save(QEMUFile *f, void *opaque)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
- int i;
-
- for (i = 0; i < 0x1a; i ++)
- qemu_put_be32s(f, &s->mm_regs[i]);
-}
-
-static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
- int i;
-
- for (i = 0; i < 0x1a; i ++)
- qemu_get_be32s(f, &s->mm_regs[i]);
-
- return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_mm = {
+ .name = "pxa2xx_mm",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a),
+ VMSTATE_END_OF_LIST()
+ }
+};
/* Synchronous Serial Ports */
typedef struct {
@@ -1748,39 +1719,23 @@ static CPUWriteMemoryFunc * const pxa2xx_i2s_writefn[] = {
pxa2xx_i2s_write,
};
-static void pxa2xx_i2s_save(QEMUFile *f, void *opaque)
-{
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
-
- qemu_put_be32s(f, &s->control[0]);
- qemu_put_be32s(f, &s->control[1]);
- qemu_put_be32s(f, &s->status);
- qemu_put_be32s(f, &s->mask);
- qemu_put_be32s(f, &s->clk);
-
- qemu_put_be32(f, s->enable);
- qemu_put_be32(f, s->rx_len);
- qemu_put_be32(f, s->tx_len);
- qemu_put_be32(f, s->fifo_len);
-}
-
-static int pxa2xx_i2s_load(QEMUFile *f, void *opaque, int version_id)
-{
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
-
- qemu_get_be32s(f, &s->control[0]);
- qemu_get_be32s(f, &s->control[1]);
- qemu_get_be32s(f, &s->status);
- qemu_get_be32s(f, &s->mask);
- qemu_get_be32s(f, &s->clk);
-
- s->enable = qemu_get_be32(f);
- s->rx_len = qemu_get_be32(f);
- s->tx_len = qemu_get_be32(f);
- s->fifo_len = qemu_get_be32(f);
-
- return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_i2s = {
+ .name = "pxa2xx_i2s",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2),
+ VMSTATE_UINT32(status, PXA2xxI2SState),
+ VMSTATE_UINT32(mask, PXA2xxI2SState),
+ VMSTATE_UINT32(clk, PXA2xxI2SState),
+ VMSTATE_INT32(enable, PXA2xxI2SState),
+ VMSTATE_INT32(rx_len, PXA2xxI2SState),
+ VMSTATE_INT32(tx_len, PXA2xxI2SState),
+ VMSTATE_INT32(fifo_len, PXA2xxI2SState),
+ VMSTATE_END_OF_LIST()
+ }
+};
static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx)
{
@@ -1822,8 +1777,7 @@ static PXA2xxI2SState *pxa2xx_i2s_init(target_phys_addr_t base,
pxa2xx_i2s_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(base, 0x100000, iomemtype);
- register_savevm(NULL, "pxa2xx_i2s", base, 0,
- pxa2xx_i2s_save, pxa2xx_i2s_load, s);
+ vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s);
return s;
}
@@ -2188,7 +2142,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn,
pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype);
- register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
@@ -2199,13 +2153,13 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn,
pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype);
- register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
s->pm_base = 0x40f00000;
iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn,
pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(s->pm_base, 0x100, iomemtype);
- register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
for (i = 0; pxa27x_ssp[i].io_base; i ++);
s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);
@@ -2324,7 +2278,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn,
pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype);
- register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
@@ -2335,13 +2289,13 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn,
pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype);
- register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
s->pm_base = 0x40f00000;
iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn,
pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(s->pm_base, 0x100, iomemtype);
- register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
for (i = 0; pxa255_ssp[i].io_base; i ++);
s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index d77dbf179..10ef154aa 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -289,40 +289,22 @@ static CPUWriteMemoryFunc * const pxa2xx_keypad_writefn[] = {
pxa2xx_keypad_write
};
-static void pxa2xx_keypad_save(QEMUFile *f, void *opaque)
-{
- PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
-
- qemu_put_be32s(f, &s->kpc);
- qemu_put_be32s(f, &s->kpdk);
- qemu_put_be32s(f, &s->kprec);
- qemu_put_be32s(f, &s->kpmk);
- qemu_put_be32s(f, &s->kpas);
- qemu_put_be32s(f, &s->kpasmkp[0]);
- qemu_put_be32s(f, &s->kpasmkp[1]);
- qemu_put_be32s(f, &s->kpasmkp[2]);
- qemu_put_be32s(f, &s->kpasmkp[3]);
- qemu_put_be32s(f, &s->kpkdi);
-
-}
-
-static int pxa2xx_keypad_load(QEMUFile *f, void *opaque, int version_id)
-{
- PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
-
- qemu_get_be32s(f, &s->kpc);
- qemu_get_be32s(f, &s->kpdk);
- qemu_get_be32s(f, &s->kprec);
- qemu_get_be32s(f, &s->kpmk);
- qemu_get_be32s(f, &s->kpas);
- qemu_get_be32s(f, &s->kpasmkp[0]);
- qemu_get_be32s(f, &s->kpasmkp[1]);
- qemu_get_be32s(f, &s->kpasmkp[2]);
- qemu_get_be32s(f, &s->kpasmkp[3]);
- qemu_get_be32s(f, &s->kpkdi);
-
- return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_keypad = {
+ .name = "pxa2xx_keypad",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(kpc, PXA2xxKeyPadState),
+ VMSTATE_UINT32(kpdk, PXA2xxKeyPadState),
+ VMSTATE_UINT32(kprec, PXA2xxKeyPadState),
+ VMSTATE_UINT32(kpmk, PXA2xxKeyPadState),
+ VMSTATE_UINT32(kpas, PXA2xxKeyPadState),
+ VMSTATE_UINT32_ARRAY(kpasmkp, PXA2xxKeyPadState, 4),
+ VMSTATE_UINT32(kpkdi, PXA2xxKeyPadState),
+ VMSTATE_END_OF_LIST()
+ }
+};
PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base,
qemu_irq irq)
@@ -337,8 +319,7 @@ PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base,
pxa2xx_keypad_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(base, 0x00100000, iomemtype);
- register_savevm(NULL, "pxa2xx_keypad", 0, 0,
- pxa2xx_keypad_save, pxa2xx_keypad_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s);
return s;
}
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 5b2b07e02..e5248023f 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -15,6 +15,20 @@
#include "sysemu.h"
#include "framebuffer.h"
+struct DMAChannel {
+ target_phys_addr_t branch;
+ uint8_t up;
+ uint8_t palette[1024];
+ uint8_t pbuffer[1024];
+ void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
+ int *miny, int *maxy);
+
+ target_phys_addr_t descriptor;
+ target_phys_addr_t source;
+ uint32_t id;
+ uint32_t command;
+};
+
struct PXA2xxLCDState {
qemu_irq irq;
int irqlevel;
@@ -50,19 +64,7 @@ struct PXA2xxLCDState {
uint32_t liidr;
uint8_t bscntr;
- struct {
- target_phys_addr_t branch;
- int up;
- uint8_t palette[1024];
- uint8_t pbuffer[1024];
- void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
- int *miny, int *maxy);
-
- target_phys_addr_t descriptor;
- target_phys_addr_t source;
- uint32_t id;
- uint32_t command;
- } dma_ch[7];
+ struct DMAChannel dma_ch[7];
qemu_irq vsync_cb;
int orientation;
@@ -831,74 +833,26 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle)
pxa2xx_lcdc_resize(s);
}
-static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque)
-{
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
- int i;
-
- qemu_put_be32(f, s->irqlevel);
- qemu_put_be32(f, s->transp);
-
- for (i = 0; i < 6; i ++)
- qemu_put_be32s(f, &s->control[i]);
- for (i = 0; i < 2; i ++)
- qemu_put_be32s(f, &s->status[i]);
- for (i = 0; i < 2; i ++)
- qemu_put_be32s(f, &s->ovl1c[i]);
- for (i = 0; i < 2; i ++)
- qemu_put_be32s(f, &s->ovl2c[i]);
- qemu_put_be32s(f, &s->ccr);
- qemu_put_be32s(f, &s->cmdcr);
- qemu_put_be32s(f, &s->trgbr);
- qemu_put_be32s(f, &s->tcr);
- qemu_put_be32s(f, &s->liidr);
- qemu_put_8s(f, &s->bscntr);
-
- for (i = 0; i < 7; i ++) {
- qemu_put_betl(f, s->dma_ch[i].branch);
- qemu_put_byte(f, s->dma_ch[i].up);
- qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer));
-
- qemu_put_betl(f, s->dma_ch[i].descriptor);
- qemu_put_betl(f, s->dma_ch[i].source);
- qemu_put_be32s(f, &s->dma_ch[i].id);
- qemu_put_be32s(f, &s->dma_ch[i].command);
+static const VMStateDescription vmstate_dma_channel = {
+ .name = "dma_channel",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINTTL(branch, struct DMAChannel),
+ VMSTATE_UINT8(up, struct DMAChannel),
+ VMSTATE_BUFFER(pbuffer, struct DMAChannel),
+ VMSTATE_UINTTL(descriptor, struct DMAChannel),
+ VMSTATE_UINTTL(source, struct DMAChannel),
+ VMSTATE_UINT32(id, struct DMAChannel),
+ VMSTATE_UINT32(command, struct DMAChannel),
+ VMSTATE_END_OF_LIST()
}
-}
+};
-static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
+static int pxa2xx_lcdc_post_load(void *opaque, int version_id)
{
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
- int i;
-
- s->irqlevel = qemu_get_be32(f);
- s->transp = qemu_get_be32(f);
-
- for (i = 0; i < 6; i ++)
- qemu_get_be32s(f, &s->control[i]);
- for (i = 0; i < 2; i ++)
- qemu_get_be32s(f, &s->status[i]);
- for (i = 0; i < 2; i ++)
- qemu_get_be32s(f, &s->ovl1c[i]);
- for (i = 0; i < 2; i ++)
- qemu_get_be32s(f, &s->ovl2c[i]);
- qemu_get_be32s(f, &s->ccr);
- qemu_get_be32s(f, &s->cmdcr);
- qemu_get_be32s(f, &s->trgbr);
- qemu_get_be32s(f, &s->tcr);
- qemu_get_be32s(f, &s->liidr);
- qemu_get_8s(f, &s->bscntr);
-
- for (i = 0; i < 7; i ++) {
- s->dma_ch[i].branch = qemu_get_betl(f);
- s->dma_ch[i].up = qemu_get_byte(f);
- qemu_get_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer));
-
- s->dma_ch[i].descriptor = qemu_get_betl(f);
- s->dma_ch[i].source = qemu_get_betl(f);
- qemu_get_be32s(f, &s->dma_ch[i].id);
- qemu_get_be32s(f, &s->dma_ch[i].command);
- }
+ PXA2xxLCDState *s = opaque;
s->bpp = LCCR3_BPP(s->control[3]);
s->xres = s->yres = s->pal_for = -1;
@@ -906,6 +860,31 @@ static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
+static const VMStateDescription vmstate_pxa2xx_lcdc = {
+ .name = "pxa2xx_lcdc",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = pxa2xx_lcdc_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(irqlevel, PXA2xxLCDState),
+ VMSTATE_INT32(transp, PXA2xxLCDState),
+ VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6),
+ VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2),
+ VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2),
+ VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2),
+ VMSTATE_UINT32(ccr, PXA2xxLCDState),
+ VMSTATE_UINT32(cmdcr, PXA2xxLCDState),
+ VMSTATE_UINT32(trgbr, PXA2xxLCDState),
+ VMSTATE_UINT32(tcr, PXA2xxLCDState),
+ VMSTATE_UINT32(liidr, PXA2xxLCDState),
+ VMSTATE_UINT8(bscntr, PXA2xxLCDState),
+ VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0,
+ vmstate_dma_channel, struct DMAChannel),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
#define BITS 8
#include "pxa2xx_template.h"
#define BITS 15
@@ -970,8 +949,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
exit(1);
}
- register_savevm(NULL, "pxa2xx_lcdc", 0, 0,
- pxa2xx_lcdc_save, pxa2xx_lcdc_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
return s;
}
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 1088a26f8..eff2d2494 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -354,10 +354,10 @@ static int parse_chr(DeviceState *dev, Property *prop, const char *str)
if (*ptr == NULL) {
return -ENOENT;
}
- if ((*ptr)->assigned) {
+ if ((*ptr)->avail_connections < 1) {
return -EEXIST;
}
- (*ptr)->assigned = 1;
+ --(*ptr)->avail_connections;
return 0;
}
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index d5459336e..515652f27 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -85,9 +85,13 @@
#define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN)
#if defined (DEBUG_RTL8139)
-# define DEBUG_PRINT(x) do { printf x ; } while (0)
+# define DPRINTF(fmt, ...) \
+ do { fprintf(stderr, "RTL8139: " fmt, ## __VA_ARGS__); } while (0)
#else
-# define DEBUG_PRINT(x)
+static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...)
+{
+ return 0;
+}
#endif
/* Symbolic offsets to registers. */
@@ -510,7 +514,7 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time);
static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
{
- DEBUG_PRINT(("RTL8139: eeprom command 0x%02x\n", command));
+ DPRINTF("eeprom command 0x%02x\n", command);
switch (command & Chip9346_op_mask)
{
@@ -521,8 +525,8 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
eeprom->eedo = 0;
eeprom->tick = 0;
eeprom->mode = Chip9346_data_read;
- DEBUG_PRINT(("RTL8139: eeprom read from address 0x%02x data=0x%04x\n",
- eeprom->address, eeprom->output));
+ DPRINTF("eeprom read from address 0x%02x data=0x%04x\n",
+ eeprom->address, eeprom->output);
}
break;
@@ -532,8 +536,8 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
eeprom->input = 0;
eeprom->tick = 0;
eeprom->mode = Chip9346_none; /* Chip9346_data_write */
- DEBUG_PRINT(("RTL8139: eeprom begin write to address 0x%02x\n",
- eeprom->address));
+ DPRINTF("eeprom begin write to address 0x%02x\n",
+ eeprom->address);
}
break;
default:
@@ -541,13 +545,13 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
switch (command & Chip9346_op_ext_mask)
{
case Chip9346_op_write_enable:
- DEBUG_PRINT(("RTL8139: eeprom write enabled\n"));
+ DPRINTF("eeprom write enabled\n");
break;
case Chip9346_op_write_all:
- DEBUG_PRINT(("RTL8139: eeprom begin write all\n"));
+ DPRINTF("eeprom begin write all\n");
break;
case Chip9346_op_write_disable:
- DEBUG_PRINT(("RTL8139: eeprom write disabled\n"));
+ DPRINTF("eeprom write disabled\n");
break;
}
break;
@@ -560,7 +564,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
++ eeprom->tick;
- DEBUG_PRINT(("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, eeprom->eedo));
+ DPRINTF("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi,
+ eeprom->eedo);
switch (eeprom->mode)
{
@@ -570,7 +575,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
eeprom->mode = Chip9346_read_command;
eeprom->tick = 0;
eeprom->input = 0;
- DEBUG_PRINT(("eeprom: +++ synchronized, begin command read\n"));
+ DPRINTF("eeprom: +++ synchronized, begin command read\n");
}
break;
@@ -595,7 +600,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
eeprom->input = 0;
eeprom->tick = 0;
- DEBUG_PRINT(("eeprom: +++ end of read, awaiting next command\n"));
+ DPRINTF("eeprom: +++ end of read, awaiting next command\n");
#else
// original behaviour
++eeprom->address;
@@ -603,8 +608,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
eeprom->output = eeprom->contents[eeprom->address];
eeprom->tick = 0;
- DEBUG_PRINT(("eeprom: +++ read next address 0x%02x data=0x%04x\n",
- eeprom->address, eeprom->output));
+ DPRINTF("eeprom: +++ read next address 0x%02x data=0x%04x\n",
+ eeprom->address, eeprom->output);
#endif
}
break;
@@ -613,8 +618,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
eeprom->input = (eeprom->input << 1) | (bit & 1);
if (eeprom->tick == 16)
{
- DEBUG_PRINT(("RTL8139: eeprom write to address 0x%02x data=0x%04x\n",
- eeprom->address, eeprom->input));
+ DPRINTF("eeprom write to address 0x%02x data=0x%04x\n",
+ eeprom->address, eeprom->input);
eeprom->contents[eeprom->address] = eeprom->input;
eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */
@@ -632,8 +637,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
{
eeprom->contents[i] = eeprom->input;
}
- DEBUG_PRINT(("RTL8139: eeprom filled with data=0x%04x\n",
- eeprom->input));
+ DPRINTF("eeprom filled with data=0x%04x\n", eeprom->input);
eeprom->mode = Chip9346_enter_command_mode;
eeprom->tick = 0;
@@ -666,8 +670,8 @@ static void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi)
eeprom->eesk = eesk;
eeprom->eedi = eedi;
- DEBUG_PRINT(("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n",
- eeprom->eecs, eeprom->eesk, eeprom->eedi, eeprom->eedo));
+ DPRINTF("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n", eeprom->eecs,
+ eeprom->eesk, eeprom->eedi, eeprom->eedo);
if (!old_eecs && eecs)
{
@@ -677,12 +681,12 @@ static void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi)
eeprom->output = 0;
eeprom->mode = Chip9346_enter_command_mode;
- DEBUG_PRINT(("=== eeprom: begin access, enter command mode\n"));
+ DPRINTF("=== eeprom: begin access, enter command mode\n");
}
if (!eecs)
{
- DEBUG_PRINT(("=== eeprom: end access\n"));
+ DPRINTF("=== eeprom: end access\n");
return;
}
@@ -698,8 +702,8 @@ static void rtl8139_update_irq(RTL8139State *s)
int isr;
isr = (s->IntrStatus & s->IntrMask) & 0xffff;
- DEBUG_PRINT(("RTL8139: Set IRQ to %d (%04x %04x)\n",
- isr ? 1 : 0, s->IntrStatus, s->IntrMask));
+ DPRINTF("Set IRQ to %d (%04x %04x)\n", isr ? 1 : 0, s->IntrStatus,
+ s->IntrMask);
qemu_set_irq(s->dev.irq[0], (isr != 0));
}
@@ -763,7 +767,7 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
/* write packet data */
if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s)))
{
- DEBUG_PRINT((">>> RTL8139: rx packet wrapped in buffer at %d\n", size-wrapped));
+ DPRINTF(">>> rx packet wrapped in buffer at %d\n", size - wrapped);
if (size > wrapped)
{
@@ -834,12 +838,12 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
static const uint8_t broadcast_macaddr[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- DEBUG_PRINT((">>> RTL8139: received len=%d\n", size));
+ DPRINTF(">>> received len=%d\n", size);
/* test if board clock is stopped */
if (!s->clock_enabled)
{
- DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
+ DPRINTF("stopped ==========================\n");
return -1;
}
@@ -847,21 +851,21 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
if (!rtl8139_receiver_enabled(s))
{
- DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
+ DPRINTF("receiver disabled ================\n");
return -1;
}
/* XXX: check this */
if (s->RxConfig & AcceptAllPhys) {
/* promiscuous: receive all */
- DEBUG_PRINT((">>> RTL8139: packet received in promiscuous mode\n"));
+ DPRINTF(">>> packet received in promiscuous mode\n");
} else {
if (!memcmp(buf, broadcast_macaddr, 6)) {
/* broadcast address */
if (!(s->RxConfig & AcceptBroadcast))
{
- DEBUG_PRINT((">>> RTL8139: broadcast packet rejected\n"));
+ DPRINTF(">>> broadcast packet rejected\n");
/* update tally counter */
++s->tally_counters.RxERR;
@@ -871,7 +875,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
packet_header |= RxBroadcast;
- DEBUG_PRINT((">>> RTL8139: broadcast packet received\n"));
+ DPRINTF(">>> broadcast packet received\n");
/* update tally counter */
++s->tally_counters.RxOkBrd;
@@ -880,7 +884,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
/* multicast */
if (!(s->RxConfig & AcceptMulticast))
{
- DEBUG_PRINT((">>> RTL8139: multicast packet rejected\n"));
+ DPRINTF(">>> multicast packet rejected\n");
/* update tally counter */
++s->tally_counters.RxERR;
@@ -892,7 +896,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
{
- DEBUG_PRINT((">>> RTL8139: multicast address mismatch\n"));
+ DPRINTF(">>> multicast address mismatch\n");
/* update tally counter */
++s->tally_counters.RxERR;
@@ -902,7 +906,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
packet_header |= RxMulticast;
- DEBUG_PRINT((">>> RTL8139: multicast packet received\n"));
+ DPRINTF(">>> multicast packet received\n");
/* update tally counter */
++s->tally_counters.RxOkMul;
@@ -916,7 +920,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
/* match */
if (!(s->RxConfig & AcceptMyPhys))
{
- DEBUG_PRINT((">>> RTL8139: rejecting physical address matching packet\n"));
+ DPRINTF(">>> rejecting physical address matching packet\n");
/* update tally counter */
++s->tally_counters.RxERR;
@@ -926,14 +930,14 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
packet_header |= RxPhysical;
- DEBUG_PRINT((">>> RTL8139: physical address matching packet received\n"));
+ DPRINTF(">>> physical address matching packet received\n");
/* update tally counter */
++s->tally_counters.RxOkPhy;
} else {
- DEBUG_PRINT((">>> RTL8139: unknown packet\n"));
+ DPRINTF(">>> unknown packet\n");
/* update tally counter */
++s->tally_counters.RxERR;
@@ -955,7 +959,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
if (rtl8139_cp_receiver_enabled(s))
{
- DEBUG_PRINT(("RTL8139: in C+ Rx mode ================\n"));
+ DPRINTF("in C+ Rx mode ================\n");
/* begin C+ receiver mode */
@@ -978,8 +982,9 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);
cplus_rx_ring_desc += 16 * descriptor;
- DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from host memory at %08x %08x = %016" PRIx64 "\n",
- descriptor, s->RxRingAddrHI, s->RxRingAddrLO, (uint64_t)cplus_rx_ring_desc));
+ DPRINTF("+++ C+ mode reading RX descriptor %d from host memory at "
+ "%08x %08x = "TARGET_FMT_plx"\n", descriptor, s->RxRingAddrHI,
+ s->RxRingAddrLO, cplus_rx_ring_desc);
uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;
@@ -992,13 +997,13 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
rxbufHI = le32_to_cpu(val);
- DEBUG_PRINT(("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",
- descriptor,
- rxdw0, rxdw1, rxbufLO, rxbufHI));
+ DPRINTF("+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",
+ descriptor, rxdw0, rxdw1, rxbufLO, rxbufHI);
if (!(rxdw0 & CP_RX_OWN))
{
- DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d is owned by host\n", descriptor));
+ DPRINTF("C+ Rx mode : descriptor %d is owned by host\n",
+ descriptor);
s->IntrStatus |= RxOverflow;
++s->RxMissed;
@@ -1028,9 +1033,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
rxdw1 |= CP_RX_TAVA | le16_to_cpup((uint16_t *)
&dot1q_buf[ETHER_TYPE_LEN]);
- DEBUG_PRINT(("RTL8139: C+ Rx mode : extracted vlan tag with tci: "
- "%u\n", be16_to_cpup((uint16_t *)
- &dot1q_buf[ETHER_TYPE_LEN])));
+ DPRINTF("C+ Rx mode : extracted vlan tag with tci: ""%u\n",
+ be16_to_cpup((uint16_t *)&dot1q_buf[ETHER_TYPE_LEN]));
} else {
/* reset VLAN tag flag */
rxdw1 &= ~CP_RX_TAVA;
@@ -1040,8 +1044,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
if (size+4 > rx_space)
{
- DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d size %d received %d + 4\n",
- descriptor, rx_space, size));
+ DPRINTF("C+ Rx mode : descriptor %d size %d received %d + 4\n",
+ descriptor, rx_space, size);
s->IntrStatus |= RxOverflow;
++s->RxMissed;
@@ -1136,12 +1140,12 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
++s->currCPlusRxDesc;
}
- DEBUG_PRINT(("RTL8139: done C+ Rx mode ----------------\n"));
+ DPRINTF("done C+ Rx mode ----------------\n");
}
else
{
- DEBUG_PRINT(("RTL8139: in ring Rx mode ================\n"));
+ DPRINTF("in ring Rx mode ================\n");
/* begin ring receiver mode */
int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize);
@@ -1150,8 +1154,9 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
if (avail != 0 && size + 8 >= avail)
{
- DEBUG_PRINT(("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n",
- s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8));
+ DPRINTF("rx overflow: rx buffer length %d head 0x%04x "
+ "read 0x%04x === available 0x%04x need 0x%04x\n",
+ s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8);
s->IntrStatus |= RxOverflow;
++s->RxMissed;
@@ -1179,8 +1184,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
/* now we can signal we have received something */
- DEBUG_PRINT((" received: rx buffer length %d head 0x%04x read 0x%04x\n",
- s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
+ DPRINTF("received: rx buffer length %d head 0x%04x read 0x%04x\n",
+ s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);
}
s->IntrStatus |= RxOK;
@@ -1374,22 +1379,22 @@ static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val)
{
val &= 0xff;
- DEBUG_PRINT(("RTL8139: ChipCmd write val=0x%08x\n", val));
+ DPRINTF("ChipCmd write val=0x%08x\n", val);
if (val & CmdReset)
{
- DEBUG_PRINT(("RTL8139: ChipCmd reset\n"));
+ DPRINTF("ChipCmd reset\n");
rtl8139_reset(&s->dev.qdev);
}
if (val & CmdRxEnb)
{
- DEBUG_PRINT(("RTL8139: ChipCmd enable receiver\n"));
+ DPRINTF("ChipCmd enable receiver\n");
s->currCPlusRxDesc = 0;
}
if (val & CmdTxEnb)
{
- DEBUG_PRINT(("RTL8139: ChipCmd enable transmitter\n"));
+ DPRINTF("ChipCmd enable transmitter\n");
s->currCPlusTxDesc = 0;
}
@@ -1409,11 +1414,11 @@ static int rtl8139_RxBufferEmpty(RTL8139State *s)
if (unread != 0)
{
- DEBUG_PRINT(("RTL8139: receiver buffer data available 0x%04x\n", unread));
+ DPRINTF("receiver buffer data available 0x%04x\n", unread);
return 0;
}
- DEBUG_PRINT(("RTL8139: receiver buffer is empty\n"));
+ DPRINTF("receiver buffer is empty\n");
return 1;
}
@@ -1425,7 +1430,7 @@ static uint32_t rtl8139_ChipCmd_read(RTL8139State *s)
if (rtl8139_RxBufferEmpty(s))
ret |= RxBufEmpty;
- DEBUG_PRINT(("RTL8139: ChipCmd read val=0x%04x\n", ret));
+ DPRINTF("ChipCmd read val=0x%04x\n", ret);
return ret;
}
@@ -1434,7 +1439,7 @@ static void rtl8139_CpCmd_write(RTL8139State *s, uint32_t val)
{
val &= 0xffff;
- DEBUG_PRINT(("RTL8139C+ command register write(w) val=0x%04x\n", val));
+ DPRINTF("C+ command register write(w) val=0x%04x\n", val);
s->cplus_enabled = 1;
@@ -1448,21 +1453,21 @@ static uint32_t rtl8139_CpCmd_read(RTL8139State *s)
{
uint32_t ret = s->CpCmd;
- DEBUG_PRINT(("RTL8139C+ command register read(w) val=0x%04x\n", ret));
+ DPRINTF("C+ command register read(w) val=0x%04x\n", ret);
return ret;
}
static void rtl8139_IntrMitigate_write(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139C+ IntrMitigate register write(w) val=0x%04x\n", val));
+ DPRINTF("C+ IntrMitigate register write(w) val=0x%04x\n", val);
}
static uint32_t rtl8139_IntrMitigate_read(RTL8139State *s)
{
uint32_t ret = 0;
- DEBUG_PRINT(("RTL8139C+ IntrMitigate register read(w) val=0x%04x\n", ret));
+ DPRINTF("C+ IntrMitigate register read(w) val=0x%04x\n", ret);
return ret;
}
@@ -1474,7 +1479,7 @@ static int rtl8139_config_writeable(RTL8139State *s)
return 1;
}
- DEBUG_PRINT(("RTL8139: Configuration registers are write-protected\n"));
+ DPRINTF("Configuration registers are write-protected\n");
return 0;
}
@@ -1483,7 +1488,7 @@ static void rtl8139_BasicModeCtrl_write(RTL8139State *s, uint32_t val)
{
val &= 0xffff;
- DEBUG_PRINT(("RTL8139: BasicModeCtrl register write(w) val=0x%04x\n", val));
+ DPRINTF("BasicModeCtrl register write(w) val=0x%04x\n", val);
/* mask unwriteable bits */
uint32_t mask = 0x4cff;
@@ -1505,7 +1510,7 @@ static uint32_t rtl8139_BasicModeCtrl_read(RTL8139State *s)
{
uint32_t ret = s->BasicModeCtrl;
- DEBUG_PRINT(("RTL8139: BasicModeCtrl register read(w) val=0x%04x\n", ret));
+ DPRINTF("BasicModeCtrl register read(w) val=0x%04x\n", ret);
return ret;
}
@@ -1514,7 +1519,7 @@ static void rtl8139_BasicModeStatus_write(RTL8139State *s, uint32_t val)
{
val &= 0xffff;
- DEBUG_PRINT(("RTL8139: BasicModeStatus register write(w) val=0x%04x\n", val));
+ DPRINTF("BasicModeStatus register write(w) val=0x%04x\n", val);
/* mask unwriteable bits */
val = SET_MASKED(val, 0xff3f, s->BasicModeStatus);
@@ -1526,7 +1531,7 @@ static uint32_t rtl8139_BasicModeStatus_read(RTL8139State *s)
{
uint32_t ret = s->BasicModeStatus;
- DEBUG_PRINT(("RTL8139: BasicModeStatus register read(w) val=0x%04x\n", ret));
+ DPRINTF("BasicModeStatus register read(w) val=0x%04x\n", ret);
return ret;
}
@@ -1535,7 +1540,7 @@ static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val)
{
val &= 0xff;
- DEBUG_PRINT(("RTL8139: Cfg9346 write val=0x%02x\n", val));
+ DPRINTF("Cfg9346 write val=0x%02x\n", val);
/* mask unwriteable bits */
val = SET_MASKED(val, 0x31, s->Cfg9346);
@@ -1578,7 +1583,7 @@ static uint32_t rtl8139_Cfg9346_read(RTL8139State *s)
}
}
- DEBUG_PRINT(("RTL8139: Cfg9346 read val=0x%02x\n", ret));
+ DPRINTF("Cfg9346 read val=0x%02x\n", ret);
return ret;
}
@@ -1587,7 +1592,7 @@ static void rtl8139_Config0_write(RTL8139State *s, uint32_t val)
{
val &= 0xff;
- DEBUG_PRINT(("RTL8139: Config0 write val=0x%02x\n", val));
+ DPRINTF("Config0 write val=0x%02x\n", val);
if (!rtl8139_config_writeable(s))
return;
@@ -1602,7 +1607,7 @@ static uint32_t rtl8139_Config0_read(RTL8139State *s)
{
uint32_t ret = s->Config0;
- DEBUG_PRINT(("RTL8139: Config0 read val=0x%02x\n", ret));
+ DPRINTF("Config0 read val=0x%02x\n", ret);
return ret;
}
@@ -1611,7 +1616,7 @@ static void rtl8139_Config1_write(RTL8139State *s, uint32_t val)
{
val &= 0xff;
- DEBUG_PRINT(("RTL8139: Config1 write val=0x%02x\n", val));
+ DPRINTF("Config1 write val=0x%02x\n", val);
if (!rtl8139_config_writeable(s))
return;
@@ -1626,7 +1631,7 @@ static uint32_t rtl8139_Config1_read(RTL8139State *s)
{
uint32_t ret = s->Config1;
- DEBUG_PRINT(("RTL8139: Config1 read val=0x%02x\n", ret));
+ DPRINTF("Config1 read val=0x%02x\n", ret);
return ret;
}
@@ -1635,7 +1640,7 @@ static void rtl8139_Config3_write(RTL8139State *s, uint32_t val)
{
val &= 0xff;
- DEBUG_PRINT(("RTL8139: Config3 write val=0x%02x\n", val));
+ DPRINTF("Config3 write val=0x%02x\n", val);
if (!rtl8139_config_writeable(s))
return;
@@ -1650,7 +1655,7 @@ static uint32_t rtl8139_Config3_read(RTL8139State *s)
{
uint32_t ret = s->Config3;
- DEBUG_PRINT(("RTL8139: Config3 read val=0x%02x\n", ret));
+ DPRINTF("Config3 read val=0x%02x\n", ret);
return ret;
}
@@ -1659,7 +1664,7 @@ static void rtl8139_Config4_write(RTL8139State *s, uint32_t val)
{
val &= 0xff;
- DEBUG_PRINT(("RTL8139: Config4 write val=0x%02x\n", val));
+ DPRINTF("Config4 write val=0x%02x\n", val);
if (!rtl8139_config_writeable(s))
return;
@@ -1674,7 +1679,7 @@ static uint32_t rtl8139_Config4_read(RTL8139State *s)
{
uint32_t ret = s->Config4;
- DEBUG_PRINT(("RTL8139: Config4 read val=0x%02x\n", ret));
+ DPRINTF("Config4 read val=0x%02x\n", ret);
return ret;
}
@@ -1683,7 +1688,7 @@ static void rtl8139_Config5_write(RTL8139State *s, uint32_t val)
{
val &= 0xff;
- DEBUG_PRINT(("RTL8139: Config5 write val=0x%02x\n", val));
+ DPRINTF("Config5 write val=0x%02x\n", val);
/* mask unwriteable bits */
val = SET_MASKED(val, 0x80, s->Config5);
@@ -1695,7 +1700,7 @@ static uint32_t rtl8139_Config5_read(RTL8139State *s)
{
uint32_t ret = s->Config5;
- DEBUG_PRINT(("RTL8139: Config5 read val=0x%02x\n", ret));
+ DPRINTF("Config5 read val=0x%02x\n", ret);
return ret;
}
@@ -1704,11 +1709,11 @@ static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val)
{
if (!rtl8139_transmitter_enabled(s))
{
- DEBUG_PRINT(("RTL8139: transmitter disabled; no TxConfig write val=0x%08x\n", val));
+ DPRINTF("transmitter disabled; no TxConfig write val=0x%08x\n", val);
return;
}
- DEBUG_PRINT(("RTL8139: TxConfig write val=0x%08x\n", val));
+ DPRINTF("TxConfig write val=0x%08x\n", val);
val = SET_MASKED(val, TxVersionMask | 0x8070f80f, s->TxConfig);
@@ -1717,7 +1722,7 @@ static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val)
static void rtl8139_TxConfig_writeb(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139C TxConfig via write(b) val=0x%02x\n", val));
+ DPRINTF("RTL8139C TxConfig via write(b) val=0x%02x\n", val);
uint32_t tc = s->TxConfig;
tc &= 0xFFFFFF00;
@@ -1729,14 +1734,14 @@ static uint32_t rtl8139_TxConfig_read(RTL8139State *s)
{
uint32_t ret = s->TxConfig;
- DEBUG_PRINT(("RTL8139: TxConfig read val=0x%04x\n", ret));
+ DPRINTF("TxConfig read val=0x%04x\n", ret);
return ret;
}
static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139: RxConfig write val=0x%08x\n", val));
+ DPRINTF("RxConfig write val=0x%08x\n", val);
/* mask unwriteable bits */
val = SET_MASKED(val, 0xf0fc0040, s->RxConfig);
@@ -1746,14 +1751,14 @@ static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val)
/* reset buffer size and read/write pointers */
rtl8139_reset_rxring(s, 8192 << ((s->RxConfig >> 11) & 0x3));
- DEBUG_PRINT(("RTL8139: RxConfig write reset buffer size to %d\n", s->RxBufferSize));
+ DPRINTF("RxConfig write reset buffer size to %d\n", s->RxBufferSize);
}
static uint32_t rtl8139_RxConfig_read(RTL8139State *s)
{
uint32_t ret = s->RxConfig;
- DEBUG_PRINT(("RTL8139: RxConfig read val=0x%08x\n", ret));
+ DPRINTF("RxConfig read val=0x%08x\n", ret);
return ret;
}
@@ -1765,7 +1770,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
if (!size)
{
- DEBUG_PRINT(("RTL8139: +++ empty ethernet frame\n"));
+ DPRINTF("+++ empty ethernet frame\n");
return;
}
@@ -1790,7 +1795,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
buf = buf2;
}
- DEBUG_PRINT(("RTL8139: +++ transmit loopback mode\n"));
+ DPRINTF("+++ transmit loopback mode\n");
rtl8139_do_receive(&s->nic->nc, buf, size, do_interrupt);
if (iov) {
@@ -1811,25 +1816,25 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
{
if (!rtl8139_transmitter_enabled(s))
{
- DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: transmitter disabled\n",
- descriptor));
+ DPRINTF("+++ cannot transmit from descriptor %d: transmitter "
+ "disabled\n", descriptor);
return 0;
}
if (s->TxStatus[descriptor] & TxHostOwns)
{
- DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: owned by host (%08x)\n",
- descriptor, s->TxStatus[descriptor]));
+ DPRINTF("+++ cannot transmit from descriptor %d: owned by host "
+ "(%08x)\n", descriptor, s->TxStatus[descriptor]);
return 0;
}
- DEBUG_PRINT(("RTL8139: +++ transmitting from descriptor %d\n", descriptor));
+ DPRINTF("+++ transmitting from descriptor %d\n", descriptor);
int txsize = s->TxStatus[descriptor] & 0x1fff;
uint8_t txbuffer[0x2000];
- DEBUG_PRINT(("RTL8139: +++ transmit reading %d bytes from host memory at 0x%08x\n",
- txsize, s->TxAddr[descriptor]));
+ DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n",
+ txsize, s->TxAddr[descriptor]);
cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
@@ -1839,7 +1844,8 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
rtl8139_transfer_frame(s, txbuffer, txsize, 0, NULL);
- DEBUG_PRINT(("RTL8139: +++ transmitted %d bytes from descriptor %d\n", txsize, descriptor));
+ DPRINTF("+++ transmitted %d bytes from descriptor %d\n", txsize,
+ descriptor);
/* update interrupt */
s->IntrStatus |= TxOK;
@@ -1939,13 +1945,13 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
{
if (!rtl8139_transmitter_enabled(s))
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode: transmitter disabled\n"));
+ DPRINTF("+++ C+ mode: transmitter disabled\n");
return 0;
}
if (!rtl8139_cp_transmitter_enabled(s))
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode: C+ transmitter disabled\n"));
+ DPRINTF("+++ C+ mode: C+ transmitter disabled\n");
return 0 ;
}
@@ -1957,8 +1963,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
/* Normal priority ring */
cplus_tx_ring_desc += 16 * descriptor;
- DEBUG_PRINT(("RTL8139: +++ C+ mode reading TX descriptor %d from host memory at %08x0x%08x = 0x%8lx\n",
- descriptor, s->TxAddr[1], s->TxAddr[0], cplus_tx_ring_desc));
+ DPRINTF("+++ C+ mode reading TX descriptor %d from host memory at "
+ "%08x0x%08x = 0x"TARGET_FMT_plx"\n", descriptor, s->TxAddr[1],
+ s->TxAddr[0], cplus_tx_ring_desc);
uint32_t val, txdw0,txdw1,txbufLO,txbufHI;
@@ -1971,9 +1978,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
txbufHI = le32_to_cpu(val);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TX descriptor %d %08x %08x %08x %08x\n",
- descriptor,
- txdw0, txdw1, txbufLO, txbufHI));
+ DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor,
+ txdw0, txdw1, txbufLO, txbufHI);
/* w0 ownership flag */
#define CP_TX_OWN (1<<31)
@@ -2019,15 +2025,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
if (!(txdw0 & CP_TX_OWN))
{
- DEBUG_PRINT(("RTL8139: C+ Tx mode : descriptor %d is owned by host\n", descriptor));
+ DPRINTF("C+ Tx mode : descriptor %d is owned by host\n", descriptor);
return 0 ;
}
- DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : transmitting from descriptor %d\n", descriptor));
+ DPRINTF("+++ C+ Tx mode : transmitting from descriptor %d\n", descriptor);
if (txdw0 & CP_TX_FS)
{
- DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is first segment descriptor\n", descriptor));
+ DPRINTF("+++ C+ Tx mode : descriptor %d is first segment "
+ "descriptor\n", descriptor);
/* reset internal buffer offset */
s->cplus_txbuffer_offset = 0;
@@ -2043,7 +2050,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
s->cplus_txbuffer = qemu_malloc(s->cplus_txbuffer_len);
s->cplus_txbuffer_offset = 0;
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len));
+ DPRINTF("+++ C+ mode transmission buffer allocated space %d\n",
+ s->cplus_txbuffer_len);
}
while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
@@ -2051,14 +2059,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
s->cplus_txbuffer = qemu_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len));
+ DPRINTF("+++ C+ mode transmission buffer space changed to %d\n",
+ s->cplus_txbuffer_len);
}
if (!s->cplus_txbuffer)
{
/* out of memory */
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmiter failed to reallocate %d bytes\n", s->cplus_txbuffer_len));
+ DPRINTF("+++ C+ mode transmiter failed to reallocate %d bytes\n",
+ s->cplus_txbuffer_len);
/* update tally counter */
++s->tally_counters.TxERR;
@@ -2069,8 +2079,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
/* append more data to the packet */
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host memory at %016" PRIx64 " to offset %d\n",
- txsize, (uint64_t)tx_addr, s->cplus_txbuffer_offset));
+ DPRINTF("+++ C+ mode transmit reading %d bytes from host memory at "
+ TARGET_FMT_plx" to offset %d\n", txsize, tx_addr,
+ s->cplus_txbuffer_offset);
cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
s->cplus_txbuffer_offset += txsize;
@@ -2107,7 +2118,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
uint8_t dot1q_buffer_space[VLAN_HLEN];
uint16_t *dot1q_buffer;
- DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is last segment descriptor\n", descriptor));
+ DPRINTF("+++ C+ Tx mode : descriptor %d is last segment descriptor\n",
+ descriptor);
/* can transfer fully assembled packet */
@@ -2119,8 +2131,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
if (txdw1 & CP_TX_TAGC) {
/* the vlan tag is in BE byte order in the descriptor
* BE + le_to_cpu() + ~swap()~ = cpu */
- DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : inserting vlan tag with "
- "tci: %u\n", bswap16(txdw1 & CP_TX_VLAN_TAG_MASK)));
+ DPRINTF("+++ C+ Tx mode : inserting vlan tag with ""tci: %u\n",
+ bswap16(txdw1 & CP_TX_VLAN_TAG_MASK));
dot1q_buffer = (uint16_t *) dot1q_buffer_space;
dot1q_buffer[0] = cpu_to_be16(ETH_P_8021Q);
@@ -2137,7 +2149,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN))
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task checksum\n"));
+ DPRINTF("+++ C+ mode offloaded task checksum\n");
/* ip packet header */
ip_header *ip = NULL;
@@ -2151,7 +2163,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
if (proto == ETH_P_IP)
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode has IP packet\n"));
+ DPRINTF("+++ C+ mode has IP packet\n");
/* not aligned */
eth_payload_data = saved_buffer + ETH_HLEN;
@@ -2160,7 +2172,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
ip = (ip_header*)eth_payload_data;
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
- DEBUG_PRINT(("RTL8139: +++ C+ mode packet has bad IP version %d expected %d\n", IP_HEADER_VERSION(ip), IP_HEADER_VERSION_4));
+ DPRINTF("+++ C+ mode packet has bad IP version %d "
+ "expected %d\n", IP_HEADER_VERSION(ip),
+ IP_HEADER_VERSION_4);
ip = NULL;
} else {
hlen = IP_HEADER_LENGTH(ip);
@@ -2173,7 +2187,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
{
if (txdw0 & CP_TX_IPCS)
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n"));
+ DPRINTF("+++ C+ mode need IP checksum\n");
if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */
/* bad packet header len */
@@ -2183,17 +2197,18 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
{
ip->ip_sum = 0;
ip->ip_sum = ip_checksum(ip, hlen);
- DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
+ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",
+ hlen, ip->ip_sum);
}
}
if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
{
-#if defined (DEBUG_RTL8139)
int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
-#endif
- DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n",
- ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss));
+
+ DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
+ "frame data %d specified MSS=%d\n", ETH_MTU,
+ ip_data_len, saved_size - ETH_HLEN, large_send_mss);
int tcp_send_offset = 0;
int send_count = 0;
@@ -2217,8 +2232,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
int tcp_data_len = ip_data_len - tcp_hlen;
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n",
- ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size));
+ DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "
+ "data len %d TCP chunk size %d\n", ip_data_len,
+ tcp_hlen, tcp_data_len, tcp_chunk_size);
/* note the cycle below overwrites IP header data,
but restores it from saved_ip_header before sending packet */
@@ -2236,13 +2252,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
chunk_size = tcp_data_len - tcp_send_offset;
}
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq)));
+ DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",
+ be32_to_cpu(p_tcp_hdr->th_seq));
/* add 4 TCP pseudoheader fields */
/* copy IP source and destination fields */
memcpy(data_to_checksum, saved_ip_header + 12, 8);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size));
+ DPRINTF("+++ C+ mode TSO calculating TCP checksum for "
+ "packet with %d bytes data\n", tcp_hlen +
+ chunk_size);
if (tcp_send_offset)
{
@@ -2264,7 +2283,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
p_tcp_hdr->th_sum = 0;
int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum));
+ DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",
+ tcp_checksum);
p_tcp_hdr->th_sum = tcp_checksum;
@@ -2279,10 +2299,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
ip->ip_sum = 0;
ip->ip_sum = ip_checksum(eth_payload_data, hlen);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
+ DPRINTF("+++ C+ mode TSO IP header len=%d "
+ "checksum=%04x\n", hlen, ip->ip_sum);
int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size));
+ DPRINTF("+++ C+ mode TSO transferring packet size "
+ "%d\n", tso_send_size);
rtl8139_transfer_frame(s, saved_buffer, tso_send_size,
0, (uint8_t *) dot1q_buffer);
@@ -2296,7 +2318,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
}
else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n"));
+ DPRINTF("+++ C+ mode need TCP or UDP checksum\n");
/* maximum IP header length is 60 bytes */
uint8_t saved_ip_header[60];
@@ -2311,7 +2333,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len));
+ DPRINTF("+++ C+ mode calculating TCP checksum for "
+ "packet with %d bytes data\n", ip_data_len);
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_tcpip_hdr->zeros = 0;
@@ -2323,13 +2346,15 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
p_tcp_hdr->th_sum = 0;
int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum));
+ DPRINTF("+++ C+ mode TCP checksum %04x\n",
+ tcp_checksum);
p_tcp_hdr->th_sum = tcp_checksum;
}
else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len));
+ DPRINTF("+++ C+ mode calculating UDP checksum for "
+ "packet with %d bytes data\n", ip_data_len);
ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_udpip_hdr->zeros = 0;
@@ -2341,7 +2366,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
p_udp_hdr->uh_sum = 0;
int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum));
+ DPRINTF("+++ C+ mode UDP checksum %04x\n",
+ udp_checksum);
p_udp_hdr->uh_sum = udp_checksum;
}
@@ -2355,7 +2381,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
/* update tally counter */
++s->tally_counters.TxOk;
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmitting %d bytes packet\n", saved_size));
+ DPRINTF("+++ C+ mode transmitting %d bytes packet\n", saved_size);
rtl8139_transfer_frame(s, saved_buffer, saved_size, 1,
(uint8_t *) dot1q_buffer);
@@ -2374,7 +2400,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
}
else
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode transmission continue to next descriptor\n"));
+ DPRINTF("+++ C+ mode transmission continue to next descriptor\n");
}
return 1;
@@ -2392,8 +2418,8 @@ static void rtl8139_cplus_transmit(RTL8139State *s)
/* Mark transfer completed */
if (!txcount)
{
- DEBUG_PRINT(("RTL8139: C+ mode : transmitter queue stalled, current TxDesc = %d\n",
- s->currCPlusTxDesc));
+ DPRINTF("C+ mode : transmitter queue stalled, current TxDesc = %d\n",
+ s->currCPlusTxDesc);
}
else
{
@@ -2418,7 +2444,8 @@ static void rtl8139_transmit(RTL8139State *s)
/* Mark transfer completed */
if (!txcount)
{
- DEBUG_PRINT(("RTL8139: transmitter queue stalled, current TxDesc = %d\n", s->currTxDesc));
+ DPRINTF("transmitter queue stalled, current TxDesc = %d\n",
+ s->currTxDesc);
}
}
@@ -2431,7 +2458,8 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32
if (s->cplus_enabled)
{
- DEBUG_PRINT(("RTL8139C+ DTCCR write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
+ DPRINTF("RTL8139C+ DTCCR write offset=0x%x val=0x%08x "
+ "descriptor=%d\n", txRegOffset, val, descriptor);
/* handle Dump Tally Counters command */
s->TxStatus[descriptor] = val;
@@ -2450,7 +2478,8 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32
return;
}
- DEBUG_PRINT(("RTL8139: TxStatus write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
+ DPRINTF("TxStatus write offset=0x%x val=0x%08x descriptor=%d\n",
+ txRegOffset, val, descriptor);
/* mask only reserved bits */
val &= ~0xff00c000; /* these bits are reset on write */
@@ -2466,7 +2495,7 @@ static uint32_t rtl8139_TxStatus_read(RTL8139State *s, uint32_t txRegOffset)
{
uint32_t ret = s->TxStatus[txRegOffset/4];
- DEBUG_PRINT(("RTL8139: TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret));
+ DPRINTF("TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret);
return ret;
}
@@ -2498,7 +2527,7 @@ static uint16_t rtl8139_TSAD_read(RTL8139State *s)
|((s->TxStatus[0] & TxHostOwns )?TSAD_OWN0:0) ;
- DEBUG_PRINT(("RTL8139: TSAD read val=0x%04x\n", ret));
+ DPRINTF("TSAD read val=0x%04x\n", ret);
return ret;
}
@@ -2507,14 +2536,14 @@ static uint16_t rtl8139_CSCR_read(RTL8139State *s)
{
uint16_t ret = s->CSCR;
- DEBUG_PRINT(("RTL8139: CSCR read val=0x%04x\n", ret));
+ DPRINTF("CSCR read val=0x%04x\n", ret);
return ret;
}
static void rtl8139_TxAddr_write(RTL8139State *s, uint32_t txAddrOffset, uint32_t val)
{
- DEBUG_PRINT(("RTL8139: TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val));
+ DPRINTF("TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val);
s->TxAddr[txAddrOffset/4] = val;
}
@@ -2523,20 +2552,20 @@ static uint32_t rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset)
{
uint32_t ret = s->TxAddr[txAddrOffset/4];
- DEBUG_PRINT(("RTL8139: TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret));
+ DPRINTF("TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret);
return ret;
}
static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139: RxBufPtr write val=0x%04x\n", val));
+ DPRINTF("RxBufPtr write val=0x%04x\n", val);
/* this value is off by 16 */
s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize);
- DEBUG_PRINT((" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
- s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
+ DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
+ s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);
}
static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s)
@@ -2544,7 +2573,7 @@ static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s)
/* this value is off by 16 */
uint32_t ret = s->RxBufPtr - 0x10;
- DEBUG_PRINT(("RTL8139: RxBufPtr read val=0x%04x\n", ret));
+ DPRINTF("RxBufPtr read val=0x%04x\n", ret);
return ret;
}
@@ -2554,14 +2583,14 @@ static uint32_t rtl8139_RxBufAddr_read(RTL8139State *s)
/* this value is NOT off by 16 */
uint32_t ret = s->RxBufAddr;
- DEBUG_PRINT(("RTL8139: RxBufAddr read val=0x%04x\n", ret));
+ DPRINTF("RxBufAddr read val=0x%04x\n", ret);
return ret;
}
static void rtl8139_RxBuf_write(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139: RxBuf write val=0x%08x\n", val));
+ DPRINTF("RxBuf write val=0x%08x\n", val);
s->RxBuf = val;
@@ -2572,14 +2601,14 @@ static uint32_t rtl8139_RxBuf_read(RTL8139State *s)
{
uint32_t ret = s->RxBuf;
- DEBUG_PRINT(("RTL8139: RxBuf read val=0x%08x\n", ret));
+ DPRINTF("RxBuf read val=0x%08x\n", ret);
return ret;
}
static void rtl8139_IntrMask_write(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139: IntrMask write(w) val=0x%04x\n", val));
+ DPRINTF("IntrMask write(w) val=0x%04x\n", val);
/* mask unwriteable bits */
val = SET_MASKED(val, 0x1e00, s->IntrMask);
@@ -2595,14 +2624,14 @@ static uint32_t rtl8139_IntrMask_read(RTL8139State *s)
{
uint32_t ret = s->IntrMask;
- DEBUG_PRINT(("RTL8139: IntrMask read(w) val=0x%04x\n", ret));
+ DPRINTF("IntrMask read(w) val=0x%04x\n", ret);
return ret;
}
static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139: IntrStatus write(w) val=0x%04x\n", val));
+ DPRINTF("IntrStatus write(w) val=0x%04x\n", val);
#if 0
@@ -2639,7 +2668,7 @@ static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
uint32_t ret = s->IntrStatus;
- DEBUG_PRINT(("RTL8139: IntrStatus read(w) val=0x%04x\n", ret));
+ DPRINTF("IntrStatus read(w) val=0x%04x\n", ret);
#if 0
@@ -2655,7 +2684,7 @@ static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
static void rtl8139_MultiIntr_write(RTL8139State *s, uint32_t val)
{
- DEBUG_PRINT(("RTL8139: MultiIntr write(w) val=0x%04x\n", val));
+ DPRINTF("MultiIntr write(w) val=0x%04x\n", val);
/* mask unwriteable bits */
val = SET_MASKED(val, 0xf000, s->MultiIntr);
@@ -2667,7 +2696,7 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
{
uint32_t ret = s->MultiIntr;
- DEBUG_PRINT(("RTL8139: MultiIntr read(w) val=0x%04x\n", ret));
+ DPRINTF("MultiIntr read(w) val=0x%04x\n", ret);
return ret;
}
@@ -2715,11 +2744,12 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
break;
case MediaStatus:
/* ignore */
- DEBUG_PRINT(("RTL8139: not implemented write(b) to MediaStatus val=0x%02x\n", val));
+ DPRINTF("not implemented write(b) to MediaStatus val=0x%02x\n",
+ val);
break;
case HltClk:
- DEBUG_PRINT(("RTL8139: HltClk write val=0x%08x\n", val));
+ DPRINTF("HltClk write val=0x%08x\n", val);
if (val == 'R')
{
s->clock_enabled = 1;
@@ -2731,27 +2761,29 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
break;
case TxThresh:
- DEBUG_PRINT(("RTL8139C+ TxThresh write(b) val=0x%02x\n", val));
+ DPRINTF("C+ TxThresh write(b) val=0x%02x\n", val);
s->TxThresh = val;
break;
case TxPoll:
- DEBUG_PRINT(("RTL8139C+ TxPoll write(b) val=0x%02x\n", val));
+ DPRINTF("C+ TxPoll write(b) val=0x%02x\n", val);
if (val & (1 << 7))
{
- DEBUG_PRINT(("RTL8139C+ TxPoll high priority transmission (not implemented)\n"));
+ DPRINTF("C+ TxPoll high priority transmission (not "
+ "implemented)\n");
//rtl8139_cplus_transmit(s);
}
if (val & (1 << 6))
{
- DEBUG_PRINT(("RTL8139C+ TxPoll normal priority transmission\n"));
+ DPRINTF("C+ TxPoll normal priority transmission\n");
rtl8139_cplus_transmit(s);
}
break;
default:
- DEBUG_PRINT(("RTL8139: not implemented write(b) addr=0x%x val=0x%02x\n", addr, val));
+ DPRINTF("not implemented write(b) addr=0x%x val=0x%02x\n", addr,
+ val);
break;
}
}
@@ -2787,14 +2819,14 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
rtl8139_BasicModeStatus_write(s, val);
break;
case NWayAdvert:
- DEBUG_PRINT(("RTL8139: NWayAdvert write(w) val=0x%04x\n", val));
+ DPRINTF("NWayAdvert write(w) val=0x%04x\n", val);
s->NWayAdvert = val;
break;
case NWayLPAR:
- DEBUG_PRINT(("RTL8139: forbidden NWayLPAR write(w) val=0x%04x\n", val));
+ DPRINTF("forbidden NWayLPAR write(w) val=0x%04x\n", val);
break;
case NWayExpansion:
- DEBUG_PRINT(("RTL8139: NWayExpansion write(w) val=0x%04x\n", val));
+ DPRINTF("NWayExpansion write(w) val=0x%04x\n", val);
s->NWayExpansion = val;
break;
@@ -2807,7 +2839,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
break;
default:
- DEBUG_PRINT(("RTL8139: ioport write(w) addr=0x%x val=0x%04x via write(b)\n", addr, val));
+ DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
+ addr, val);
rtl8139_io_writeb(opaque, addr, val & 0xff);
rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
@@ -2820,7 +2853,7 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
int64_t pci_time, next_time;
uint32_t low_pci;
- DEBUG_PRINT(("RTL8139: entered rtl8139_set_next_tctr_time\n"));
+ DPRINTF("entered rtl8139_set_next_tctr_time\n");
if (s->TimerExpire && current_time >= s->TimerExpire) {
s->IntrStatus |= PCSTimeout;
@@ -2864,7 +2897,7 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
switch (addr)
{
case RxMissed:
- DEBUG_PRINT(("RTL8139: RxMissed clearing on write\n"));
+ DPRINTF("RxMissed clearing on write\n");
s->RxMissed = 0;
break;
@@ -2889,23 +2922,23 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
break;
case RxRingAddrLO:
- DEBUG_PRINT(("RTL8139: C+ RxRing low bits write val=0x%08x\n", val));
+ DPRINTF("C+ RxRing low bits write val=0x%08x\n", val);
s->RxRingAddrLO = val;
break;
case RxRingAddrHI:
- DEBUG_PRINT(("RTL8139: C+ RxRing high bits write val=0x%08x\n", val));
+ DPRINTF("C+ RxRing high bits write val=0x%08x\n", val);
s->RxRingAddrHI = val;
break;
case Timer:
- DEBUG_PRINT(("RTL8139: TCTR Timer reset on write\n"));
+ DPRINTF("TCTR Timer reset on write\n");
s->TCTR_base = qemu_get_clock_ns(vm_clock);
rtl8139_set_next_tctr_time(s, s->TCTR_base);
break;
case FlashReg:
- DEBUG_PRINT(("RTL8139: FlashReg TimerInt write val=0x%08x\n", val));
+ DPRINTF("FlashReg TimerInt write val=0x%08x\n", val);
if (s->TimerInt != val) {
s->TimerInt = val;
rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
@@ -2913,7 +2946,8 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
break;
default:
- DEBUG_PRINT(("RTL8139: ioport write(l) addr=0x%x val=0x%08x via write(b)\n", addr, val));
+ DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
+ addr, val);
rtl8139_io_writeb(opaque, addr, val & 0xff);
rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
@@ -2964,31 +2998,31 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
case MediaStatus:
ret = 0xd0;
- DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret));
+ DPRINTF("MediaStatus read 0x%x\n", ret);
break;
case HltClk:
ret = s->clock_enabled;
- DEBUG_PRINT(("RTL8139: HltClk read 0x%x\n", ret));
+ DPRINTF("HltClk read 0x%x\n", ret);
break;
case PCIRevisionID:
ret = RTL8139_PCI_REVID;
- DEBUG_PRINT(("RTL8139: PCI Revision ID read 0x%x\n", ret));
+ DPRINTF("PCI Revision ID read 0x%x\n", ret);
break;
case TxThresh:
ret = s->TxThresh;
- DEBUG_PRINT(("RTL8139C+ TxThresh read(b) val=0x%02x\n", ret));
+ DPRINTF("C+ TxThresh read(b) val=0x%02x\n", ret);
break;
case 0x43: /* Part of TxConfig register. Windows driver tries to read it */
ret = s->TxConfig >> 24;
- DEBUG_PRINT(("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret));
+ DPRINTF("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret);
break;
default:
- DEBUG_PRINT(("RTL8139: not implemented read(b) addr=0x%x\n", addr));
+ DPRINTF("not implemented read(b) addr=0x%x\n", addr);
ret = 0;
break;
}
@@ -3033,15 +3067,15 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
break;
case NWayAdvert:
ret = s->NWayAdvert;
- DEBUG_PRINT(("RTL8139: NWayAdvert read(w) val=0x%04x\n", ret));
+ DPRINTF("NWayAdvert read(w) val=0x%04x\n", ret);
break;
case NWayLPAR:
ret = s->NWayLPAR;
- DEBUG_PRINT(("RTL8139: NWayLPAR read(w) val=0x%04x\n", ret));
+ DPRINTF("NWayLPAR read(w) val=0x%04x\n", ret);
break;
case NWayExpansion:
ret = s->NWayExpansion;
- DEBUG_PRINT(("RTL8139: NWayExpansion read(w) val=0x%04x\n", ret));
+ DPRINTF("NWayExpansion read(w) val=0x%04x\n", ret);
break;
case CpCmd:
@@ -3061,12 +3095,12 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
break;
default:
- DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x via read(b)\n", addr));
+ DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
ret = rtl8139_io_readb(opaque, addr);
ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
- DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x val=0x%04x\n", addr, ret));
+ DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
break;
}
@@ -3085,7 +3119,7 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
case RxMissed:
ret = s->RxMissed;
- DEBUG_PRINT(("RTL8139: RxMissed read val=0x%08x\n", ret));
+ DPRINTF("RxMissed read val=0x%08x\n", ret);
break;
case TxConfig:
@@ -3110,34 +3144,34 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
case RxRingAddrLO:
ret = s->RxRingAddrLO;
- DEBUG_PRINT(("RTL8139: C+ RxRing low bits read val=0x%08x\n", ret));
+ DPRINTF("C+ RxRing low bits read val=0x%08x\n", ret);
break;
case RxRingAddrHI:
ret = s->RxRingAddrHI;
- DEBUG_PRINT(("RTL8139: C+ RxRing high bits read val=0x%08x\n", ret));
+ DPRINTF("C+ RxRing high bits read val=0x%08x\n", ret);
break;
case Timer:
ret = muldiv64(qemu_get_clock_ns(vm_clock) - s->TCTR_base,
PCI_FREQUENCY, get_ticks_per_sec());
- DEBUG_PRINT(("RTL8139: TCTR Timer read val=0x%08x\n", ret));
+ DPRINTF("TCTR Timer read val=0x%08x\n", ret);
break;
case FlashReg:
ret = s->TimerInt;
- DEBUG_PRINT(("RTL8139: FlashReg TimerInt read val=0x%08x\n", ret));
+ DPRINTF("FlashReg TimerInt read val=0x%08x\n", ret);
break;
default:
- DEBUG_PRINT(("RTL8139: ioport read(l) addr=0x%x via read(b)\n", addr));
+ DPRINTF("ioport read(l) addr=0x%x via read(b)\n", addr);
ret = rtl8139_io_readb(opaque, addr);
ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
ret |= rtl8139_io_readb(opaque, addr + 2) << 16;
ret |= rtl8139_io_readb(opaque, addr + 3) << 24;
- DEBUG_PRINT(("RTL8139: read(l) addr=0x%x val=%08x\n", addr, ret));
+ DPRINTF("read(l) addr=0x%x val=%08x\n", addr, ret);
break;
}
@@ -3382,7 +3416,7 @@ static void rtl8139_timer(void *opaque)
if (!s->clock_enabled)
{
- DEBUG_PRINT(("RTL8139: >>> timer: clock is not running\n"));
+ DPRINTF(">>> timer: clock is not running\n");
return;
}
@@ -3484,7 +3518,7 @@ static PCIDeviceInfo rtl8139_info = {
.qdev.vmsd = &vmstate_rtl8139,
.init = pci_rtl8139_init,
.exit = pci_rtl8139_uninit,
- .romfile = "pxe-rtl8139.bin",
+ .romfile = "pxe-rtl8139.rom",
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 175e5cb3a..bb49e393e 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -43,6 +43,8 @@
do { } while (0)
#endif
+#define VIRTIO_EXT_CODE 0x2603
+
struct BusInfo s390_virtio_bus_info = {
.name = "s390-virtio",
.size = sizeof(VirtIOS390Bus),
@@ -305,9 +307,13 @@ static void virtio_s390_notify(void *opaque, uint16_t vector)
{
VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
uint64_t token = s390_virtio_device_vq_token(dev, vector);
+ CPUState *env = s390_cpu_addr2state(0);
- /* XXX kvm dependency! */
- kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token);
+ if (kvm_enabled()) {
+ kvm_s390_virtio_irq(env, 0, token);
+ } else {
+ cpu_inject_ext(env, VIRTIO_EXT_CODE, 0, token);
+ }
}
static unsigned virtio_s390_get_features(void *opaque)
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index d429f10d5..698ff6f34 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -82,13 +82,12 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
return ipi_states[cpu_addr];
}
-int s390_virtio_hypercall(CPUState *env)
+int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall)
{
int r = 0, i;
- target_ulong mem = env->regs[2];
- dprintf("KVM hypercall: %ld\n", env->regs[1]);
- switch (env->regs[1]) {
+ dprintf("KVM hypercall: %ld\n", hypercall);
+ switch (hypercall) {
case KVM_S390_VIRTIO_NOTIFY:
if (mem > ram_size) {
VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
@@ -128,8 +127,7 @@ int s390_virtio_hypercall(CPUState *env)
break;
}
- env->regs[2] = r;
- return 0;
+ return r;
}
/* PC hardware initialisation */
@@ -145,14 +143,9 @@ static void s390_init(ram_addr_t ram_size,
ram_addr_t kernel_size = 0;
ram_addr_t initrd_offset;
ram_addr_t initrd_size = 0;
+ uint8_t *storage_keys;
int i;
- /* XXX we only work on KVM for now */
-
- if (!kvm_enabled()) {
- fprintf(stderr, "The S390 target only works with KVM enabled\n");
- exit(1);
- }
/* get a BUS */
s390_bus = s390_virtio_bus_init(&ram_size);
@@ -161,6 +154,9 @@ static void s390_init(ram_addr_t ram_size,
ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size);
cpu_register_physical_memory(0, ram_size, ram_addr);
+ /* allocate storage keys */
+ storage_keys = qemu_mallocz(ram_size / TARGET_PAGE_SIZE);
+
/* init CPUs */
if (cpu_model == NULL) {
cpu_model = "host";
@@ -178,6 +174,7 @@ static void s390_init(ram_addr_t ram_size,
ipi_states[i] = tmp_env;
tmp_env->halted = 1;
tmp_env->exception_index = EXCP_HLT;
+ tmp_env->storage_keys = storage_keys;
}
env->halted = 0;
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 0d5292688..ac9fcc1f3 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -14,7 +14,6 @@
#include "qemu-timer.h"
#include "i2c.h"
#include "net.h"
-#include "sysemu.h"
#include "boards.h"
#define GPIO_A 0
@@ -280,64 +279,28 @@ static CPUWriteMemoryFunc * const gptm_writefn[] = {
gptm_write
};
-static void gptm_save(QEMUFile *f, void *opaque)
-{
- gptm_state *s = (gptm_state *)opaque;
-
- qemu_put_be32(f, s->config);
- qemu_put_be32(f, s->mode[0]);
- qemu_put_be32(f, s->mode[1]);
- qemu_put_be32(f, s->control);
- qemu_put_be32(f, s->state);
- qemu_put_be32(f, s->mask);
- qemu_put_be32(f, s->mode[0]);
- qemu_put_be32(f, s->mode[0]);
- qemu_put_be32(f, s->load[0]);
- qemu_put_be32(f, s->load[1]);
- qemu_put_be32(f, s->match[0]);
- qemu_put_be32(f, s->match[1]);
- qemu_put_be32(f, s->prescale[0]);
- qemu_put_be32(f, s->prescale[1]);
- qemu_put_be32(f, s->match_prescale[0]);
- qemu_put_be32(f, s->match_prescale[1]);
- qemu_put_be32(f, s->rtc);
- qemu_put_be64(f, s->tick[0]);
- qemu_put_be64(f, s->tick[1]);
- qemu_put_timer(f, s->timer[0]);
- qemu_put_timer(f, s->timer[1]);
-}
-
-static int gptm_load(QEMUFile *f, void *opaque, int version_id)
-{
- gptm_state *s = (gptm_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->config = qemu_get_be32(f);
- s->mode[0] = qemu_get_be32(f);
- s->mode[1] = qemu_get_be32(f);
- s->control = qemu_get_be32(f);
- s->state = qemu_get_be32(f);
- s->mask = qemu_get_be32(f);
- s->mode[0] = qemu_get_be32(f);
- s->mode[0] = qemu_get_be32(f);
- s->load[0] = qemu_get_be32(f);
- s->load[1] = qemu_get_be32(f);
- s->match[0] = qemu_get_be32(f);
- s->match[1] = qemu_get_be32(f);
- s->prescale[0] = qemu_get_be32(f);
- s->prescale[1] = qemu_get_be32(f);
- s->match_prescale[0] = qemu_get_be32(f);
- s->match_prescale[1] = qemu_get_be32(f);
- s->rtc = qemu_get_be32(f);
- s->tick[0] = qemu_get_be64(f);
- s->tick[1] = qemu_get_be64(f);
- qemu_get_timer(f, s->timer[0]);
- qemu_get_timer(f, s->timer[1]);
-
- return 0;
-}
+static const VMStateDescription vmstate_stellaris_gptm = {
+ .name = "stellaris_gptm",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(config, gptm_state),
+ VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
+ VMSTATE_UINT32(control, gptm_state),
+ VMSTATE_UINT32(state, gptm_state),
+ VMSTATE_UINT32(mask, gptm_state),
+ VMSTATE_UNUSED(8),
+ VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
+ VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
+ VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
+ VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
+ VMSTATE_UINT32(rtc, gptm_state),
+ VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
+ VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int stellaris_gptm_init(SysBusDevice *dev)
{
@@ -355,8 +318,7 @@ static int stellaris_gptm_init(SysBusDevice *dev)
s->opaque[0] = s->opaque[1] = s;
s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
- register_savevm(&dev->qdev, "stellaris_gptm", -1, 1,
- gptm_save, gptm_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
return 0;
}
@@ -605,58 +567,37 @@ static void ssys_reset(void *opaque)
s->dcgc[0] = 1;
}
-static void ssys_save(QEMUFile *f, void *opaque)
-{
- ssys_state *s = (ssys_state *)opaque;
-
- qemu_put_be32(f, s->pborctl);
- qemu_put_be32(f, s->ldopctl);
- qemu_put_be32(f, s->int_mask);
- qemu_put_be32(f, s->int_status);
- qemu_put_be32(f, s->resc);
- qemu_put_be32(f, s->rcc);
- qemu_put_be32(f, s->rcgc[0]);
- qemu_put_be32(f, s->rcgc[1]);
- qemu_put_be32(f, s->rcgc[2]);
- qemu_put_be32(f, s->scgc[0]);
- qemu_put_be32(f, s->scgc[1]);
- qemu_put_be32(f, s->scgc[2]);
- qemu_put_be32(f, s->dcgc[0]);
- qemu_put_be32(f, s->dcgc[1]);
- qemu_put_be32(f, s->dcgc[2]);
- qemu_put_be32(f, s->clkvclr);
- qemu_put_be32(f, s->ldoarst);
-}
-
-static int ssys_load(QEMUFile *f, void *opaque, int version_id)
+static int stellaris_sys_post_load(void *opaque, int version_id)
{
- ssys_state *s = (ssys_state *)opaque;
+ ssys_state *s = opaque;
- if (version_id != 1)
- return -EINVAL;
-
- s->pborctl = qemu_get_be32(f);
- s->ldopctl = qemu_get_be32(f);
- s->int_mask = qemu_get_be32(f);
- s->int_status = qemu_get_be32(f);
- s->resc = qemu_get_be32(f);
- s->rcc = qemu_get_be32(f);
- s->rcgc[0] = qemu_get_be32(f);
- s->rcgc[1] = qemu_get_be32(f);
- s->rcgc[2] = qemu_get_be32(f);
- s->scgc[0] = qemu_get_be32(f);
- s->scgc[1] = qemu_get_be32(f);
- s->scgc[2] = qemu_get_be32(f);
- s->dcgc[0] = qemu_get_be32(f);
- s->dcgc[1] = qemu_get_be32(f);
- s->dcgc[2] = qemu_get_be32(f);
- s->clkvclr = qemu_get_be32(f);
- s->ldoarst = qemu_get_be32(f);
ssys_calculate_system_clock(s);
return 0;
}
+static const VMStateDescription vmstate_stellaris_sys = {
+ .name = "stellaris_sys",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .post_load = stellaris_sys_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(pborctl, ssys_state),
+ VMSTATE_UINT32(ldopctl, ssys_state),
+ VMSTATE_UINT32(int_mask, ssys_state),
+ VMSTATE_UINT32(int_status, ssys_state),
+ VMSTATE_UINT32(resc, ssys_state),
+ VMSTATE_UINT32(rcc, ssys_state),
+ VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
+ VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
+ VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
+ VMSTATE_UINT32(clkvclr, ssys_state),
+ VMSTATE_UINT32(ldoarst, ssys_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static int stellaris_sys_init(uint32_t base, qemu_irq irq,
stellaris_board_info * board,
uint8_t *macaddr)
@@ -676,7 +617,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(base, 0x00001000, iomemtype);
ssys_reset(s);
- register_savevm(NULL, "stellaris_sys", -1, 1, ssys_save, ssys_load, s);
+ vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
return 0;
}
@@ -844,36 +785,22 @@ static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
stellaris_i2c_write
};
-static void stellaris_i2c_save(QEMUFile *f, void *opaque)
-{
- stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
-
- qemu_put_be32(f, s->msa);
- qemu_put_be32(f, s->mcs);
- qemu_put_be32(f, s->mdr);
- qemu_put_be32(f, s->mtpr);
- qemu_put_be32(f, s->mimr);
- qemu_put_be32(f, s->mris);
- qemu_put_be32(f, s->mcr);
-}
-
-static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
-{
- stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->msa = qemu_get_be32(f);
- s->mcs = qemu_get_be32(f);
- s->mdr = qemu_get_be32(f);
- s->mtpr = qemu_get_be32(f);
- s->mimr = qemu_get_be32(f);
- s->mris = qemu_get_be32(f);
- s->mcr = qemu_get_be32(f);
-
- return 0;
-}
+static const VMStateDescription vmstate_stellaris_i2c = {
+ .name = "stellaris_i2c",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(msa, stellaris_i2c_state),
+ VMSTATE_UINT32(mcs, stellaris_i2c_state),
+ VMSTATE_UINT32(mdr, stellaris_i2c_state),
+ VMSTATE_UINT32(mtpr, stellaris_i2c_state),
+ VMSTATE_UINT32(mimr, stellaris_i2c_state),
+ VMSTATE_UINT32(mris, stellaris_i2c_state),
+ VMSTATE_UINT32(mcr, stellaris_i2c_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int stellaris_i2c_init(SysBusDevice * dev)
{
@@ -891,8 +818,7 @@ static int stellaris_i2c_init(SysBusDevice * dev)
sysbus_init_mmio(dev, 0x1000, iomemtype);
/* ??? For now we only implement the master interface. */
stellaris_i2c_reset(s);
- register_savevm(&dev->qdev, "stellaris_i2c", -1, 1,
- stellaris_i2c_save, stellaris_i2c_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
return 0;
}
@@ -1130,60 +1056,40 @@ static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
stellaris_adc_write
};
-static void stellaris_adc_save(QEMUFile *f, void *opaque)
-{
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
- int i;
- int j;
-
- qemu_put_be32(f, s->actss);
- qemu_put_be32(f, s->ris);
- qemu_put_be32(f, s->im);
- qemu_put_be32(f, s->emux);
- qemu_put_be32(f, s->ostat);
- qemu_put_be32(f, s->ustat);
- qemu_put_be32(f, s->sspri);
- qemu_put_be32(f, s->sac);
- for (i = 0; i < 4; i++) {
- qemu_put_be32(f, s->fifo[i].state);
- for (j = 0; j < 16; j++) {
- qemu_put_be32(f, s->fifo[i].data[j]);
- }
- qemu_put_be32(f, s->ssmux[i]);
- qemu_put_be32(f, s->ssctl[i]);
- }
- qemu_put_be32(f, s->noise);
-}
-
-static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
-{
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
- int i;
- int j;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->actss = qemu_get_be32(f);
- s->ris = qemu_get_be32(f);
- s->im = qemu_get_be32(f);
- s->emux = qemu_get_be32(f);
- s->ostat = qemu_get_be32(f);
- s->ustat = qemu_get_be32(f);
- s->sspri = qemu_get_be32(f);
- s->sac = qemu_get_be32(f);
- for (i = 0; i < 4; i++) {
- s->fifo[i].state = qemu_get_be32(f);
- for (j = 0; j < 16; j++) {
- s->fifo[i].data[j] = qemu_get_be32(f);
- }
- s->ssmux[i] = qemu_get_be32(f);
- s->ssctl[i] = qemu_get_be32(f);
+static const VMStateDescription vmstate_stellaris_adc = {
+ .name = "stellaris_adc",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(actss, stellaris_adc_state),
+ VMSTATE_UINT32(ris, stellaris_adc_state),
+ VMSTATE_UINT32(im, stellaris_adc_state),
+ VMSTATE_UINT32(emux, stellaris_adc_state),
+ VMSTATE_UINT32(ostat, stellaris_adc_state),
+ VMSTATE_UINT32(ustat, stellaris_adc_state),
+ VMSTATE_UINT32(sspri, stellaris_adc_state),
+ VMSTATE_UINT32(sac, stellaris_adc_state),
+ VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
+ VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
+ VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
+ VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
+ VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
+ VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
+ VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
+ VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
+ VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
+ VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
+ VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
+ VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
+ VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
+ VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
+ VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
+ VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
+ VMSTATE_UINT32(noise, stellaris_adc_state),
+ VMSTATE_END_OF_LIST()
}
- s->noise = qemu_get_be32(f);
-
- return 0;
-}
+};
static int stellaris_adc_init(SysBusDevice *dev)
{
@@ -1201,8 +1107,7 @@ static int stellaris_adc_init(SysBusDevice *dev)
sysbus_init_mmio(dev, 0x1000, iomemtype);
stellaris_adc_reset(s);
qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
- register_savevm(&dev->qdev, "stellaris_adc", -1, 1,
- stellaris_adc_save, stellaris_adc_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
return 0;
}
@@ -1234,24 +1139,16 @@ static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
return ssi_transfer(s->bus[s->current_dev], val);
}
-static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
-{
- stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
-
- qemu_put_be32(f, s->current_dev);
-}
-
-static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
-{
- stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->current_dev = qemu_get_be32(f);
-
- return 0;
-}
+static const VMStateDescription vmstate_stellaris_ssi_bus = {
+ .name = "stellaris_ssi_bus",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(current_dev, stellaris_ssi_bus_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int stellaris_ssi_bus_init(SSISlave *dev)
{
@@ -1261,8 +1158,7 @@ static int stellaris_ssi_bus_init(SSISlave *dev)
s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
- register_savevm(&dev->qdev, "stellaris_ssi_bus", -1, 1,
- stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
return 0;
}
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 16aae96f2..06c5f9d95 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -13,7 +13,7 @@
typedef struct {
qemu_irq irq;
int keycode;
- int pressed;
+ uint8_t pressed;
} gamepad_button;
typedef struct {
@@ -47,30 +47,29 @@ static void stellaris_gamepad_put_key(void * opaque, int keycode)
s->extension = 0;
}
-static void stellaris_gamepad_save(QEMUFile *f, void *opaque)
-{
- gamepad_state *s = (gamepad_state *)opaque;
- int i;
-
- qemu_put_be32(f, s->extension);
- for (i = 0; i < s->num_buttons; i++)
- qemu_put_byte(f, s->buttons[i].pressed);
-}
-
-static int stellaris_gamepad_load(QEMUFile *f, void *opaque, int version_id)
-{
- gamepad_state *s = (gamepad_state *)opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->extension = qemu_get_be32(f);
- for (i = 0; i < s->num_buttons; i++)
- s->buttons[i].pressed = qemu_get_byte(f);
+static const VMStateDescription vmstate_stellaris_button = {
+ .name = "stellaris_button",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(pressed, gamepad_button),
+ VMSTATE_END_OF_LIST()
+ }
+};
- return 0;
-}
+static const VMStateDescription vmstate_stellaris_gamepad = {
+ .name = "stellaris_gamepad",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(extension, gamepad_state),
+ VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0,
+ vmstate_stellaris_button, gamepad_button),
+ VMSTATE_END_OF_LIST()
+ }
+};
/* Returns an array 5 ouput slots. */
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
@@ -86,6 +85,5 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
}
s->num_buttons = n;
qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
- register_savevm(NULL, "stellaris_gamepad", -1, 1,
- stellaris_gamepad_save, stellaris_gamepad_load, s);
+ vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s);
}
diff --git a/hw/strongarm.c b/hw/strongarm.c
new file mode 100644
index 000000000..de08bdf67
--- /dev/null
+++ b/hw/strongarm.c
@@ -0,0 +1,1598 @@
+/*
+ * StrongARM SA-1100/SA-1110 emulation
+ *
+ * Copyright (C) 2011 Dmitry Eremin-Solenikov
+ *
+ * Largely based on StrongARM emulation:
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Written by Andrzej Zaborowski <balrog@zabor.org>
+ *
+ * UART code based on QEMU 16550A UART emulation
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2008 Citrix Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "sysbus.h"
+#include "strongarm.h"
+#include "qemu-error.h"
+#include "arm-misc.h"
+#include "sysemu.h"
+#include "ssi.h"
+
+//#define DEBUG
+
+/*
+ TODO
+ - Implement cp15, c14 ?
+ - Implement cp15, c15 !!! (idle used in L)
+ - Implement idle mode handling/DIM
+ - Implement sleep mode/Wake sources
+ - Implement reset control
+ - Implement memory control regs
+ - PCMCIA handling
+ - Maybe support MBGNT/MBREQ
+ - DMA channels
+ - GPCLK
+ - IrDA
+ - MCP
+ - Enhance UART with modem signals
+ */
+
+#ifdef DEBUG
+# define DPRINTF(format, ...) printf(format , ## __VA_ARGS__)
+#else
+# define DPRINTF(format, ...) do { } while (0)
+#endif
+
+static struct {
+ target_phys_addr_t io_base;
+ int irq;
+} sa_serial[] = {
+ { 0x80010000, SA_PIC_UART1 },
+ { 0x80030000, SA_PIC_UART2 },
+ { 0x80050000, SA_PIC_UART3 },
+ { 0, 0 }
+};
+
+/* Interrupt Controller */
+typedef struct {
+ SysBusDevice busdev;
+ qemu_irq irq;
+ qemu_irq fiq;
+
+ uint32_t pending;
+ uint32_t enabled;
+ uint32_t is_fiq;
+ uint32_t int_idle;
+} StrongARMPICState;
+
+#define ICIP 0x00
+#define ICMR 0x04
+#define ICLR 0x08
+#define ICFP 0x10
+#define ICPR 0x20
+#define ICCR 0x0c
+
+#define SA_PIC_SRCS 32
+
+
+static void strongarm_pic_update(void *opaque)
+{
+ StrongARMPICState *s = opaque;
+
+ /* FIXME: reflect DIM */
+ qemu_set_irq(s->fiq, s->pending & s->enabled & s->is_fiq);
+ qemu_set_irq(s->irq, s->pending & s->enabled & ~s->is_fiq);
+}
+
+static void strongarm_pic_set_irq(void *opaque, int irq, int level)
+{
+ StrongARMPICState *s = opaque;
+
+ if (level) {
+ s->pending |= 1 << irq;
+ } else {
+ s->pending &= ~(1 << irq);
+ }
+
+ strongarm_pic_update(s);
+}
+
+static uint32_t strongarm_pic_mem_read(void *opaque, target_phys_addr_t offset)
+{
+ StrongARMPICState *s = opaque;
+
+ switch (offset) {
+ case ICIP:
+ return s->pending & ~s->is_fiq & s->enabled;
+ case ICMR:
+ return s->enabled;
+ case ICLR:
+ return s->is_fiq;
+ case ICCR:
+ return s->int_idle == 0;
+ case ICFP:
+ return s->pending & s->is_fiq & s->enabled;
+ case ICPR:
+ return s->pending;
+ default:
+ printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
+ __func__, offset);
+ return 0;
+ }
+}
+
+static void strongarm_pic_mem_write(void *opaque, target_phys_addr_t offset,
+ uint32_t value)
+{
+ StrongARMPICState *s = opaque;
+
+ switch (offset) {
+ case ICMR:
+ s->enabled = value;
+ break;
+ case ICLR:
+ s->is_fiq = value;
+ break;
+ case ICCR:
+ s->int_idle = (value & 1) ? 0 : ~0;
+ break;
+ default:
+ printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
+ __func__, offset);
+ break;
+ }
+ strongarm_pic_update(s);
+}
+
+static CPUReadMemoryFunc * const strongarm_pic_readfn[] = {
+ strongarm_pic_mem_read,
+ strongarm_pic_mem_read,
+ strongarm_pic_mem_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_pic_writefn[] = {
+ strongarm_pic_mem_write,
+ strongarm_pic_mem_write,
+ strongarm_pic_mem_write,
+};
+
+static int strongarm_pic_initfn(SysBusDevice *dev)
+{
+ StrongARMPICState *s = FROM_SYSBUS(StrongARMPICState, dev);
+ int iomemtype;
+
+ qdev_init_gpio_in(&dev->qdev, strongarm_pic_set_irq, SA_PIC_SRCS);
+ iomemtype = cpu_register_io_memory(strongarm_pic_readfn,
+ strongarm_pic_writefn, s, DEVICE_NATIVE_ENDIAN);
+ sysbus_init_mmio(dev, 0x1000, iomemtype);
+ sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(dev, &s->fiq);
+
+ return 0;
+}
+
+static int strongarm_pic_post_load(void *opaque, int version_id)
+{
+ strongarm_pic_update(opaque);
+ return 0;
+}
+
+static VMStateDescription vmstate_strongarm_pic_regs = {
+ .name = "strongarm_pic",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = strongarm_pic_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(pending, StrongARMPICState),
+ VMSTATE_UINT32(enabled, StrongARMPICState),
+ VMSTATE_UINT32(is_fiq, StrongARMPICState),
+ VMSTATE_UINT32(int_idle, StrongARMPICState),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static SysBusDeviceInfo strongarm_pic_info = {
+ .init = strongarm_pic_initfn,
+ .qdev.name = "strongarm_pic",
+ .qdev.desc = "StrongARM PIC",
+ .qdev.size = sizeof(StrongARMPICState),
+ .qdev.vmsd = &vmstate_strongarm_pic_regs,
+};
+
+/* Real-Time Clock */
+#define RTAR 0x00 /* RTC Alarm register */
+#define RCNR 0x04 /* RTC Counter register */
+#define RTTR 0x08 /* RTC Timer Trim register */
+#define RTSR 0x10 /* RTC Status register */
+
+#define RTSR_AL (1 << 0) /* RTC Alarm detected */
+#define RTSR_HZ (1 << 1) /* RTC 1Hz detected */
+#define RTSR_ALE (1 << 2) /* RTC Alarm enable */
+#define RTSR_HZE (1 << 3) /* RTC 1Hz enable */
+
+/* 16 LSB of RTTR are clockdiv for internal trim logic,
+ * trim delete isn't emulated, so
+ * f = 32 768 / (RTTR_trim + 1) */
+
+typedef struct {
+ SysBusDevice busdev;
+ uint32_t rttr;
+ uint32_t rtsr;
+ uint32_t rtar;
+ uint32_t last_rcnr;
+ int64_t last_hz;
+ QEMUTimer *rtc_alarm;
+ QEMUTimer *rtc_hz;
+ qemu_irq rtc_irq;
+ qemu_irq rtc_hz_irq;
+} StrongARMRTCState;
+
+static inline void strongarm_rtc_int_update(StrongARMRTCState *s)
+{
+ qemu_set_irq(s->rtc_irq, s->rtsr & RTSR_AL);
+ qemu_set_irq(s->rtc_hz_irq, s->rtsr & RTSR_HZ);
+}
+
+static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
+{
+ int64_t rt = qemu_get_clock_ms(rt_clock);
+ s->last_rcnr += ((rt - s->last_hz) << 15) /
+ (1000 * ((s->rttr & 0xffff) + 1));
+ s->last_hz = rt;
+}
+
+static inline void strongarm_rtc_timer_update(StrongARMRTCState *s)
+{
+ if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) {
+ qemu_mod_timer(s->rtc_hz, s->last_hz + 1000);
+ } else {
+ qemu_del_timer(s->rtc_hz);
+ }
+
+ if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) {
+ qemu_mod_timer(s->rtc_alarm, s->last_hz +
+ (((s->rtar - s->last_rcnr) * 1000 *
+ ((s->rttr & 0xffff) + 1)) >> 15));
+ } else {
+ qemu_del_timer(s->rtc_alarm);
+ }
+}
+
+static inline void strongarm_rtc_alarm_tick(void *opaque)
+{
+ StrongARMRTCState *s = opaque;
+ s->rtsr |= RTSR_AL;
+ strongarm_rtc_timer_update(s);
+ strongarm_rtc_int_update(s);
+}
+
+static inline void strongarm_rtc_hz_tick(void *opaque)
+{
+ StrongARMRTCState *s = opaque;
+ s->rtsr |= RTSR_HZ;
+ strongarm_rtc_timer_update(s);
+ strongarm_rtc_int_update(s);
+}
+
+static uint32_t strongarm_rtc_read(void *opaque, target_phys_addr_t addr)
+{
+ StrongARMRTCState *s = opaque;
+
+ switch (addr) {
+ case RTTR:
+ return s->rttr;
+ case RTSR:
+ return s->rtsr;
+ case RTAR:
+ return s->rtar;
+ case RCNR:
+ return s->last_rcnr +
+ ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+ (1000 * ((s->rttr & 0xffff) + 1));
+ default:
+ printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+ return 0;
+ }
+}
+
+static void strongarm_rtc_write(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+ StrongARMRTCState *s = opaque;
+ uint32_t old_rtsr;
+
+ switch (addr) {
+ case RTTR:
+ strongarm_rtc_hzupdate(s);
+ s->rttr = value;
+ strongarm_rtc_timer_update(s);
+ break;
+
+ case RTSR:
+ old_rtsr = s->rtsr;
+ s->rtsr = (value & (RTSR_ALE | RTSR_HZE)) |
+ (s->rtsr & ~(value & (RTSR_AL | RTSR_HZ)));
+
+ if (s->rtsr != old_rtsr) {
+ strongarm_rtc_timer_update(s);
+ }
+
+ strongarm_rtc_int_update(s);
+ break;
+
+ case RTAR:
+ s->rtar = value;
+ strongarm_rtc_timer_update(s);
+ break;
+
+ case RCNR:
+ strongarm_rtc_hzupdate(s);
+ s->last_rcnr = value;
+ strongarm_rtc_timer_update(s);
+ break;
+
+ default:
+ printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+ }
+}
+
+static CPUReadMemoryFunc * const strongarm_rtc_readfn[] = {
+ strongarm_rtc_read,
+ strongarm_rtc_read,
+ strongarm_rtc_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_rtc_writefn[] = {
+ strongarm_rtc_write,
+ strongarm_rtc_write,
+ strongarm_rtc_write,
+};
+
+static int strongarm_rtc_init(SysBusDevice *dev)
+{
+ StrongARMRTCState *s = FROM_SYSBUS(StrongARMRTCState, dev);
+ struct tm tm;
+ int iomemtype;
+
+ s->rttr = 0x0;
+ s->rtsr = 0;
+
+ qemu_get_timedate(&tm, 0);
+
+ s->last_rcnr = (uint32_t) mktimegm(&tm);
+ s->last_hz = qemu_get_clock_ms(rt_clock);
+
+ s->rtc_alarm = qemu_new_timer_ms(rt_clock, strongarm_rtc_alarm_tick, s);
+ s->rtc_hz = qemu_new_timer_ms(rt_clock, strongarm_rtc_hz_tick, s);
+
+ sysbus_init_irq(dev, &s->rtc_irq);
+ sysbus_init_irq(dev, &s->rtc_hz_irq);
+
+ iomemtype = cpu_register_io_memory(strongarm_rtc_readfn,
+ strongarm_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);
+ sysbus_init_mmio(dev, 0x10000, iomemtype);
+
+ return 0;
+}
+
+static void strongarm_rtc_pre_save(void *opaque)
+{
+ StrongARMRTCState *s = opaque;
+
+ strongarm_rtc_hzupdate(s);
+}
+
+static int strongarm_rtc_post_load(void *opaque, int version_id)
+{
+ StrongARMRTCState *s = opaque;
+
+ strongarm_rtc_timer_update(s);
+ strongarm_rtc_int_update(s);
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_rtc_regs = {
+ .name = "strongarm-rtc",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .pre_save = strongarm_rtc_pre_save,
+ .post_load = strongarm_rtc_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(rttr, StrongARMRTCState),
+ VMSTATE_UINT32(rtsr, StrongARMRTCState),
+ VMSTATE_UINT32(rtar, StrongARMRTCState),
+ VMSTATE_UINT32(last_rcnr, StrongARMRTCState),
+ VMSTATE_INT64(last_hz, StrongARMRTCState),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static SysBusDeviceInfo strongarm_rtc_sysbus_info = {
+ .init = strongarm_rtc_init,
+ .qdev.name = "strongarm-rtc",
+ .qdev.desc = "StrongARM RTC Controller",
+ .qdev.size = sizeof(StrongARMRTCState),
+ .qdev.vmsd = &vmstate_strongarm_rtc_regs,
+};
+
+/* GPIO */
+#define GPLR 0x00
+#define GPDR 0x04
+#define GPSR 0x08
+#define GPCR 0x0c
+#define GRER 0x10
+#define GFER 0x14
+#define GEDR 0x18
+#define GAFR 0x1c
+
+typedef struct StrongARMGPIOInfo StrongARMGPIOInfo;
+struct StrongARMGPIOInfo {
+ SysBusDevice busdev;
+ qemu_irq handler[28];
+ qemu_irq irqs[11];
+ qemu_irq irqX;
+
+ uint32_t ilevel;
+ uint32_t olevel;
+ uint32_t dir;
+ uint32_t rising;
+ uint32_t falling;
+ uint32_t status;
+ uint32_t gpsr;
+ uint32_t gafr;
+
+ uint32_t prev_level;
+};
+
+
+static void strongarm_gpio_irq_update(StrongARMGPIOInfo *s)
+{
+ int i;
+ for (i = 0; i < 11; i++) {
+ qemu_set_irq(s->irqs[i], s->status & (1 << i));
+ }
+
+ qemu_set_irq(s->irqX, (s->status & ~0x7ff));
+}
+
+static void strongarm_gpio_set(void *opaque, int line, int level)
+{
+ StrongARMGPIOInfo *s = opaque;
+ uint32_t mask;
+
+ mask = 1 << line;
+
+ if (level) {
+ s->status |= s->rising & mask &
+ ~s->ilevel & ~s->dir;
+ s->ilevel |= mask;
+ } else {
+ s->status |= s->falling & mask &
+ s->ilevel & ~s->dir;
+ s->ilevel &= ~mask;
+ }
+
+ if (s->status & mask) {
+ strongarm_gpio_irq_update(s);
+ }
+}
+
+static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s)
+{
+ uint32_t level, diff;
+ int bit;
+
+ level = s->olevel & s->dir;
+
+ for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
+ bit = ffs(diff) - 1;
+ qemu_set_irq(s->handler[bit], (level >> bit) & 1);
+ }
+
+ s->prev_level = level;
+}
+
+static uint32_t strongarm_gpio_read(void *opaque, target_phys_addr_t offset)
+{
+ StrongARMGPIOInfo *s = opaque;
+
+ switch (offset) {
+ case GPDR: /* GPIO Pin-Direction registers */
+ return s->dir;
+
+ case GPSR: /* GPIO Pin-Output Set registers */
+ DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
+ __func__, offset);
+ return s->gpsr; /* Return last written value. */
+
+ case GPCR: /* GPIO Pin-Output Clear registers */
+ DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
+ __func__, offset);
+ return 31337; /* Specified as unpredictable in the docs. */
+
+ case GRER: /* GPIO Rising-Edge Detect Enable registers */
+ return s->rising;
+
+ case GFER: /* GPIO Falling-Edge Detect Enable registers */
+ return s->falling;
+
+ case GAFR: /* GPIO Alternate Function registers */
+ return s->gafr;
+
+ case GPLR: /* GPIO Pin-Level registers */
+ return (s->olevel & s->dir) |
+ (s->ilevel & ~s->dir);
+
+ case GEDR: /* GPIO Edge Detect Status registers */
+ return s->status;
+
+ default:
+ printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+ }
+
+ return 0;
+}
+
+static void strongarm_gpio_write(void *opaque,
+ target_phys_addr_t offset, uint32_t value)
+{
+ StrongARMGPIOInfo *s = opaque;
+
+ switch (offset) {
+ case GPDR: /* GPIO Pin-Direction registers */
+ s->dir = value;
+ strongarm_gpio_handler_update(s);
+ break;
+
+ case GPSR: /* GPIO Pin-Output Set registers */
+ s->olevel |= value;
+ strongarm_gpio_handler_update(s);
+ s->gpsr = value;
+ break;
+
+ case GPCR: /* GPIO Pin-Output Clear registers */
+ s->olevel &= ~value;
+ strongarm_gpio_handler_update(s);
+ break;
+
+ case GRER: /* GPIO Rising-Edge Detect Enable registers */
+ s->rising = value;
+ break;
+
+ case GFER: /* GPIO Falling-Edge Detect Enable registers */
+ s->falling = value;
+ break;
+
+ case GAFR: /* GPIO Alternate Function registers */
+ s->gafr = value;
+ break;
+
+ case GEDR: /* GPIO Edge Detect Status registers */
+ s->status &= ~value;
+ strongarm_gpio_irq_update(s);
+ break;
+
+ default:
+ printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+ }
+}
+
+static CPUReadMemoryFunc * const strongarm_gpio_readfn[] = {
+ strongarm_gpio_read,
+ strongarm_gpio_read,
+ strongarm_gpio_read
+};
+
+static CPUWriteMemoryFunc * const strongarm_gpio_writefn[] = {
+ strongarm_gpio_write,
+ strongarm_gpio_write,
+ strongarm_gpio_write
+};
+
+static DeviceState *strongarm_gpio_init(target_phys_addr_t base,
+ DeviceState *pic)
+{
+ DeviceState *dev;
+ int i;
+
+ dev = qdev_create(NULL, "strongarm-gpio");
+ qdev_init_nofail(dev);
+
+ sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+ for (i = 0; i < 12; i++)
+ sysbus_connect_irq(sysbus_from_qdev(dev), i,
+ qdev_get_gpio_in(pic, SA_PIC_GPIO0_EDGE + i));
+
+ return dev;
+}
+
+static int strongarm_gpio_initfn(SysBusDevice *dev)
+{
+ int iomemtype;
+ StrongARMGPIOInfo *s;
+ int i;
+
+ s = FROM_SYSBUS(StrongARMGPIOInfo, dev);
+
+ qdev_init_gpio_in(&dev->qdev, strongarm_gpio_set, 28);
+ qdev_init_gpio_out(&dev->qdev, s->handler, 28);
+
+ iomemtype = cpu_register_io_memory(strongarm_gpio_readfn,
+ strongarm_gpio_writefn, s, DEVICE_NATIVE_ENDIAN);
+
+ sysbus_init_mmio(dev, 0x1000, iomemtype);
+ for (i = 0; i < 11; i++) {
+ sysbus_init_irq(dev, &s->irqs[i]);
+ }
+ sysbus_init_irq(dev, &s->irqX);
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_gpio_regs = {
+ .name = "strongarm-gpio",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(ilevel, StrongARMGPIOInfo),
+ VMSTATE_UINT32(olevel, StrongARMGPIOInfo),
+ VMSTATE_UINT32(dir, StrongARMGPIOInfo),
+ VMSTATE_UINT32(rising, StrongARMGPIOInfo),
+ VMSTATE_UINT32(falling, StrongARMGPIOInfo),
+ VMSTATE_UINT32(status, StrongARMGPIOInfo),
+ VMSTATE_UINT32(gafr, StrongARMGPIOInfo),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static SysBusDeviceInfo strongarm_gpio_info = {
+ .init = strongarm_gpio_initfn,
+ .qdev.name = "strongarm-gpio",
+ .qdev.desc = "StrongARM GPIO controller",
+ .qdev.size = sizeof(StrongARMGPIOInfo),
+};
+
+/* Peripheral Pin Controller */
+#define PPDR 0x00
+#define PPSR 0x04
+#define PPAR 0x08
+#define PSDR 0x0c
+#define PPFR 0x10
+
+typedef struct StrongARMPPCInfo StrongARMPPCInfo;
+struct StrongARMPPCInfo {
+ SysBusDevice busdev;
+ qemu_irq handler[28];
+
+ uint32_t ilevel;
+ uint32_t olevel;
+ uint32_t dir;
+ uint32_t ppar;
+ uint32_t psdr;
+ uint32_t ppfr;
+
+ uint32_t prev_level;
+};
+
+static void strongarm_ppc_set(void *opaque, int line, int level)
+{
+ StrongARMPPCInfo *s = opaque;
+
+ if (level) {
+ s->ilevel |= 1 << line;
+ } else {
+ s->ilevel &= ~(1 << line);
+ }
+}
+
+static void strongarm_ppc_handler_update(StrongARMPPCInfo *s)
+{
+ uint32_t level, diff;
+ int bit;
+
+ level = s->olevel & s->dir;
+
+ for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
+ bit = ffs(diff) - 1;
+ qemu_set_irq(s->handler[bit], (level >> bit) & 1);
+ }
+
+ s->prev_level = level;
+}
+
+static uint32_t strongarm_ppc_read(void *opaque, target_phys_addr_t offset)
+{
+ StrongARMPPCInfo *s = opaque;
+
+ switch (offset) {
+ case PPDR: /* PPC Pin Direction registers */
+ return s->dir | ~0x3fffff;
+
+ case PPSR: /* PPC Pin State registers */
+ return (s->olevel & s->dir) |
+ (s->ilevel & ~s->dir) |
+ ~0x3fffff;
+
+ case PPAR:
+ return s->ppar | ~0x41000;
+
+ case PSDR:
+ return s->psdr;
+
+ case PPFR:
+ return s->ppfr | ~0x7f001;
+
+ default:
+ printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+ }
+
+ return 0;
+}
+
+static void strongarm_ppc_write(void *opaque,
+ target_phys_addr_t offset, uint32_t value)
+{
+ StrongARMPPCInfo *s = opaque;
+
+ switch (offset) {
+ case PPDR: /* PPC Pin Direction registers */
+ s->dir = value & 0x3fffff;
+ strongarm_ppc_handler_update(s);
+ break;
+
+ case PPSR: /* PPC Pin State registers */
+ s->olevel = value & s->dir & 0x3fffff;
+ strongarm_ppc_handler_update(s);
+ break;
+
+ case PPAR:
+ s->ppar = value & 0x41000;
+ break;
+
+ case PSDR:
+ s->psdr = value & 0x3fffff;
+ break;
+
+ case PPFR:
+ s->ppfr = value & 0x7f001;
+ break;
+
+ default:
+ printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+ }
+}
+
+static CPUReadMemoryFunc * const strongarm_ppc_readfn[] = {
+ strongarm_ppc_read,
+ strongarm_ppc_read,
+ strongarm_ppc_read
+};
+
+static CPUWriteMemoryFunc * const strongarm_ppc_writefn[] = {
+ strongarm_ppc_write,
+ strongarm_ppc_write,
+ strongarm_ppc_write
+};
+
+static int strongarm_ppc_init(SysBusDevice *dev)
+{
+ int iomemtype;
+ StrongARMPPCInfo *s;
+
+ s = FROM_SYSBUS(StrongARMPPCInfo, dev);
+
+ qdev_init_gpio_in(&dev->qdev, strongarm_ppc_set, 22);
+ qdev_init_gpio_out(&dev->qdev, s->handler, 22);
+
+ iomemtype = cpu_register_io_memory(strongarm_ppc_readfn,
+ strongarm_ppc_writefn, s, DEVICE_NATIVE_ENDIAN);
+
+ sysbus_init_mmio(dev, 0x1000, iomemtype);
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_ppc_regs = {
+ .name = "strongarm-ppc",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(ilevel, StrongARMPPCInfo),
+ VMSTATE_UINT32(olevel, StrongARMPPCInfo),
+ VMSTATE_UINT32(dir, StrongARMPPCInfo),
+ VMSTATE_UINT32(ppar, StrongARMPPCInfo),
+ VMSTATE_UINT32(psdr, StrongARMPPCInfo),
+ VMSTATE_UINT32(ppfr, StrongARMPPCInfo),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static SysBusDeviceInfo strongarm_ppc_info = {
+ .init = strongarm_ppc_init,
+ .qdev.name = "strongarm-ppc",
+ .qdev.desc = "StrongARM PPC controller",
+ .qdev.size = sizeof(StrongARMPPCInfo),
+};
+
+/* UART Ports */
+#define UTCR0 0x00
+#define UTCR1 0x04
+#define UTCR2 0x08
+#define UTCR3 0x0c
+#define UTDR 0x14
+#define UTSR0 0x1c
+#define UTSR1 0x20
+
+#define UTCR0_PE (1 << 0) /* Parity enable */
+#define UTCR0_OES (1 << 1) /* Even parity */
+#define UTCR0_SBS (1 << 2) /* 2 stop bits */
+#define UTCR0_DSS (1 << 3) /* 8-bit data */
+
+#define UTCR3_RXE (1 << 0) /* Rx enable */
+#define UTCR3_TXE (1 << 1) /* Tx enable */
+#define UTCR3_BRK (1 << 2) /* Force Break */
+#define UTCR3_RIE (1 << 3) /* Rx int enable */
+#define UTCR3_TIE (1 << 4) /* Tx int enable */
+#define UTCR3_LBM (1 << 5) /* Loopback */
+
+#define UTSR0_TFS (1 << 0) /* Tx FIFO nearly empty */
+#define UTSR0_RFS (1 << 1) /* Rx FIFO nearly full */
+#define UTSR0_RID (1 << 2) /* Receiver Idle */
+#define UTSR0_RBB (1 << 3) /* Receiver begin break */
+#define UTSR0_REB (1 << 4) /* Receiver end break */
+#define UTSR0_EIF (1 << 5) /* Error in FIFO */
+
+#define UTSR1_RNE (1 << 1) /* Receive FIFO not empty */
+#define UTSR1_TNF (1 << 2) /* Transmit FIFO not full */
+#define UTSR1_PRE (1 << 3) /* Parity error */
+#define UTSR1_FRE (1 << 4) /* Frame error */
+#define UTSR1_ROR (1 << 5) /* Receive Over Run */
+
+#define RX_FIFO_PRE (1 << 8)
+#define RX_FIFO_FRE (1 << 9)
+#define RX_FIFO_ROR (1 << 10)
+
+typedef struct {
+ SysBusDevice busdev;
+ CharDriverState *chr;
+ qemu_irq irq;
+
+ uint8_t utcr0;
+ uint16_t brd;
+ uint8_t utcr3;
+ uint8_t utsr0;
+ uint8_t utsr1;
+
+ uint8_t tx_fifo[8];
+ uint8_t tx_start;
+ uint8_t tx_len;
+ uint16_t rx_fifo[12]; /* value + error flags in high bits */
+ uint8_t rx_start;
+ uint8_t rx_len;
+
+ uint64_t char_transmit_time; /* time to transmit a char in ticks*/
+ bool wait_break_end;
+ QEMUTimer *rx_timeout_timer;
+ QEMUTimer *tx_timer;
+} StrongARMUARTState;
+
+static void strongarm_uart_update_status(StrongARMUARTState *s)
+{
+ uint16_t utsr1 = 0;
+
+ if (s->tx_len != 8) {
+ utsr1 |= UTSR1_TNF;
+ }
+
+ if (s->rx_len != 0) {
+ uint16_t ent = s->rx_fifo[s->rx_start];
+
+ utsr1 |= UTSR1_RNE;
+ if (ent & RX_FIFO_PRE) {
+ s->utsr1 |= UTSR1_PRE;
+ }
+ if (ent & RX_FIFO_FRE) {
+ s->utsr1 |= UTSR1_FRE;
+ }
+ if (ent & RX_FIFO_ROR) {
+ s->utsr1 |= UTSR1_ROR;
+ }
+ }
+
+ s->utsr1 = utsr1;
+}
+
+static void strongarm_uart_update_int_status(StrongARMUARTState *s)
+{
+ uint16_t utsr0 = s->utsr0 &
+ (UTSR0_REB | UTSR0_RBB | UTSR0_RID);
+ int i;
+
+ if ((s->utcr3 & UTCR3_TXE) &&
+ (s->utcr3 & UTCR3_TIE) &&
+ s->tx_len <= 4) {
+ utsr0 |= UTSR0_TFS;
+ }
+
+ if ((s->utcr3 & UTCR3_RXE) &&
+ (s->utcr3 & UTCR3_RIE) &&
+ s->rx_len > 4) {
+ utsr0 |= UTSR0_RFS;
+ }
+
+ for (i = 0; i < s->rx_len && i < 4; i++)
+ if (s->rx_fifo[(s->rx_start + i) % 12] & ~0xff) {
+ utsr0 |= UTSR0_EIF;
+ break;
+ }
+
+ s->utsr0 = utsr0;
+ qemu_set_irq(s->irq, utsr0);
+}
+
+static void strongarm_uart_update_parameters(StrongARMUARTState *s)
+{
+ int speed, parity, data_bits, stop_bits, frame_size;
+ QEMUSerialSetParams ssp;
+
+ /* Start bit. */
+ frame_size = 1;
+ if (s->utcr0 & UTCR0_PE) {
+ /* Parity bit. */
+ frame_size++;
+ if (s->utcr0 & UTCR0_OES) {
+ parity = 'E';
+ } else {
+ parity = 'O';
+ }
+ } else {
+ parity = 'N';
+ }
+ if (s->utcr0 & UTCR0_SBS) {
+ stop_bits = 2;
+ } else {
+ stop_bits = 1;
+ }
+
+ data_bits = (s->utcr0 & UTCR0_DSS) ? 8 : 7;
+ frame_size += data_bits + stop_bits;
+ speed = 3686400 / 16 / (s->brd + 1);
+ ssp.speed = speed;
+ ssp.parity = parity;
+ ssp.data_bits = data_bits;
+ ssp.stop_bits = stop_bits;
+ s->char_transmit_time = (get_ticks_per_sec() / speed) * frame_size;
+ if (s->chr) {
+ qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+ }
+
+ DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
+ speed, parity, data_bits, stop_bits);
+}
+
+static void strongarm_uart_rx_to(void *opaque)
+{
+ StrongARMUARTState *s = opaque;
+
+ if (s->rx_len) {
+ s->utsr0 |= UTSR0_RID;
+ strongarm_uart_update_int_status(s);
+ }
+}
+
+static void strongarm_uart_rx_push(StrongARMUARTState *s, uint16_t c)
+{
+ if ((s->utcr3 & UTCR3_RXE) == 0) {
+ /* rx disabled */
+ return;
+ }
+
+ if (s->wait_break_end) {
+ s->utsr0 |= UTSR0_REB;
+ s->wait_break_end = false;
+ }
+
+ if (s->rx_len < 12) {
+ s->rx_fifo[(s->rx_start + s->rx_len) % 12] = c;
+ s->rx_len++;
+ } else
+ s->rx_fifo[(s->rx_start + 11) % 12] |= RX_FIFO_ROR;
+}
+
+static int strongarm_uart_can_receive(void *opaque)
+{
+ StrongARMUARTState *s = opaque;
+
+ if (s->rx_len == 12) {
+ return 0;
+ }
+ /* It's best not to get more than 2/3 of RX FIFO, so advertise that much */
+ if (s->rx_len < 8) {
+ return 8 - s->rx_len;
+ }
+ return 1;
+}
+
+static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size)
+{
+ StrongARMUARTState *s = opaque;
+ int i;
+
+ for (i = 0; i < size; i++) {
+ strongarm_uart_rx_push(s, buf[i]);
+ }
+
+ /* call the timeout receive callback in 3 char transmit time */
+ qemu_mod_timer(s->rx_timeout_timer,
+ qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+}
+
+static void strongarm_uart_event(void *opaque, int event)
+{
+ StrongARMUARTState *s = opaque;
+ if (event == CHR_EVENT_BREAK) {
+ s->utsr0 |= UTSR0_RBB;
+ strongarm_uart_rx_push(s, RX_FIFO_FRE);
+ s->wait_break_end = true;
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+ }
+}
+
+static void strongarm_uart_tx(void *opaque)
+{
+ StrongARMUARTState *s = opaque;
+ uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock);
+
+ if (s->utcr3 & UTCR3_LBM) /* loopback */ {
+ strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
+ } else if (s->chr) {
+ qemu_chr_write(s->chr, &s->tx_fifo[s->tx_start], 1);
+ }
+
+ s->tx_start = (s->tx_start + 1) % 8;
+ s->tx_len--;
+ if (s->tx_len) {
+ qemu_mod_timer(s->tx_timer, new_xmit_ts + s->char_transmit_time);
+ }
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+}
+
+static uint32_t strongarm_uart_read(void *opaque, target_phys_addr_t addr)
+{
+ StrongARMUARTState *s = opaque;
+ uint16_t ret;
+
+ switch (addr) {
+ case UTCR0:
+ return s->utcr0;
+
+ case UTCR1:
+ return s->brd >> 8;
+
+ case UTCR2:
+ return s->brd & 0xff;
+
+ case UTCR3:
+ return s->utcr3;
+
+ case UTDR:
+ if (s->rx_len != 0) {
+ ret = s->rx_fifo[s->rx_start];
+ s->rx_start = (s->rx_start + 1) % 12;
+ s->rx_len--;
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+ return ret;
+ }
+ return 0;
+
+ case UTSR0:
+ return s->utsr0;
+
+ case UTSR1:
+ return s->utsr1;
+
+ default:
+ printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+ return 0;
+ }
+}
+
+static void strongarm_uart_write(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+ StrongARMUARTState *s = opaque;
+
+ switch (addr) {
+ case UTCR0:
+ s->utcr0 = value & 0x7f;
+ strongarm_uart_update_parameters(s);
+ break;
+
+ case UTCR1:
+ s->brd = (s->brd & 0xff) | ((value & 0xf) << 8);
+ strongarm_uart_update_parameters(s);
+ break;
+
+ case UTCR2:
+ s->brd = (s->brd & 0xf00) | (value & 0xff);
+ strongarm_uart_update_parameters(s);
+ break;
+
+ case UTCR3:
+ s->utcr3 = value & 0x3f;
+ if ((s->utcr3 & UTCR3_RXE) == 0) {
+ s->rx_len = 0;
+ }
+ if ((s->utcr3 & UTCR3_TXE) == 0) {
+ s->tx_len = 0;
+ }
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+ break;
+
+ case UTDR:
+ if ((s->utcr3 & UTCR3_TXE) && s->tx_len != 8) {
+ s->tx_fifo[(s->tx_start + s->tx_len) % 8] = value;
+ s->tx_len++;
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+ if (s->tx_len == 1) {
+ strongarm_uart_tx(s);
+ }
+ }
+ break;
+
+ case UTSR0:
+ s->utsr0 = s->utsr0 & ~(value &
+ (UTSR0_REB | UTSR0_RBB | UTSR0_RID));
+ strongarm_uart_update_int_status(s);
+ break;
+
+ default:
+ printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+ }
+}
+
+static CPUReadMemoryFunc * const strongarm_uart_readfn[] = {
+ strongarm_uart_read,
+ strongarm_uart_read,
+ strongarm_uart_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_uart_writefn[] = {
+ strongarm_uart_write,
+ strongarm_uart_write,
+ strongarm_uart_write,
+};
+
+static int strongarm_uart_init(SysBusDevice *dev)
+{
+ StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev);
+ int iomemtype;
+
+ iomemtype = cpu_register_io_memory(strongarm_uart_readfn,
+ strongarm_uart_writefn, s, DEVICE_NATIVE_ENDIAN);
+ sysbus_init_mmio(dev, 0x10000, iomemtype);
+ sysbus_init_irq(dev, &s->irq);
+
+ s->rx_timeout_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_rx_to, s);
+ s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
+
+ if (s->chr) {
+ qemu_chr_add_handlers(s->chr,
+ strongarm_uart_can_receive,
+ strongarm_uart_receive,
+ strongarm_uart_event,
+ s);
+ }
+
+ return 0;
+}
+
+static void strongarm_uart_reset(DeviceState *dev)
+{
+ StrongARMUARTState *s = DO_UPCAST(StrongARMUARTState, busdev.qdev, dev);
+
+ s->utcr0 = UTCR0_DSS; /* 8 data, no parity */
+ s->brd = 23; /* 9600 */
+ /* enable send & recv - this actually violates spec */
+ s->utcr3 = UTCR3_TXE | UTCR3_RXE;
+
+ s->rx_len = s->tx_len = 0;
+
+ strongarm_uart_update_parameters(s);
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+}
+
+static int strongarm_uart_post_load(void *opaque, int version_id)
+{
+ StrongARMUARTState *s = opaque;
+
+ strongarm_uart_update_parameters(s);
+ strongarm_uart_update_status(s);
+ strongarm_uart_update_int_status(s);
+
+ /* tx and restart timer */
+ if (s->tx_len) {
+ strongarm_uart_tx(s);
+ }
+
+ /* restart rx timeout timer */
+ if (s->rx_len) {
+ qemu_mod_timer(s->rx_timeout_timer,
+ qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+ }
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_uart_regs = {
+ .name = "strongarm-uart",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = strongarm_uart_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(utcr0, StrongARMUARTState),
+ VMSTATE_UINT16(brd, StrongARMUARTState),
+ VMSTATE_UINT8(utcr3, StrongARMUARTState),
+ VMSTATE_UINT8(utsr0, StrongARMUARTState),
+ VMSTATE_UINT8_ARRAY(tx_fifo, StrongARMUARTState, 8),
+ VMSTATE_UINT8(tx_start, StrongARMUARTState),
+ VMSTATE_UINT8(tx_len, StrongARMUARTState),
+ VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMUARTState, 12),
+ VMSTATE_UINT8(rx_start, StrongARMUARTState),
+ VMSTATE_UINT8(rx_len, StrongARMUARTState),
+ VMSTATE_BOOL(wait_break_end, StrongARMUARTState),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static SysBusDeviceInfo strongarm_uart_info = {
+ .init = strongarm_uart_init,
+ .qdev.name = "strongarm-uart",
+ .qdev.desc = "StrongARM UART controller",
+ .qdev.size = sizeof(StrongARMUARTState),
+ .qdev.reset = strongarm_uart_reset,
+ .qdev.vmsd = &vmstate_strongarm_uart_regs,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr),
+ DEFINE_PROP_END_OF_LIST(),
+ }
+};
+
+/* Synchronous Serial Ports */
+typedef struct {
+ SysBusDevice busdev;
+ qemu_irq irq;
+ SSIBus *bus;
+
+ uint16_t sscr[2];
+ uint16_t sssr;
+
+ uint16_t rx_fifo[8];
+ uint8_t rx_level;
+ uint8_t rx_start;
+} StrongARMSSPState;
+
+#define SSCR0 0x60 /* SSP Control register 0 */
+#define SSCR1 0x64 /* SSP Control register 1 */
+#define SSDR 0x6c /* SSP Data register */
+#define SSSR 0x74 /* SSP Status register */
+
+/* Bitfields for above registers */
+#define SSCR0_SPI(x) (((x) & 0x30) == 0x00)
+#define SSCR0_SSP(x) (((x) & 0x30) == 0x10)
+#define SSCR0_UWIRE(x) (((x) & 0x30) == 0x20)
+#define SSCR0_PSP(x) (((x) & 0x30) == 0x30)
+#define SSCR0_SSE (1 << 7)
+#define SSCR0_DSS(x) (((x) & 0xf) + 1)
+#define SSCR1_RIE (1 << 0)
+#define SSCR1_TIE (1 << 1)
+#define SSCR1_LBM (1 << 2)
+#define SSSR_TNF (1 << 2)
+#define SSSR_RNE (1 << 3)
+#define SSSR_TFS (1 << 5)
+#define SSSR_RFS (1 << 6)
+#define SSSR_ROR (1 << 7)
+#define SSSR_RW 0x0080
+
+static void strongarm_ssp_int_update(StrongARMSSPState *s)
+{
+ int level = 0;
+
+ level |= (s->sssr & SSSR_ROR);
+ level |= (s->sssr & SSSR_RFS) && (s->sscr[1] & SSCR1_RIE);
+ level |= (s->sssr & SSSR_TFS) && (s->sscr[1] & SSCR1_TIE);
+ qemu_set_irq(s->irq, level);
+}
+
+static void strongarm_ssp_fifo_update(StrongARMSSPState *s)
+{
+ s->sssr &= ~SSSR_TFS;
+ s->sssr &= ~SSSR_TNF;
+ if (s->sscr[0] & SSCR0_SSE) {
+ if (s->rx_level >= 4) {
+ s->sssr |= SSSR_RFS;
+ } else {
+ s->sssr &= ~SSSR_RFS;
+ }
+ if (s->rx_level) {
+ s->sssr |= SSSR_RNE;
+ } else {
+ s->sssr &= ~SSSR_RNE;
+ }
+ /* TX FIFO is never filled, so it is always in underrun
+ condition if SSP is enabled */
+ s->sssr |= SSSR_TFS;
+ s->sssr |= SSSR_TNF;
+ }
+
+ strongarm_ssp_int_update(s);
+}
+
+static uint32_t strongarm_ssp_read(void *opaque, target_phys_addr_t addr)
+{
+ StrongARMSSPState *s = opaque;
+ uint32_t retval;
+
+ switch (addr) {
+ case SSCR0:
+ return s->sscr[0];
+ case SSCR1:
+ return s->sscr[1];
+ case SSSR:
+ return s->sssr;
+ case SSDR:
+ if (~s->sscr[0] & SSCR0_SSE) {
+ return 0xffffffff;
+ }
+ if (s->rx_level < 1) {
+ printf("%s: SSP Rx Underrun\n", __func__);
+ return 0xffffffff;
+ }
+ s->rx_level--;
+ retval = s->rx_fifo[s->rx_start++];
+ s->rx_start &= 0x7;
+ strongarm_ssp_fifo_update(s);
+ return retval;
+ default:
+ printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+ break;
+ }
+ return 0;
+}
+
+static void strongarm_ssp_write(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+ StrongARMSSPState *s = opaque;
+
+ switch (addr) {
+ case SSCR0:
+ s->sscr[0] = value & 0xffbf;
+ if ((s->sscr[0] & SSCR0_SSE) && SSCR0_DSS(value) < 4) {
+ printf("%s: Wrong data size: %i bits\n", __func__,
+ SSCR0_DSS(value));
+ }
+ if (!(value & SSCR0_SSE)) {
+ s->sssr = 0;
+ s->rx_level = 0;
+ }
+ strongarm_ssp_fifo_update(s);
+ break;
+
+ case SSCR1:
+ s->sscr[1] = value & 0x2f;
+ if (value & SSCR1_LBM) {
+ printf("%s: Attempt to use SSP LBM mode\n", __func__);
+ }
+ strongarm_ssp_fifo_update(s);
+ break;
+
+ case SSSR:
+ s->sssr &= ~(value & SSSR_RW);
+ strongarm_ssp_int_update(s);
+ break;
+
+ case SSDR:
+ if (SSCR0_UWIRE(s->sscr[0])) {
+ value &= 0xff;
+ } else
+ /* Note how 32bits overflow does no harm here */
+ value &= (1 << SSCR0_DSS(s->sscr[0])) - 1;
+
+ /* Data goes from here to the Tx FIFO and is shifted out from
+ * there directly to the slave, no need to buffer it.
+ */
+ if (s->sscr[0] & SSCR0_SSE) {
+ uint32_t readval;
+ if (s->sscr[1] & SSCR1_LBM) {
+ readval = value;
+ } else {
+ readval = ssi_transfer(s->bus, value);
+ }
+
+ if (s->rx_level < 0x08) {
+ s->rx_fifo[(s->rx_start + s->rx_level++) & 0x7] = readval;
+ } else {
+ s->sssr |= SSSR_ROR;
+ }
+ }
+ strongarm_ssp_fifo_update(s);
+ break;
+
+ default:
+ printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+ break;
+ }
+}
+
+static CPUReadMemoryFunc * const strongarm_ssp_readfn[] = {
+ strongarm_ssp_read,
+ strongarm_ssp_read,
+ strongarm_ssp_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_ssp_writefn[] = {
+ strongarm_ssp_write,
+ strongarm_ssp_write,
+ strongarm_ssp_write,
+};
+
+static int strongarm_ssp_post_load(void *opaque, int version_id)
+{
+ StrongARMSSPState *s = opaque;
+
+ strongarm_ssp_fifo_update(s);
+
+ return 0;
+}
+
+static int strongarm_ssp_init(SysBusDevice *dev)
+{
+ int iomemtype;
+ StrongARMSSPState *s = FROM_SYSBUS(StrongARMSSPState, dev);
+
+ sysbus_init_irq(dev, &s->irq);
+
+ iomemtype = cpu_register_io_memory(strongarm_ssp_readfn,
+ strongarm_ssp_writefn, s,
+ DEVICE_NATIVE_ENDIAN);
+ sysbus_init_mmio(dev, 0x1000, iomemtype);
+
+ s->bus = ssi_create_bus(&dev->qdev, "ssi");
+ return 0;
+}
+
+static void strongarm_ssp_reset(DeviceState *dev)
+{
+ StrongARMSSPState *s = DO_UPCAST(StrongARMSSPState, busdev.qdev, dev);
+ s->sssr = 0x03; /* 3 bit data, SPI, disabled */
+ s->rx_start = 0;
+ s->rx_level = 0;
+}
+
+static const VMStateDescription vmstate_strongarm_ssp_regs = {
+ .name = "strongarm-ssp",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = strongarm_ssp_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT16_ARRAY(sscr, StrongARMSSPState, 2),
+ VMSTATE_UINT16(sssr, StrongARMSSPState),
+ VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMSSPState, 8),
+ VMSTATE_UINT8(rx_start, StrongARMSSPState),
+ VMSTATE_UINT8(rx_level, StrongARMSSPState),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static SysBusDeviceInfo strongarm_ssp_info = {
+ .init = strongarm_ssp_init,
+ .qdev.name = "strongarm-ssp",
+ .qdev.desc = "StrongARM SSP controller",
+ .qdev.size = sizeof(StrongARMSSPState),
+ .qdev.reset = strongarm_ssp_reset,
+ .qdev.vmsd = &vmstate_strongarm_ssp_regs,
+};
+
+/* Main CPU functions */
+StrongARMState *sa1110_init(unsigned int sdram_size, const char *rev)
+{
+ StrongARMState *s;
+ qemu_irq *pic;
+ int i;
+
+ s = qemu_mallocz(sizeof(StrongARMState));
+
+ if (!rev) {
+ rev = "sa1110-b5";
+ }
+
+ if (strncmp(rev, "sa1110", 6)) {
+ error_report("Machine requires a SA1110 processor.\n");
+ exit(1);
+ }
+
+ s->env = cpu_init(rev);
+
+ if (!s->env) {
+ error_report("Unable to find CPU definition\n");
+ exit(1);
+ }
+
+ cpu_register_physical_memory(SA_SDCS0,
+ sdram_size, qemu_ram_alloc(NULL, "strongarm.sdram",
+ sdram_size) | IO_MEM_RAM);
+
+ pic = arm_pic_init_cpu(s->env);
+ s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
+ pic[ARM_PIC_CPU_IRQ], pic[ARM_PIC_CPU_FIQ], NULL);
+
+ sysbus_create_varargs("pxa25x-timer", 0x90000000,
+ qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
+ qdev_get_gpio_in(s->pic, SA_PIC_OSTC1),
+ qdev_get_gpio_in(s->pic, SA_PIC_OSTC2),
+ qdev_get_gpio_in(s->pic, SA_PIC_OSTC3),
+ NULL);
+
+ sysbus_create_simple("strongarm-rtc", 0x90010000,
+ qdev_get_gpio_in(s->pic, SA_PIC_RTC_ALARM));
+
+ s->gpio = strongarm_gpio_init(0x90040000, s->pic);
+
+ s->ppc = sysbus_create_varargs("strongarm-ppc", 0x90060000, NULL);
+
+ for (i = 0; sa_serial[i].io_base; i++) {
+ DeviceState *dev = qdev_create(NULL, "strongarm-uart");
+ qdev_prop_set_chr(dev, "chardev", serial_hds[i]);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(sysbus_from_qdev(dev), 0,
+ sa_serial[i].io_base);
+ sysbus_connect_irq(sysbus_from_qdev(dev), 0,
+ qdev_get_gpio_in(s->pic, sa_serial[i].irq));
+ }
+
+ s->ssp = sysbus_create_varargs("strongarm-ssp", 0x80070000,
+ qdev_get_gpio_in(s->pic, SA_PIC_SSP), NULL);
+ s->ssp_bus = (SSIBus *)qdev_get_child_bus(s->ssp, "ssi");
+
+ return s;
+}
+
+static void strongarm_register_devices(void)
+{
+ sysbus_register_withprop(&strongarm_pic_info);
+ sysbus_register_withprop(&strongarm_rtc_sysbus_info);
+ sysbus_register_withprop(&strongarm_gpio_info);
+ sysbus_register_withprop(&strongarm_ppc_info);
+ sysbus_register_withprop(&strongarm_uart_info);
+ sysbus_register_withprop(&strongarm_ssp_info);
+}
+device_init(strongarm_register_devices)
diff --git a/hw/strongarm.h b/hw/strongarm.h
new file mode 100644
index 000000000..a81b110e2
--- /dev/null
+++ b/hw/strongarm.h
@@ -0,0 +1,64 @@
+#ifndef _STRONGARM_H
+#define _STRONGARM_H
+
+#define SA_CS0 0x00000000
+#define SA_CS1 0x08000000
+#define SA_CS2 0x10000000
+#define SA_CS3 0x18000000
+#define SA_PCMCIA_CS0 0x20000000
+#define SA_PCMCIA_CS1 0x30000000
+#define SA_CS4 0x40000000
+#define SA_CS5 0x48000000
+/* system registers here */
+#define SA_SDCS0 0xc0000000
+#define SA_SDCS1 0xc8000000
+#define SA_SDCS2 0xd0000000
+#define SA_SDCS3 0xd8000000
+
+enum {
+ SA_PIC_GPIO0_EDGE = 0,
+ SA_PIC_GPIO1_EDGE,
+ SA_PIC_GPIO2_EDGE,
+ SA_PIC_GPIO3_EDGE,
+ SA_PIC_GPIO4_EDGE,
+ SA_PIC_GPIO5_EDGE,
+ SA_PIC_GPIO6_EDGE,
+ SA_PIC_GPIO7_EDGE,
+ SA_PIC_GPIO8_EDGE,
+ SA_PIC_GPIO9_EDGE,
+ SA_PIC_GPIO10_EDGE,
+ SA_PIC_GPIOX_EDGE,
+ SA_PIC_LCD,
+ SA_PIC_UDC,
+ SA_PIC_RSVD1,
+ SA_PIC_UART1,
+ SA_PIC_UART2,
+ SA_PIC_UART3,
+ SA_PIC_MCP,
+ SA_PIC_SSP,
+ SA_PIC_DMA_CH0,
+ SA_PIC_DMA_CH1,
+ SA_PIC_DMA_CH2,
+ SA_PIC_DMA_CH3,
+ SA_PIC_DMA_CH4,
+ SA_PIC_DMA_CH5,
+ SA_PIC_OSTC0,
+ SA_PIC_OSTC1,
+ SA_PIC_OSTC2,
+ SA_PIC_OSTC3,
+ SA_PIC_RTC_HZ,
+ SA_PIC_RTC_ALARM,
+};
+
+typedef struct {
+ CPUState *env;
+ DeviceState *pic;
+ DeviceState *gpio;
+ DeviceState *ppc;
+ DeviceState *ssp;
+ SSIBus *ssp_bus;
+} StrongARMState;
+
+StrongARMState *sa1110_init(unsigned int sdram_size, const char *rev);
+
+#endif
diff --git a/hw/syborg.c b/hw/syborg.c
index 758c69a9c..bc200e48a 100644
--- a/hw/syborg.c
+++ b/hw/syborg.c
@@ -25,7 +25,6 @@
#include "sysbus.h"
#include "boards.h"
#include "arm-misc.h"
-#include "sysemu.h"
#include "net.h"
static struct arm_boot_info syborg_binfo;
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index d295e99eb..706a03966 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -51,11 +51,11 @@ enum {
typedef struct {
SysBusDevice busdev;
- int int_enabled;
+ uint32_t int_enabled;
int extension_bit;
uint32_t fifo_size;
uint32_t *key_fifo;
- int read_pos, read_count;
+ uint32_t read_pos, read_count;
qemu_irq irq;
} SyborgKeyboardState;
@@ -165,43 +165,21 @@ static void syborg_keyboard_event(void *opaque, int keycode)
syborg_keyboard_update(s);
}
-static void syborg_keyboard_save(QEMUFile *f, void *opaque)
-{
- SyborgKeyboardState *s = (SyborgKeyboardState *)opaque;
- int i;
-
- qemu_put_be32(f, s->fifo_size);
- qemu_put_be32(f, s->int_enabled);
- qemu_put_be32(f, s->extension_bit);
- qemu_put_be32(f, s->read_pos);
- qemu_put_be32(f, s->read_count);
- for (i = 0; i < s->fifo_size; i++) {
- qemu_put_be32(f, s->key_fifo[i]);
- }
-}
-
-static int syborg_keyboard_load(QEMUFile *f, void *opaque, int version_id)
-{
- SyborgKeyboardState *s = (SyborgKeyboardState *)opaque;
- uint32_t val;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- val = qemu_get_be32(f);
- if (val != s->fifo_size)
- return -EINVAL;
-
- s->int_enabled = qemu_get_be32(f);
- s->extension_bit = qemu_get_be32(f);
- s->read_pos = qemu_get_be32(f);
- s->read_count = qemu_get_be32(f);
- for (i = 0; i < s->fifo_size; i++) {
- s->key_fifo[i] = qemu_get_be32(f);
+static const VMStateDescription vmstate_syborg_keyboard = {
+ .name = "syborg_keyboard",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_EQUAL(fifo_size, SyborgKeyboardState),
+ VMSTATE_UINT32(int_enabled, SyborgKeyboardState),
+ VMSTATE_UINT32(read_pos, SyborgKeyboardState),
+ VMSTATE_UINT32(read_count, SyborgKeyboardState),
+ VMSTATE_VARRAY_UINT32(key_fifo, SyborgKeyboardState, fifo_size, 1,
+ vmstate_info_uint32, uint32),
+ VMSTATE_END_OF_LIST()
}
- return 0;
-}
+};
static int syborg_keyboard_init(SysBusDevice *dev)
{
@@ -221,8 +199,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
qemu_add_kbd_event_handler(syborg_keyboard_event, s);
- register_savevm(&dev->qdev, "syborg_keyboard", -1, 1,
- syborg_keyboard_save, syborg_keyboard_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_syborg_keyboard, s);
return 0;
}
diff --git a/hw/syborg_pointer.c b/hw/syborg_pointer.c
index a88688846..2f9970704 100644
--- a/hw/syborg_pointer.c
+++ b/hw/syborg_pointer.c
@@ -152,52 +152,36 @@ static void syborg_pointer_event(void *opaque, int dx, int dy, int dz,
syborg_pointer_update(s);
}
-static void syborg_pointer_save(QEMUFile *f, void *opaque)
-{
- SyborgPointerState *s = (SyborgPointerState *)opaque;
- int i;
-
- qemu_put_be32(f, s->fifo_size);
- qemu_put_be32(f, s->absolute);
- qemu_put_be32(f, s->int_enabled);
- qemu_put_be32(f, s->read_pos);
- qemu_put_be32(f, s->read_count);
- for (i = 0; i < s->fifo_size; i++) {
- qemu_put_be32(f, s->event_fifo[i].x);
- qemu_put_be32(f, s->event_fifo[i].y);
- qemu_put_be32(f, s->event_fifo[i].z);
- qemu_put_be32(f, s->event_fifo[i].pointer_buttons);
+static const VMStateDescription vmstate_event_data = {
+ .name = "dbma_channel",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(x, event_data),
+ VMSTATE_INT32(y, event_data),
+ VMSTATE_INT32(z, event_data),
+ VMSTATE_INT32(pointer_buttons, event_data),
+ VMSTATE_END_OF_LIST()
}
-}
+};
-static int syborg_pointer_load(QEMUFile *f, void *opaque, int version_id)
-{
- SyborgPointerState *s = (SyborgPointerState *)opaque;
- uint32_t val;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- val = qemu_get_be32(f);
- if (val != s->fifo_size)
- return -EINVAL;
-
- val = qemu_get_be32(f);
- if (val != s->absolute)
- return -EINVAL;
-
- s->int_enabled = qemu_get_be32(f);
- s->read_pos = qemu_get_be32(f);
- s->read_count = qemu_get_be32(f);
- for (i = 0; i < s->fifo_size; i++) {
- s->event_fifo[i].x = qemu_get_be32(f);
- s->event_fifo[i].y = qemu_get_be32(f);
- s->event_fifo[i].z = qemu_get_be32(f);
- s->event_fifo[i].pointer_buttons = qemu_get_be32(f);
+static const VMStateDescription vmstate_syborg_pointer = {
+ .name = "syborg_pointer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_EQUAL(fifo_size, SyborgPointerState),
+ VMSTATE_UINT32_EQUAL(absolute, SyborgPointerState),
+ VMSTATE_INT32(int_enabled, SyborgPointerState),
+ VMSTATE_INT32(read_pos, SyborgPointerState),
+ VMSTATE_INT32(read_count, SyborgPointerState),
+ VMSTATE_STRUCT_VARRAY_UINT32(event_fifo, SyborgPointerState, fifo_size,
+ 1, vmstate_event_data, event_data),
+ VMSTATE_END_OF_LIST()
}
- return 0;
-}
+};
static int syborg_pointer_init(SysBusDevice *dev)
{
@@ -219,8 +203,7 @@ static int syborg_pointer_init(SysBusDevice *dev)
qemu_add_mouse_event_handler(syborg_pointer_event, s, s->absolute,
"Syborg Pointer");
- register_savevm(&dev->qdev, "syborg_pointer", -1, 1,
- syborg_pointer_save, syborg_pointer_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_syborg_pointer, s);
return 0;
}
diff --git a/hw/syborg_rtc.c b/hw/syborg_rtc.c
index 16d8f9edb..69f6ccf29 100644
--- a/hw/syborg_rtc.c
+++ b/hw/syborg_rtc.c
@@ -102,26 +102,17 @@ static CPUWriteMemoryFunc * const syborg_rtc_writefn[] = {
syborg_rtc_write
};
-static void syborg_rtc_save(QEMUFile *f, void *opaque)
-{
- SyborgRTCState *s = opaque;
-
- qemu_put_be64(f, s->offset);
- qemu_put_be64(f, s->data);
-}
-
-static int syborg_rtc_load(QEMUFile *f, void *opaque, int version_id)
-{
- SyborgRTCState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->offset = qemu_get_be64(f);
- s->data = qemu_get_be64(f);
-
- return 0;
-}
+static const VMStateDescription vmstate_syborg_rtc = {
+ .name = "syborg_keyboard",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT64(offset, SyborgRTCState),
+ VMSTATE_INT64(data, SyborgRTCState),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int syborg_rtc_init(SysBusDevice *dev)
{
@@ -137,8 +128,7 @@ static int syborg_rtc_init(SysBusDevice *dev)
qemu_get_timedate(&tm, 0);
s->offset = (uint64_t)mktime(&tm) * 1000000000;
- register_savevm(&dev->qdev, "syborg_rtc", -1, 1,
- syborg_rtc_save, syborg_rtc_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_syborg_rtc, s);
return 0;
}
diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
index 34ce076d4..df2950fe8 100644
--- a/hw/syborg_serial.c
+++ b/hw/syborg_serial.c
@@ -273,47 +273,24 @@ static CPUWriteMemoryFunc * const syborg_serial_writefn[] = {
syborg_serial_write
};
-static void syborg_serial_save(QEMUFile *f, void *opaque)
-{
- SyborgSerialState *s = opaque;
- int i;
-
- qemu_put_be32(f, s->fifo_size);
- qemu_put_be32(f, s->int_enable);
- qemu_put_be32(f, s->read_pos);
- qemu_put_be32(f, s->read_count);
- qemu_put_be32(f, s->dma_tx_ptr);
- qemu_put_be32(f, s->dma_rx_ptr);
- qemu_put_be32(f, s->dma_rx_size);
- for (i = 0; i < s->fifo_size; i++) {
- qemu_put_be32(f, s->read_fifo[i]);
- }
-}
-
-static int syborg_serial_load(QEMUFile *f, void *opaque, int version_id)
-{
- SyborgSerialState *s = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- i = qemu_get_be32(f);
- if (s->fifo_size != i)
- return -EINVAL;
-
- s->int_enable = qemu_get_be32(f);
- s->read_pos = qemu_get_be32(f);
- s->read_count = qemu_get_be32(f);
- s->dma_tx_ptr = qemu_get_be32(f);
- s->dma_rx_ptr = qemu_get_be32(f);
- s->dma_rx_size = qemu_get_be32(f);
- for (i = 0; i < s->fifo_size; i++) {
- s->read_fifo[i] = qemu_get_be32(f);
+static const VMStateDescription vmstate_syborg_serial = {
+ .name = "syborg_serial",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_EQUAL(fifo_size, SyborgSerialState),
+ VMSTATE_UINT32(int_enable, SyborgSerialState),
+ VMSTATE_INT32(read_pos, SyborgSerialState),
+ VMSTATE_INT32(read_count, SyborgSerialState),
+ VMSTATE_UINT32(dma_tx_ptr, SyborgSerialState),
+ VMSTATE_UINT32(dma_rx_ptr, SyborgSerialState),
+ VMSTATE_UINT32(dma_rx_size, SyborgSerialState),
+ VMSTATE_VARRAY_UINT32(read_fifo, SyborgSerialState, fifo_size, 1,
+ vmstate_info_uint32, uint32),
+ VMSTATE_END_OF_LIST()
}
-
- return 0;
-}
+};
static int syborg_serial_init(SysBusDevice *dev)
{
@@ -336,8 +313,6 @@ static int syborg_serial_init(SysBusDevice *dev)
}
s->read_fifo = qemu_mallocz(s->fifo_size * sizeof(s->read_fifo[0]));
- register_savevm(&dev->qdev, "syborg_serial", -1, 1,
- syborg_serial_save, syborg_serial_load, s);
return 0;
}
@@ -345,6 +320,7 @@ static SysBusDeviceInfo syborg_serial_info = {
.init = syborg_serial_init,
.qdev.name = "syborg,serial",
.qdev.size = sizeof(SyborgSerialState),
+ .qdev.vmsd = &vmstate_syborg_serial,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("fifo-size", SyborgSerialState, fifo_size, 16),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/syborg_timer.c b/hw/syborg_timer.c
index cedcd8ed4..50c813e96 100644
--- a/hw/syborg_timer.c
+++ b/hw/syborg_timer.c
@@ -174,34 +174,21 @@ static CPUWriteMemoryFunc * const syborg_timer_writefn[] = {
syborg_timer_write
};
-static void syborg_timer_save(QEMUFile *f, void *opaque)
-{
- SyborgTimerState *s = opaque;
-
- qemu_put_be32(f, s->running);
- qemu_put_be32(f, s->oneshot);
- qemu_put_be32(f, s->limit);
- qemu_put_be32(f, s->int_level);
- qemu_put_be32(f, s->int_enabled);
- qemu_put_ptimer(f, s->timer);
-}
-
-static int syborg_timer_load(QEMUFile *f, void *opaque, int version_id)
-{
- SyborgTimerState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->running = qemu_get_be32(f);
- s->oneshot = qemu_get_be32(f);
- s->limit = qemu_get_be32(f);
- s->int_level = qemu_get_be32(f);
- s->int_enabled = qemu_get_be32(f);
- qemu_get_ptimer(f, s->timer);
-
- return 0;
-}
+static const VMStateDescription vmstate_syborg_timer = {
+ .name = "syborg_timer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(running, SyborgTimerState),
+ VMSTATE_INT32(oneshot, SyborgTimerState),
+ VMSTATE_UINT32(limit, SyborgTimerState),
+ VMSTATE_UINT32(int_level, SyborgTimerState),
+ VMSTATE_UINT32(int_enabled, SyborgTimerState),
+ VMSTATE_PTIMER(timer, SyborgTimerState),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int syborg_timer_init(SysBusDevice *dev)
{
@@ -222,8 +209,7 @@ static int syborg_timer_init(SysBusDevice *dev)
bh = qemu_bh_new(syborg_timer_tick, s);
s->timer = ptimer_init(bh);
ptimer_set_freq(s->timer, s->freq);
- register_savevm(&dev->qdev, "syborg_timer", -1, 1,
- syborg_timer_save, syborg_timer_load, s);
+ vmstate_register(&dev->qdev, -1, &vmstate_syborg_timer, s);
return 0;
}
diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index ee08c4910..2f3e6da4e 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -26,7 +26,6 @@
#include "sysbus.h"
#include "virtio.h"
#include "virtio-net.h"
-#include "sysemu.h"
//#define DEBUG_SYBORG_VIRTIO
diff --git a/hw/sysbus.c b/hw/sysbus.c
index acad72abe..2e22be7b2 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -18,7 +18,6 @@
*/
#include "sysbus.h"
-#include "sysemu.h"
#include "monitor.h"
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
diff --git a/hw/tc58128.c b/hw/tc58128.c
index 672a01c46..61b99dd4d 100644
--- a/hw/tc58128.c
+++ b/hw/tc58128.c
@@ -1,6 +1,5 @@
#include "hw.h"
#include "sh.h"
-#include "sysemu.h"
#include "loader.h"
#define CE1 0x0100
diff --git a/hw/tosa.c b/hw/tosa.c
index b8b6c4f39..a7967a286 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -11,7 +11,6 @@
#include "hw.h"
#include "pxa.h"
#include "arm-misc.h"
-#include "sysemu.h"
#include "devices.h"
#include "sharpsl.h"
#include "pcmcia.h"
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 8e74acc05..a75448f06 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -22,7 +22,6 @@
#include "hw.h"
#include "qemu-timer.h"
#include "i2c.h"
-#include "sysemu.h"
#include "console.h"
#define VERBOSE 1
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index c25362cc9..89c293c46 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -26,7 +26,7 @@
#include "console.h"
#include "usb.h"
#include "usb-desc.h"
-#include "sysemu.h"
+#include "qemu-timer.h"
/* HID interface requests */
#define GET_REPORT 0xa101
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 76f5b027b..947fd3f83 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -33,7 +33,7 @@ do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
enum USBMSDMode {
USB_MSDM_CBW, /* Command Block. */
- USB_MSDM_DATAOUT, /* Tranfer data to device. */
+ USB_MSDM_DATAOUT, /* Transfer data to device. */
USB_MSDM_DATAIN, /* Transfer data from device. */
USB_MSDM_CSW /* Command Status. */
};
@@ -253,7 +253,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
usb_msd_copy_data(s);
if (s->usb_len == 0) {
/* Set s->packet to NULL before calling usb_packet_complete
- because annother request may be issued before
+ because another request may be issued before
usb_packet_complete returns. */
DPRINTF("Packet complete %p\n", p);
s->packet = NULL;
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index f9add1cd4..447b337e0 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -15,7 +15,6 @@
#include "qemu-common.h"
#include "virtio.h"
#include "pc.h"
-#include "sysemu.h"
#include "cpu.h"
#include "monitor.h"
#include "balloon.h"
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 6b5237b3c..de539c4ea 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -28,6 +28,22 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
return qemu_chr_write(vcon->chr, buf, len);
}
+/* Callback function that's called when the guest opens the port */
+static void guest_open(VirtIOSerialPort *port)
+{
+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+
+ qemu_chr_guest_open(vcon->chr);
+}
+
+/* Callback function that's called when the guest closes the port */
+static void guest_close(VirtIOSerialPort *port)
+{
+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+
+ qemu_chr_guest_close(vcon->chr);
+}
+
/* Readiness of the guest to accept data on a port */
static int chr_can_read(void *opaque)
{
@@ -64,6 +80,8 @@ static int generic_port_init(VirtConsole *vcon, VirtIOSerialPort *port)
qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
vcon);
vcon->port.info->have_data = flush_buf;
+ vcon->port.info->guest_open = guest_open;
+ vcon->port.info->guest_close = guest_close;
}
return 0;
}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 5236470ba..991005bca 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -961,7 +961,7 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_net_init_pci,
.exit = virtio_net_exit_pci,
- .romfile = "pxe-virtio.bin",
+ .romfile = "pxe-virtio.rom",
.qdev.props = (Property[]) {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 62273799b..f10d48fdb 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -494,7 +494,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
VirtIOSerial *s = opaque;
VirtIOSerialPort *port;
uint32_t nr_active_ports;
- unsigned int i;
+ unsigned int i, max_nr_ports;
/* The virtio device */
virtio_save(&s->vdev, f);
@@ -506,8 +506,8 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
qemu_put_be32s(f, &s->config.max_nr_ports);
/* The ports map */
-
- for (i = 0; i < (s->config.max_nr_ports + 31) / 32; i++) {
+ max_nr_ports = tswap32(s->config.max_nr_ports);
+ for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
qemu_put_be32s(f, &s->ports_map[i]);
}
@@ -568,7 +568,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_be16s(f, &s->config.rows);
qemu_get_be32s(f, &max_nr_ports);
- if (max_nr_ports > s->config.max_nr_ports) {
+ tswap32s(&max_nr_ports);
+ if (max_nr_ports > tswap32(s->config.max_nr_ports)) {
/* Source could have had more ports than us. Fail migration. */
return -EINVAL;
}
@@ -670,9 +671,10 @@ static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
/* This function is only used if a port id is not provided by the user */
static uint32_t find_free_port_id(VirtIOSerial *vser)
{
- unsigned int i;
+ unsigned int i, max_nr_ports;
- for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) {
+ max_nr_ports = tswap32(vser->config.max_nr_ports);
+ for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
uint32_t map, bit;
map = vser->ports_map[i];
@@ -720,7 +722,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base);
VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
- int ret;
+ int ret, max_nr_ports;
bool plugging_port0;
port->vser = bus->vser;
@@ -750,9 +752,10 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
}
}
- if (port->id >= port->vser->config.max_nr_ports) {
+ max_nr_ports = tswap32(port->vser->config.max_nr_ports);
+ if (port->id >= max_nr_ports) {
error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n",
- port->vser->config.max_nr_ports - 1);
+ max_nr_ports - 1);
return -1;
}
@@ -863,7 +866,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
}
- vser->config.max_nr_ports = conf->max_virtserial_ports;
+ vser->config.max_nr_ports = tswap32(conf->max_virtserial_ports);
vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
* sizeof(vser->ports_map[0]));
/*
diff --git a/hw/virtio.c b/hw/virtio.c
index 31bd9e32d..6e8814cb6 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -16,7 +16,6 @@
#include "trace.h"
#include "qemu-error.h"
#include "virtio.h"
-#include "sysemu.h"
/* The alignment to use between consumer and producer parts of vring.
* x86 pagesize again. */
diff --git a/hw/vmport.c b/hw/vmport.c
index 19010e484..c8aefaabb 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -24,7 +24,6 @@
#include "hw.h"
#include "isa.h"
#include "pc.h"
-#include "sysemu.h"
#include "kvm.h"
#include "qdev.h"
diff --git a/hw/xen_console.c b/hw/xen_console.c
index d2261f413..c6c816381 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -33,7 +33,6 @@
#include <xenctrl.h>
#include "hw.h"
-#include "sysemu.h"
#include "qemu-char.h"
#include "xen_backend.h"
diff --git a/hw/xen_domainbuild.c b/hw/xen_domainbuild.c
index 371c56206..4093587df 100644
--- a/hw/xen_domainbuild.c
+++ b/hw/xen_domainbuild.c
@@ -1,7 +1,6 @@
#include <signal.h>
#include "xen_backend.h"
#include "xen_domainbuild.h"
-#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-log.h"
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 77a34bf11..0d7f73ed8 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -24,7 +24,6 @@
#include "hw.h"
#include "pc.h"
-#include "sysemu.h"
#include "boards.h"
#include "xen_backend.h"
#include "xen_domainbuild.h"
diff --git a/hw/xenfb.c b/hw/xenfb.c
index da5297b49..1db75fbe4 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -44,7 +44,6 @@
#include <xen/io/protocols.h>
#include "hw.h"
-#include "sysemu.h"
#include "console.h"
#include "qemu-char.h"
#include "xen_backend.h"
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index 30827b03c..d398c18e9 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -23,7 +23,6 @@
*/
#include "sysbus.h"
-#include "sysemu.h"
#include "qemu-timer.h"
#define D(x)