typedef struct {
SysBusDevice busdev;
+ MemoryRegion iomem;
uint32_t int_enable;
uint32_t fifo_size;
uint32_t *read_fifo;
/* optimize later. Now, 1 byte per iteration */
while (count--) {
cpu_physical_memory_read(s->dma_tx_ptr, &ch, 1);
- qemu_chr_write(s->chr, &ch, 1);
+ qemu_chr_fe_write(s->chr, &ch, 1);
s->dma_tx_ptr++;
}
} else {
s->dma_tx_ptr += count;
}
/* QEMU char backends do not have a nonblocking mode, so we transmit all
- the data imediately and the interrupt status will be unchanged. */
+ the data immediately and the interrupt status will be unchanged. */
}
/* Initiate RX DMA, and transfer data from the FIFO. */
syborg_serial_update(s);
}
-static uint32_t syborg_serial_read(void *opaque, target_phys_addr_t offset)
+static uint64_t syborg_serial_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
SyborgSerialState *s = (SyborgSerialState *)opaque;
uint32_t c;
}
static void syborg_serial_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
SyborgSerialState *s = (SyborgSerialState *)opaque;
unsigned char ch;
case SERIAL_DATA:
ch = value;
if (s->chr)
- qemu_chr_write(s->chr, &ch, 1);
+ qemu_chr_fe_write(s->chr, &ch, 1);
break;
case SERIAL_INT_ENABLE:
s->int_enable = value;
/* TODO: Report BREAK events? */
}
-static CPUReadMemoryFunc * const syborg_serial_readfn[] = {
- syborg_serial_read,
- syborg_serial_read,
- syborg_serial_read
+static const MemoryRegionOps syborg_serial_ops = {
+ .read = syborg_serial_read,
+ .write = syborg_serial_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static CPUWriteMemoryFunc * const syborg_serial_writefn[] = {
- syborg_serial_write,
- syborg_serial_write,
- 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 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()
}
-}
-
-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);
- }
-
- return 0;
-}
+};
static int syborg_serial_init(SysBusDevice *dev)
{
SyborgSerialState *s = FROM_SYSBUS(SyborgSerialState, dev);
- int iomemtype;
sysbus_init_irq(dev, &s->irq);
- iomemtype = cpu_register_io_memory(syborg_serial_readfn,
- syborg_serial_writefn, s);
- sysbus_init_mmio(dev, 0x1000, iomemtype);
+ memory_region_init_io(&s->iomem, &syborg_serial_ops, s,
+ "serial", 0x1000);
+ sysbus_init_mmio(dev, &s->iomem);
s->chr = qdev_init_chardev(&dev->qdev);
if (s->chr) {
qemu_chr_add_handlers(s->chr, syborg_serial_can_receive,
fprintf(stderr, "syborg_serial: fifo too small\n");
s->fifo_size = 16;
}
- s->read_fifo = qemu_mallocz(s->fifo_size * sizeof(s->read_fifo[0]));
+ s->read_fifo = g_malloc0(s->fifo_size * sizeof(s->read_fifo[0]));
- register_savevm("syborg_serial", -1, 1,
- syborg_serial_save, syborg_serial_load, s);
return 0;
}
.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(),