diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/acpi/ich9.c | 10 | ||||
-rw-r--r-- | hw/acpi/piix4.c | 10 | ||||
-rw-r--r-- | hw/block/fdc.c | 42 | ||||
-rw-r--r-- | hw/char/serial.c | 41 | ||||
-rw-r--r-- | hw/display/qxl.c | 11 | ||||
-rw-r--r-- | hw/display/vga.c | 11 | ||||
-rw-r--r-- | hw/dma/rc4030.c | 462 | ||||
-rw-r--r-- | hw/i386/pc_piix.c | 2 | ||||
-rw-r--r-- | hw/i386/pc_q35.c | 2 | ||||
-rw-r--r-- | hw/ide/core.c | 32 | ||||
-rw-r--r-- | hw/ide/pci.c | 16 | ||||
-rw-r--r-- | hw/input/pckbd.c | 22 | ||||
-rw-r--r-- | hw/input/ps2.c | 11 | ||||
-rw-r--r-- | hw/intc/apic_common.c | 10 | ||||
-rw-r--r-- | hw/isa/lpc_ich9.c | 10 | ||||
-rw-r--r-- | hw/mips/Makefile.objs | 3 | ||||
-rw-r--r-- | hw/mips/mips_jazz.c | 53 | ||||
-rw-r--r-- | hw/mips/mips_malta.c | 15 | ||||
-rw-r--r-- | hw/net/dp8393x.c | 369 | ||||
-rw-r--r-- | hw/net/e1000.c | 11 | ||||
-rw-r--r-- | hw/net/rtl8139.c | 11 | ||||
-rw-r--r-- | hw/net/vmxnet3.c | 12 | ||||
-rw-r--r-- | hw/pci-host/piix.c | 10 | ||||
-rw-r--r-- | hw/scsi/scsi-bus.c | 11 | ||||
-rw-r--r-- | hw/sh4/r2d.c | 12 | ||||
-rw-r--r-- | hw/timer/hpet.c | 11 | ||||
-rw-r--r-- | hw/timer/mc146818rtc.c | 23 | ||||
-rw-r--r-- | hw/usb/hcd-ohci.c | 11 | ||||
-rw-r--r-- | hw/usb/redirect.c | 34 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 16 |
30 files changed, 624 insertions, 670 deletions
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 25bc023882..8a64ffb38f 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -152,6 +152,7 @@ static const VMStateDescription vmstate_memhp_state = { .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, + .needed = vmstate_test_use_memhp, .fields = (VMStateField[]) { VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, ICH9LPCPMRegs), VMSTATE_END_OF_LIST() @@ -175,12 +176,9 @@ const VMStateDescription vmstate_ich9_pm = { VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_memhp_state, - .needed = vmstate_test_use_memhp, - }, - VMSTATE_END_OF_LIST() + .subsections = (const VMStateDescription*[]) { + &vmstate_memhp_state, + NULL } }; diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index b730ca6ced..3bd1d5a865 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -260,6 +260,7 @@ static const VMStateDescription vmstate_memhp_state = { .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, + .needed = vmstate_test_use_memhp, .fields = (VMStateField[]) { VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, PIIX4PMState), VMSTATE_END_OF_LIST() @@ -298,12 +299,9 @@ static const VMStateDescription vmstate_acpi = { vmstate_test_use_acpi_pci_hotplug), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_memhp_state, - .needed = vmstate_test_use_memhp, - }, - VMSTATE_END_OF_LIST() + .subsections = (const VMStateDescription*[]) { + &vmstate_memhp_state, + NULL } }; diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 6e794597dc..5e1b67ee43 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -699,6 +699,7 @@ static const VMStateDescription vmstate_fdrive_media_changed = { .name = "fdrive/media_changed", .version_id = 1, .minimum_version_id = 1, + .needed = fdrive_media_changed_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(media_changed, FDrive), VMSTATE_END_OF_LIST() @@ -716,6 +717,7 @@ static const VMStateDescription vmstate_fdrive_media_rate = { .name = "fdrive/media_rate", .version_id = 1, .minimum_version_id = 1, + .needed = fdrive_media_rate_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(media_rate, FDrive), VMSTATE_END_OF_LIST() @@ -733,6 +735,7 @@ static const VMStateDescription vmstate_fdrive_perpendicular = { .name = "fdrive/perpendicular", .version_id = 1, .minimum_version_id = 1, + .needed = fdrive_perpendicular_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(perpendicular, FDrive), VMSTATE_END_OF_LIST() @@ -756,19 +759,11 @@ static const VMStateDescription vmstate_fdrive = { VMSTATE_UINT8(sect, FDrive), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_fdrive_media_changed, - .needed = &fdrive_media_changed_needed, - } , { - .vmsd = &vmstate_fdrive_media_rate, - .needed = &fdrive_media_rate_needed, - } , { - .vmsd = &vmstate_fdrive_perpendicular, - .needed = &fdrive_perpendicular_needed, - } , { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_fdrive_media_changed, + &vmstate_fdrive_media_rate, + &vmstate_fdrive_perpendicular, + NULL } }; @@ -833,6 +828,7 @@ static const VMStateDescription vmstate_fdc_reset_sensei = { .name = "fdc/reset_sensei", .version_id = 1, .minimum_version_id = 1, + .needed = fdc_reset_sensei_needed, .fields = (VMStateField[]) { VMSTATE_INT32(reset_sensei, FDCtrl), VMSTATE_END_OF_LIST() @@ -850,6 +846,7 @@ static const VMStateDescription vmstate_fdc_result_timer = { .name = "fdc/result_timer", .version_id = 1, .minimum_version_id = 1, + .needed = fdc_result_timer_needed, .fields = (VMStateField[]) { VMSTATE_TIMER_PTR(result_timer, FDCtrl), VMSTATE_END_OF_LIST() @@ -867,6 +864,7 @@ static const VMStateDescription vmstate_fdc_phase = { .name = "fdc/phase", .version_id = 1, .minimum_version_id = 1, + .needed = fdc_phase_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(phase, FDCtrl), VMSTATE_END_OF_LIST() @@ -911,19 +909,11 @@ static const VMStateDescription vmstate_fdc = { vmstate_fdrive, FDrive), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_fdc_reset_sensei, - .needed = fdc_reset_sensei_needed, - } , { - .vmsd = &vmstate_fdc_result_timer, - .needed = fdc_result_timer_needed, - } , { - .vmsd = &vmstate_fdc_phase, - .needed = fdc_phase_needed, - } , { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_fdc_reset_sensei, + &vmstate_fdc_result_timer, + &vmstate_fdc_phase, + NULL } }; diff --git a/hw/char/serial.c b/hw/char/serial.c index 55011cfd26..513d73c27f 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -662,6 +662,7 @@ static const VMStateDescription vmstate_serial_thr_ipending = { .name = "serial/thr_ipending", .version_id = 1, .minimum_version_id = 1, + .needed = serial_thr_ipending_needed, .fields = (VMStateField[]) { VMSTATE_INT32(thr_ipending, SerialState), VMSTATE_END_OF_LIST() @@ -678,6 +679,7 @@ static const VMStateDescription vmstate_serial_tsr = { .name = "serial/tsr", .version_id = 1, .minimum_version_id = 1, + .needed = serial_tsr_needed, .fields = (VMStateField[]) { VMSTATE_INT32(tsr_retry, SerialState), VMSTATE_UINT8(thr, SerialState), @@ -697,6 +699,7 @@ static const VMStateDescription vmstate_serial_recv_fifo = { .name = "serial/recv_fifo", .version_id = 1, .minimum_version_id = 1, + .needed = serial_recv_fifo_needed, .fields = (VMStateField[]) { VMSTATE_STRUCT(recv_fifo, SerialState, 1, vmstate_fifo8, Fifo8), VMSTATE_END_OF_LIST() @@ -713,6 +716,7 @@ static const VMStateDescription vmstate_serial_xmit_fifo = { .name = "serial/xmit_fifo", .version_id = 1, .minimum_version_id = 1, + .needed = serial_xmit_fifo_needed, .fields = (VMStateField[]) { VMSTATE_STRUCT(xmit_fifo, SerialState, 1, vmstate_fifo8, Fifo8), VMSTATE_END_OF_LIST() @@ -729,6 +733,7 @@ static const VMStateDescription vmstate_serial_fifo_timeout_timer = { .name = "serial/fifo_timeout_timer", .version_id = 1, .minimum_version_id = 1, + .needed = serial_fifo_timeout_timer_needed, .fields = (VMStateField[]) { VMSTATE_TIMER_PTR(fifo_timeout_timer, SerialState), VMSTATE_END_OF_LIST() @@ -745,6 +750,7 @@ static const VMStateDescription vmstate_serial_timeout_ipending = { .name = "serial/timeout_ipending", .version_id = 1, .minimum_version_id = 1, + .needed = serial_timeout_ipending_needed, .fields = (VMStateField[]) { VMSTATE_INT32(timeout_ipending, SerialState), VMSTATE_END_OF_LIST() @@ -760,6 +766,7 @@ static bool serial_poll_needed(void *opaque) static const VMStateDescription vmstate_serial_poll = { .name = "serial/poll", .version_id = 1, + .needed = serial_poll_needed, .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_INT32(poll_msl, SerialState), @@ -788,31 +795,15 @@ const VMStateDescription vmstate_serial = { VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_serial_thr_ipending, - .needed = &serial_thr_ipending_needed, - } , { - .vmsd = &vmstate_serial_tsr, - .needed = &serial_tsr_needed, - } , { - .vmsd = &vmstate_serial_recv_fifo, - .needed = &serial_recv_fifo_needed, - } , { - .vmsd = &vmstate_serial_xmit_fifo, - .needed = &serial_xmit_fifo_needed, - } , { - .vmsd = &vmstate_serial_fifo_timeout_timer, - .needed = &serial_fifo_timeout_timer_needed, - } , { - .vmsd = &vmstate_serial_timeout_ipending, - .needed = &serial_timeout_ipending_needed, - } , { - .vmsd = &vmstate_serial_poll, - .needed = &serial_poll_needed, - } , { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_serial_thr_ipending, + &vmstate_serial_tsr, + &vmstate_serial_recv_fifo, + &vmstate_serial_xmit_fifo, + &vmstate_serial_fifo_timeout_timer, + &vmstate_serial_timeout_ipending, + &vmstate_serial_poll, + NULL } }; diff --git a/hw/display/qxl.c b/hw/display/qxl.c index b220e2d5d2..722146ec3a 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2220,6 +2220,7 @@ static VMStateDescription qxl_vmstate_monitors_config = { .name = "qxl/monitors-config", .version_id = 1, .minimum_version_id = 1, + .needed = qxl_monitors_config_needed, .fields = (VMStateField[]) { VMSTATE_UINT64(guest_monitors_config, PCIQXLDevice), VMSTATE_END_OF_LIST() @@ -2253,13 +2254,9 @@ static VMStateDescription qxl_vmstate = { VMSTATE_UINT64(guest_cursor, PCIQXLDevice), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &qxl_vmstate_monitors_config, - .needed = qxl_monitors_config_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &qxl_vmstate_monitors_config, + NULL } }; diff --git a/hw/display/vga.c b/hw/display/vga.c index d1d296c74e..b35d523e65 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -2035,6 +2035,7 @@ static const VMStateDescription vmstate_vga_endian = { .name = "vga.endian", .version_id = 1, .minimum_version_id = 1, + .needed = vga_endian_state_needed, .fields = (VMStateField[]) { VMSTATE_BOOL(big_endian_fb, VGACommonState), VMSTATE_END_OF_LIST() @@ -2078,13 +2079,9 @@ const VMStateDescription vmstate_vga_common = { VMSTATE_UINT32(vbe_bank_mask, VGACommonState), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_vga_endian, - .needed = vga_endian_state_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_vga_endian, + NULL } }; diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c index af2663256e..3efa6de352 100644 --- a/hw/dma/rc4030.c +++ b/hw/dma/rc4030.c @@ -1,7 +1,7 @@ /* * QEMU JAZZ RC4030 chipset * - * Copyright (c) 2007-2009 Herve Poussineau + * Copyright (c) 2007-2013 Hervé Poussineau * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,29 +24,16 @@ #include "hw/hw.h" #include "hw/mips/mips.h" +#include "hw/sysbus.h" #include "qemu/timer.h" - -/********************************************************/ -/* debug rc4030 */ - -//#define DEBUG_RC4030 -//#define DEBUG_RC4030_DMA - -#ifdef DEBUG_RC4030 -#define DPRINTF(fmt, ...) \ -do { printf("rc4030: " fmt , ## __VA_ARGS__); } while (0) -static const char* irq_names[] = { "parallel", "floppy", "sound", "video", - "network", "scsi", "keyboard", "mouse", "serial0", "serial1" }; -#else -#define DPRINTF(fmt, ...) -#endif - -#define RC4030_ERROR(fmt, ...) \ -do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0) +#include "exec/address-spaces.h" +#include "trace.h" /********************************************************/ /* rc4030 emulation */ +#define MAX_TL_ENTRIES 512 + typedef struct dma_pagetable_entry { int32_t frame; int32_t owner; @@ -63,8 +50,14 @@ typedef struct dma_pagetable_entry { #define DMA_FLAG_MEM_INTR 0x0200 #define DMA_FLAG_ADDR_INTR 0x0400 +#define TYPE_RC4030 "rc4030" +#define RC4030(obj) \ + OBJECT_CHECK(rc4030State, (obj), TYPE_RC4030) + typedef struct rc4030State { + SysBusDevice parent; + uint32_t config; /* 0x0000: RC4030 config register */ uint32_t revision; /* 0x0008: RC4030 Revision register */ uint32_t invalid_address_register; /* 0x0010: Invalid Address register */ @@ -83,7 +76,7 @@ typedef struct rc4030State uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */ uint32_t nmi_interrupt; /* 0x0200: interrupt source */ - uint32_t offset210; + uint32_t memory_refresh_rate; /* 0x0210: memory refresh rate */ uint32_t nvram_protect; /* 0x0220: NV ram protect register */ uint32_t rem_speed[16]; uint32_t imr_jazz; /* Local bus int enable mask */ @@ -96,6 +89,16 @@ typedef struct rc4030State qemu_irq timer_irq; qemu_irq jazz_bus_irq; + /* biggest translation table */ + MemoryRegion dma_tt; + /* translation table memory region alias, added to system RAM */ + MemoryRegion dma_tt_alias; + /* whole DMA memory region, root of DMA address space */ + MemoryRegion dma_mr; + /* translation table entry aliases, added to DMA memory region */ + MemoryRegion dma_mrs[MAX_TL_ENTRIES]; + AddressSpace dma_as; + MemoryRegion iomem_chipset; MemoryRegion iomem_jazzio; } rc4030State; @@ -112,7 +115,7 @@ static void set_next_tick(rc4030State *s) } /* called for accesses to rc4030 */ -static uint32_t rc4030_readl(void *opaque, hwaddr addr) +static uint64_t rc4030_read(void *opaque, hwaddr addr, unsigned int size) { rc4030State *s = opaque; uint32_t val; @@ -220,9 +223,9 @@ static uint32_t rc4030_readl(void *opaque, hwaddr addr) case 0x0208: val = 0; break; - /* Offset 0x0210 */ + /* Memory refresh rate */ case 0x0210: - val = s->offset210; + val = s->memory_refresh_rate; break; /* NV ram protect register */ case 0x0220: @@ -238,39 +241,117 @@ static uint32_t rc4030_readl(void *opaque, hwaddr addr) val = 7; /* FIXME: should be read from EISA controller */ break; default: - RC4030_ERROR("invalid read [" TARGET_FMT_plx "]\n", addr); + qemu_log_mask(LOG_GUEST_ERROR, + "rc4030: invalid read at 0x%x", (int)addr); val = 0; break; } if ((addr & ~3) != 0x230) { - DPRINTF("read 0x%02x at " TARGET_FMT_plx "\n", val, addr); + trace_rc4030_read(addr, val); } return val; } -static uint32_t rc4030_readw(void *opaque, hwaddr addr) +static void rc4030_dma_as_update_one(rc4030State *s, int index, uint32_t frame) { - uint32_t v = rc4030_readl(opaque, addr & ~0x3); - if (addr & 0x2) - return v >> 16; - else - return v & 0xffff; + if (index < MAX_TL_ENTRIES) { + memory_region_set_enabled(&s->dma_mrs[index], false); + } + + if (!frame) { + return; + } + + if (index >= MAX_TL_ENTRIES) { + qemu_log_mask(LOG_UNIMP, + "rc4030: trying to use too high " + "translation table entry %d (max allowed=%d)", + index, MAX_TL_ENTRIES); + return; + } + memory_region_set_alias_offset(&s->dma_mrs[index], frame); + memory_region_set_enabled(&s->dma_mrs[index], true); } -static uint32_t rc4030_readb(void *opaque, hwaddr addr) +static void rc4030_dma_tt_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) { - uint32_t v = rc4030_readl(opaque, addr & ~0x3); - return (v >> (8 * (addr & 0x3))) & 0xff; + rc4030State *s = opaque; + + /* write memory */ + memcpy(memory_region_get_ram_ptr(&s->dma_tt) + addr, &data, size); + + /* update dma address space (only if frame field has been written) */ + if (addr % sizeof(dma_pagetable_entry) == 0) { + int index = addr / sizeof(dma_pagetable_entry); + memory_region_transaction_begin(); + rc4030_dma_as_update_one(s, index, (uint32_t)data); + memory_region_transaction_commit(); + } } -static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val) +static const MemoryRegionOps rc4030_dma_tt_ops = { + .write = rc4030_dma_tt_write, + .impl.min_access_size = 4, + .impl.max_access_size = 4, +}; + +static void rc4030_dma_tt_update(rc4030State *s, uint32_t new_tl_base, + uint32_t new_tl_limit) +{ + int entries, i; + dma_pagetable_entry *dma_tl_contents; + + if (s->dma_tl_limit) { + /* write old dma tl table to physical memory */ + memory_region_del_subregion(get_system_memory(), &s->dma_tt_alias); + cpu_physical_memory_write(s->dma_tl_limit & 0x7fffffff, + memory_region_get_ram_ptr(&s->dma_tt), + memory_region_size(&s->dma_tt_alias)); + } + object_unparent(OBJECT(&s->dma_tt_alias)); + + s->dma_tl_base = new_tl_base; + s->dma_tl_limit = new_tl_limit; + new_tl_base &= 0x7fffffff; + + if (s->dma_tl_limit) { + uint64_t dma_tt_size; + if (s->dma_tl_limit <= memory_region_size(&s->dma_tt)) { + dma_tt_size = s->dma_tl_limit; + } else { + dma_tt_size = memory_region_size(&s->dma_tt); + } + memory_region_init_alias(&s->dma_tt_alias, OBJECT(s), + "dma-table-alias", + &s->dma_tt, 0, dma_tt_size); + dma_tl_contents = memory_region_get_ram_ptr(&s->dma_tt); + cpu_physical_memory_read(new_tl_base, dma_tl_contents, dma_tt_size); + + memory_region_transaction_begin(); + entries = dma_tt_size / sizeof(dma_pagetable_entry); + for (i = 0; i < entries; i++) { + rc4030_dma_as_update_one(s, i, dma_tl_contents[i].frame); + } + memory_region_add_subregion(get_system_memory(), new_tl_base, + &s->dma_tt_alias); + memory_region_transaction_commit(); + } else { + memory_region_init(&s->dma_tt_alias, OBJECT(s), + "dma-table-alias", 0); + } +} + +static void rc4030_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) { rc4030State *s = opaque; + uint32_t val = data; addr &= 0x3fff; - DPRINTF("write 0x%02x at " TARGET_FMT_plx "\n", val, addr); + trace_rc4030_write(addr, val); switch (addr & ~0x3) { /* Global config register */ @@ -279,11 +360,11 @@ static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val) break; /* DMA transl. table base */ case 0x0018: - s->dma_tl_base = val; + rc4030_dma_tt_update(s, val, s->dma_tl_limit); break; /* DMA transl. table limit */ case 0x0020: - s->dma_tl_limit = val; + rc4030_dma_tt_update(s, s->dma_tl_base, val); break; /* DMA transl. table invalidated */ case 0x0028: @@ -371,9 +452,9 @@ static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val) s->dma_regs[entry][idx] = val; } break; - /* Offset 0x0210 */ + /* Memory refresh rate */ case 0x0210: - s->offset210 = val; + s->memory_refresh_rate = val; break; /* Interval timer reload */ case 0x0228: @@ -385,48 +466,18 @@ static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val) case 0x0238: break; default: - RC4030_ERROR("invalid write of 0x%02x at [" TARGET_FMT_plx "]\n", val, addr); - break; - } -} - -static void rc4030_writew(void *opaque, hwaddr addr, uint32_t val) -{ - uint32_t old_val = rc4030_readl(opaque, addr & ~0x3); - - if (addr & 0x2) - val = (val << 16) | (old_val & 0x0000ffff); - else - val = val | (old_val & 0xffff0000); - rc4030_writel(opaque, addr & ~0x3, val); -} - -static void rc4030_writeb(void *opaque, hwaddr addr, uint32_t val) -{ - uint32_t old_val = rc4030_readl(opaque, addr & ~0x3); - - switch (addr & 3) { - case 0: - val = val | (old_val & 0xffffff00); - break; - case 1: - val = (val << 8) | (old_val & 0xffff00ff); - break; - case 2: - val = (val << 16) | (old_val & 0xff00ffff); - break; - case 3: - val = (val << 24) | (old_val & 0x00ffffff); + qemu_log_mask(LOG_GUEST_ERROR, + "rc4030: invalid write of 0x%02x at 0x%x", + val, (int)addr); break; } - rc4030_writel(opaque, addr & ~0x3, val); } static const MemoryRegionOps rc4030_ops = { - .old_mmio = { - .read = { rc4030_readb, rc4030_readw, rc4030_readl, }, - .write = { rc4030_writeb, rc4030_writew, rc4030_writel, }, - }, + .read = rc4030_read, + .write = rc4030_write, + .impl.min_access_size = 4, + .impl.max_access_size = 4, .endianness = DEVICE_NATIVE_ENDIAN, }; @@ -436,22 +487,6 @@ static void update_jazz_irq(rc4030State *s) pending = s->isr_jazz & s->imr_jazz; -#ifdef DEBUG_RC4030 - if (s->isr_jazz != 0) { - uint32_t irq = 0; - DPRINTF("pending irqs:"); - for (irq = 0; irq < ARRAY_SIZE(irq_names); irq++) { - if (s->isr_jazz & (1 << irq)) { - printf(" %s", irq_names[irq]); - if (!(s->imr_jazz & (1 << irq))) { - printf("(ignored)"); - } - } - } - printf("\n"); - } -#endif - if (pending != 0) qemu_irq_raise(s->jazz_bus_irq); else @@ -479,7 +514,7 @@ static void rc4030_periodic_timer(void *opaque) qemu_irq_raise(s->timer_irq); } -static uint32_t jazzio_readw(void *opaque, hwaddr addr) +static uint64_t jazzio_read(void *opaque, hwaddr addr, unsigned int size) { rc4030State *s = opaque; uint32_t val; @@ -494,7 +529,6 @@ static uint32_t jazzio_readw(void *opaque, hwaddr addr) irq = 0; while (pending) { if (pending & 1) { - DPRINTF("returning irq %s\n", irq_names[irq]); val = (irq + 1) << 2; break; } @@ -508,36 +542,25 @@ static uint32_t jazzio_readw(void *opaque, hwaddr addr) val = s->imr_jazz; break; default: - RC4030_ERROR("(jazz io controller) invalid read [" TARGET_FMT_plx "]\n", addr); + qemu_log_mask(LOG_GUEST_ERROR, + "rc4030/jazzio: invalid read at 0x%x", (int)addr); val = 0; + break; } - DPRINTF("(jazz io controller) read 0x%04x at " TARGET_FMT_plx "\n", val, addr); + trace_jazzio_read(addr, val); return val; } -static uint32_t jazzio_readb(void *opaque, hwaddr addr) -{ - uint32_t v; - v = jazzio_readw(opaque, addr & ~0x1); - return (v >> (8 * (addr & 0x1))) & 0xff; -} - -static uint32_t jazzio_readl(void *opaque, hwaddr addr) -{ - uint32_t v; - v = jazzio_readw(opaque, addr); - v |= jazzio_readw(opaque, addr + 2) << 16; - return v; -} - -static void jazzio_writew(void *opaque, hwaddr addr, uint32_t val) +static void jazzio_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) { rc4030State *s = opaque; + uint32_t val = data; addr &= 0xfff; - DPRINTF("(jazz io controller) write 0x%04x at " TARGET_FMT_plx "\n", val, addr); + trace_jazzio_write(addr, val); switch (addr) { /* Local bus int enable mask */ @@ -546,43 +569,24 @@ static void jazzio_writew(void *opaque, hwaddr addr, uint32_t val) update_jazz_irq(s); break; default: - RC4030_ERROR("(jazz io controller) invalid write of 0x%04x at [" TARGET_FMT_plx "]\n", val, addr); + qemu_log_mask(LOG_GUEST_ERROR, + "rc4030/jazzio: invalid write of 0x%02x at 0x%x", + val, (int)addr); break; } } -static void jazzio_writeb(void *opaque, hwaddr addr, uint32_t val) -{ - uint32_t old_val = jazzio_readw(opaque, addr & ~0x1); - - switch (addr & 1) { - case 0: - val = val | (old_val & 0xff00); - break; - case 1: - val = (val << 8) | (old_val & 0x00ff); - break; - } - jazzio_writew(opaque, addr & ~0x1, val); -} - -static void jazzio_writel(void *opaque, hwaddr addr, uint32_t val) -{ - jazzio_writew(opaque, addr, val & 0xffff); - jazzio_writew(opaque, addr + 2, (val >> 16) & 0xffff); -} - static const MemoryRegionOps jazzio_ops = { - .old_mmio = { - .read = { jazzio_readb, jazzio_readw, jazzio_readl, }, - .write = { jazzio_writeb, jazzio_writew, jazzio_writel, }, - }, + .read = jazzio_read, + .write = jazzio_write, + .impl.min_access_size = 2, + .impl.max_access_size = 2, .endianness = DEVICE_NATIVE_ENDIAN, }; -static void rc4030_reset(void *opaque) +static void rc4030_reset(DeviceState *dev) { - rc4030State *s = opaque; + rc4030State *s = RC4030(dev); int i; s->config = 0x410; /* some boards seem to accept 0x104 too */ @@ -590,14 +594,14 @@ static void rc4030_reset(void *opaque) s->invalid_address_register = 0; memset(s->dma_regs, 0, sizeof(s->dma_regs)); - s->dma_tl_base = s->dma_tl_limit = 0; + rc4030_dma_tt_update(s, 0, 0); s->remote_failed_address = s->memory_failed_address = 0; s->cache_maint = 0; s->cache_ptag = s->cache_ltag = 0; s->cache_bmask = 0; - s->offset210 = 0x18186; + s->memory_refresh_rate = 0x18186; s->nvram_protect = 7; for (i = 0; i < 15; i++) s->rem_speed[i] = 7; @@ -631,7 +635,7 @@ static int rc4030_load(QEMUFile *f, void *opaque, int version_id) s->cache_ptag = qemu_get_be32(f); s->cache_ltag = qemu_get_be32(f); s->cache_bmask = qemu_get_be32(f); - s->offset210 = qemu_get_be32(f); + s->memory_refresh_rate = qemu_get_be32(f); s->nvram_protect = qemu_get_be32(f); for (i = 0; i < 15; i++) s->rem_speed[i] = qemu_get_be32(f); @@ -663,7 +667,7 @@ static void rc4030_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->cache_ptag); qemu_put_be32(f, s->cache_ltag); qemu_put_be32(f, s->cache_bmask); - qemu_put_be32(f, s->offset210); + qemu_put_be32(f, s->memory_refresh_rate); qemu_put_be32(f, s->nvram_protect); for (i = 0; i < 15; i++) qemu_put_be32(f, s->rem_speed[i]); @@ -672,44 +676,6 @@ static void rc4030_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->itr); } -void rc4030_dma_memory_rw(void *opaque, hwaddr addr, uint8_t *buf, int len, int is_write) -{ - rc4030State *s = opaque; - hwaddr entry_addr; - hwaddr phys_addr; - dma_pagetable_entry entry; - int index; - int ncpy, i; - - i = 0; - for (;;) { - if (i == len) { - break; - } - - ncpy = DMA_PAGESIZE - (addr & (DMA_PAGESIZE - 1)); - if (ncpy > len - i) - ncpy = len - i; - - /* Get DMA translation table entry */ - index = addr / DMA_PAGESIZE; - if (index >= s->dma_tl_limit / sizeof(dma_pagetable_entry)) { - break; - } - entry_addr = s->dma_tl_base + index * sizeof(dma_pagetable_entry); - /* XXX: not sure. should we really use only lowest bits? */ - entry_addr &= 0x7fffffff; - cpu_physical_memory_read(entry_addr, &entry, sizeof(entry)); - - /* Read/write data at right place */ - phys_addr = entry.frame + (addr & (DMA_PAGESIZE - 1)); - cpu_physical_memory_rw(phys_addr, &buf[i], ncpy, is_write); - - i += ncpy; - addr += ncpy; - } -} - static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_write) { rc4030State *s = opaque; @@ -733,32 +699,11 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_wri dma_addr = s->dma_regs[n][DMA_REG_ADDRESS]; /* Read/write data at right place */ - rc4030_dma_memory_rw(opaque, dma_addr, buf, len, is_write); + address_space_rw(&s->dma_as, dma_addr, MEMTXATTRS_UNSPECIFIED, + buf, len, is_write); s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_TC_INTR; s->dma_regs[n][DMA_REG_COUNT] -= len; - -#ifdef DEBUG_RC4030_DMA - { - int i, j; - printf("rc4030 dma: Copying %d bytes %s host %p\n", - len, is_write ? "from" : "to", buf); - for (i = 0; i < len; i += 16) { - int n = 16; - if (n > len - i) { - n = len - i; - } - for (j = 0; j < n; j++) - printf("%02x ", buf[i + j]); - while (j++ < 16) - printf(" "); - printf("| "); - for (j = 0; j < n; j++) - printf("%c", isprint(buf[i + j]) ? buf[i + j] : '.'); - printf("\n"); - } - } -#endif } struct rc4030DMAState { @@ -795,31 +740,102 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n) return s; } -void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, - qemu_irq **irqs, rc4030_dma **dmas, - MemoryRegion *sysmem) +static void rc4030_initfn(Object *obj) { - rc4030State *s; + DeviceState *dev = DEVICE(obj); + rc4030State *s = RC4030(obj); + SysBusDevice *sysbus = SYS_BUS_DEVICE(obj); - s = g_malloc0(sizeof(rc4030State)); + qdev_init_gpio_in(dev, rc4030_irq_jazz_request, 16); - *irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16); - *dmas = rc4030_allocate_dmas(s, 4); + sysbus_init_irq(sysbus, &s->timer_irq); + sysbus_init_irq(sysbus, &s->jazz_bus_irq); - s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rc4030_periodic_timer, s); - s->timer_irq = timer; - s->jazz_bus_irq = jazz_bus; - - qemu_register_reset(rc4030_reset, s); register_savevm(NULL, "rc4030", 0, 2, rc4030_save, rc4030_load, s); - rc4030_reset(s); + + sysbus_init_mmio(sysbus, &s->iomem_chipset); + sysbus_init_mmio(sysbus, &s->iomem_jazzio); +} + +static void rc4030_realize(DeviceState *dev, Error **errp) +{ + rc4030State *s = RC4030(dev); + Object *o = OBJECT(dev); + int i; + + s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + rc4030_periodic_timer, s); memory_region_init_io(&s->iomem_chipset, NULL, &rc4030_ops, s, "rc4030.chipset", 0x300); - memory_region_add_subregion(sysmem, 0x80000000, &s->iomem_chipset); memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s, "rc4030.jazzio", 0x00001000); - memory_region_add_subregion(sysmem, 0xf0000000, &s->iomem_jazzio); - return s; + memory_region_init_rom_device(&s->dma_tt, o, + &rc4030_dma_tt_ops, s, "dma-table", + MAX_TL_ENTRIES * sizeof(dma_pagetable_entry), + NULL); + memory_region_init(&s->dma_tt_alias, o, "dma-table-alias", 0); + memory_region_init(&s->dma_mr, o, "dma", INT32_MAX); + for (i = 0; i < MAX_TL_ENTRIES; ++i) { + memory_region_init_alias(&s->dma_mrs[i], o, "dma-alias", + get_system_memory(), 0, DMA_PAGESIZE); + memory_region_set_enabled(&s->dma_mrs[i], false); + memory_region_add_subregion(&s->dma_mr, i * DMA_PAGESIZE, + &s->dma_mrs[i]); + } + address_space_init(&s->dma_as, &s->dma_mr, "rc4030-dma"); +} + +static void rc4030_unrealize(DeviceState *dev, Error **errp) +{ + rc4030State *s = RC4030(dev); + int i; + + timer_free(s->periodic_timer); + + address_space_destroy(&s->dma_as); + object_unparent(OBJECT(&s->dma_tt)); + object_unparent(OBJECT(&s->dma_tt_alias)); + object_unparent(OBJECT(&s->dma_mr)); + for (i = 0; i < MAX_TL_ENTRIES; ++i) { + memory_region_del_subregion(&s->dma_mr, &s->dma_mrs[i]); + object_unparent(OBJECT(&s->dma_mrs[i])); + } +} + +static void rc4030_class_init(ObjectClass *klass, void *class_data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = rc4030_realize; + dc->unrealize = rc4030_unrealize; + dc->reset = rc4030_reset; +} + +static const TypeInfo rc4030_info = { + .name = TYPE_RC4030, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(rc4030State), + .instance_init = rc4030_initfn, + .class_init = rc4030_class_init, +}; + +static void rc4030_register_types(void) +{ + type_register_static(&rc4030_info); +} + +type_init(rc4030_register_types) + +DeviceState *rc4030_init(rc4030_dma **dmas, MemoryRegion **dma_mr) +{ + DeviceState *dev; + + dev = qdev_create(NULL, TYPE_RC4030); + qdev_init_nofail(dev); + + *dmas = rc4030_allocate_dmas(dev, 4); + *dma_mr = &RC4030(dev)->dma_mr; + return dev; } diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 5253e6d4fa..e142f75649 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -52,6 +52,7 @@ #ifdef CONFIG_XEN # include <xen/hvm/hvm_info_table.h> #endif +#include "migration/migration.h" #define MAX_IDE_BUS 2 @@ -305,6 +306,7 @@ static void pc_init1(MachineState *machine) static void pc_compat_2_3(MachineState *machine) { + savevm_skip_section_footers(); } static void pc_compat_2_2(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 110dfb78a8..b68263d231 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -45,6 +45,7 @@ #include "hw/usb.h" #include "hw/cpu/icc_bus.h" #include "qemu/error-report.h" +#include "migration/migration.h" /* ICH9 AHCI has 6 ports */ #define MAX_SATA_PORTS 6 @@ -289,6 +290,7 @@ static void pc_q35_init(MachineState *machine) static void pc_compat_2_3(MachineState *machine) { + savevm_skip_section_footers(); } static void pc_compat_2_2(MachineState *machine) diff --git a/hw/ide/core.c b/hw/ide/core.c index fcb908061c..1efd98af63 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2561,6 +2561,7 @@ static const VMStateDescription vmstate_ide_atapi_gesn_state = { .name ="ide_drive/atapi/gesn_state", .version_id = 1, .minimum_version_id = 1, + .needed = ide_atapi_gesn_needed, .fields = (VMStateField[]) { VMSTATE_BOOL(events.new_media, IDEState), VMSTATE_BOOL(events.eject_request, IDEState), @@ -2572,6 +2573,7 @@ static const VMStateDescription vmstate_ide_tray_state = { .name = "ide_drive/tray_state", .version_id = 1, .minimum_version_id = 1, + .needed = ide_tray_state_needed, .fields = (VMStateField[]) { VMSTATE_BOOL(tray_open, IDEState), VMSTATE_BOOL(tray_locked, IDEState), @@ -2585,6 +2587,7 @@ static const VMStateDescription vmstate_ide_drive_pio_state = { .minimum_version_id = 1, .pre_save = ide_drive_pio_pre_save, .post_load = ide_drive_pio_post_load, + .needed = ide_drive_pio_state_needed, .fields = (VMStateField[]) { VMSTATE_INT32(req_nb_sectors, IDEState), VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1, @@ -2626,19 +2629,11 @@ const VMStateDescription vmstate_ide_drive = { VMSTATE_UINT8_V(cdrom_changed, IDEState, 3), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_ide_drive_pio_state, - .needed = ide_drive_pio_state_needed, - }, { - .vmsd = &vmstate_ide_tray_state, - .needed = ide_tray_state_needed, - }, { - .vmsd = &vmstate_ide_atapi_gesn_state, - .needed = ide_atapi_gesn_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_ide_drive_pio_state, + &vmstate_ide_tray_state, + &vmstate_ide_atapi_gesn_state, + NULL } }; @@ -2646,6 +2641,7 @@ static const VMStateDescription vmstate_ide_error_status = { .name ="ide_bus/error", .version_id = 2, .minimum_version_id = 1, + .needed = ide_error_needed, .fields = (VMStateField[]) { VMSTATE_INT32(error_status, IDEBus), VMSTATE_INT64_V(retry_sector_num, IDEBus, 2), @@ -2664,13 +2660,9 @@ const VMStateDescription vmstate_ide_bus = { VMSTATE_UINT8(unit, IDEBus), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_ide_error_status, - .needed = ide_error_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_ide_error_status, + NULL } }; diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 4b5e32dcbe..4afd0cfe8c 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -350,6 +350,7 @@ static const VMStateDescription vmstate_bmdma_current = { .name = "ide bmdma_current", .version_id = 1, .minimum_version_id = 1, + .needed = ide_bmdma_current_needed, .fields = (VMStateField[]) { VMSTATE_UINT32(cur_addr, BMDMAState), VMSTATE_UINT32(cur_prd_last, BMDMAState), @@ -363,6 +364,7 @@ static const VMStateDescription vmstate_bmdma_status = { .name ="ide bmdma/status", .version_id = 1, .minimum_version_id = 1, + .needed = ide_bmdma_status_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(status, BMDMAState), VMSTATE_END_OF_LIST() @@ -383,16 +385,10 @@ static const VMStateDescription vmstate_bmdma = { VMSTATE_UINT8(migration_retry_unit, BMDMAState), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_bmdma_current, - .needed = ide_bmdma_current_needed, - }, { - .vmsd = &vmstate_bmdma_status, - .needed = ide_bmdma_status_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_bmdma_current, + &vmstate_bmdma_status, + NULL } }; diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 9b9a7d7a8a..ddac69df6f 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -391,23 +391,24 @@ static int kbd_outport_post_load(void *opaque, int version_id) return 0; } +static bool kbd_outport_needed(void *opaque) +{ + KBDState *s = opaque; + return s->outport != kbd_outport_default(s); +} + static const VMStateDescription vmstate_kbd_outport = { .name = "pckbd_outport", .version_id = 1, .minimum_version_id = 1, .post_load = kbd_outport_post_load, + .needed = kbd_outport_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(outport, KBDState), VMSTATE_END_OF_LIST() } }; -static bool kbd_outport_needed(void *opaque) -{ - KBDState *s = opaque; - return s->outport != kbd_outport_default(s); -} - static int kbd_post_load(void *opaque, int version_id) { KBDState *s = opaque; @@ -430,12 +431,9 @@ static const VMStateDescription vmstate_kbd = { VMSTATE_UINT8(pending, KBDState), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_kbd_outport, - .needed = kbd_outport_needed, - }, - VMSTATE_END_OF_LIST() + .subsections = (const VMStateDescription*[]) { + &vmstate_kbd_outport, + NULL } }; diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 4baeea2b56..fdbe565e62 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -677,6 +677,7 @@ static const VMStateDescription vmstate_ps2_keyboard_ledstate = { .version_id = 3, .minimum_version_id = 2, .post_load = ps2_kbd_ledstate_post_load, + .needed = ps2_keyboard_ledstate_needed, .fields = (VMStateField[]) { VMSTATE_INT32(ledstate, PS2KbdState), VMSTATE_END_OF_LIST() @@ -717,13 +718,9 @@ static const VMStateDescription vmstate_ps2_keyboard = { VMSTATE_INT32_V(scancode_set, PS2KbdState,3), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_ps2_keyboard_ledstate, - .needed = ps2_keyboard_ledstate_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_ps2_keyboard_ledstate, + NULL } }; diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index d595d63a51..0032b97c5f 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -369,6 +369,7 @@ static const VMStateDescription vmstate_apic_common_sipi = { .name = "apic_sipi", .version_id = 1, .minimum_version_id = 1, + .needed = apic_common_sipi_needed, .fields = (VMStateField[]) { VMSTATE_INT32(sipi_vector, APICCommonState), VMSTATE_INT32(wait_for_sipi, APICCommonState), @@ -408,12 +409,9 @@ static const VMStateDescription vmstate_apic_common = { APICCommonState), /* open-coded timer state */ VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_apic_common_sipi, - .needed = apic_common_sipi_needed, - }, - VMSTATE_END_OF_LIST() + .subsections = (const VMStateDescription*[]) { + &vmstate_apic_common_sipi, + NULL } }; diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 71a9f7a716..b3e0b1fd52 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -650,6 +650,7 @@ static const VMStateDescription vmstate_ich9_rst_cnt = { .name = "ICH9LPC/rst_cnt", .version_id = 1, .minimum_version_id = 1, + .needed = ich9_rst_cnt_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(rst_cnt, ICH9LPCState), VMSTATE_END_OF_LIST() @@ -669,12 +670,9 @@ static const VMStateDescription vmstate_ich9_lpc = { VMSTATE_UINT32(sci_level, ICH9LPCState), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_ich9_rst_cnt, - .needed = ich9_rst_cnt_needed - }, - { 0 } + .subsections = (const VMStateDescription*[]) { + &vmstate_ich9_rst_cnt, + NULL } }; diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs index 0a652f8521..9633f3a57d 100644 --- a/hw/mips/Makefile.objs +++ b/hw/mips/Makefile.objs @@ -1,4 +1,5 @@ -obj-y += mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o +obj-y += mips_r4k.o mips_malta.o mips_mipssim.o obj-y += addr.o cputimer.o mips_int.o +obj-$(CONFIG_JAZZ) += mips_jazz.o obj-$(CONFIG_FULONG) += mips_fulong2e.o obj-y += gt64xxx_pci.o diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 2c153e092f..9d60633efb 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -135,16 +135,16 @@ static void mips_jazz_init(MachineState *machine, MIPSCPU *cpu; CPUClass *cc; CPUMIPSState *env; - qemu_irq *rc4030, *i8259; + qemu_irq *i8259; rc4030_dma *dmas; - void* rc4030_opaque; + MemoryRegion *rc4030_dma_mr; MemoryRegion *isa_mem = g_new(MemoryRegion, 1); MemoryRegion *isa_io = g_new(MemoryRegion, 1); MemoryRegion *rtc = g_new(MemoryRegion, 1); MemoryRegion *i8042 = g_new(MemoryRegion, 1); MemoryRegion *dma_dummy = g_new(MemoryRegion, 1); NICInfo *nd; - DeviceState *dev; + DeviceState *dev, *rc4030; SysBusDevice *sysbus; ISABus *isa_bus; ISADevice *pit; @@ -157,12 +157,7 @@ static void mips_jazz_init(MachineState *machine, /* init CPUs */ if (cpu_model == NULL) { -#ifdef TARGET_MIPS64 cpu_model = "R4000"; -#else - /* FIXME: All wrong, this maybe should be R3000 for the older JAZZs. */ - cpu_model = "24Kf"; -#endif } cpu = cpu_mips_init(cpu_model); if (cpu == NULL) { @@ -218,8 +213,14 @@ static void mips_jazz_init(MachineState *machine, cpu_mips_clock_init(env); /* Chipset */ - rc4030_opaque = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas, - address_space); + rc4030 = rc4030_init(&dmas, &rc4030_dma_mr); + sysbus = SYS_BUS_DEVICE(rc4030); + sysbus_connect_irq(sysbus, 0, env->irq[6]); + sysbus_connect_irq(sysbus, 1, env->irq[3]); + memory_region_add_subregion(address_space, 0x80000000, + sysbus_mmio_get_region(sysbus, 0)); + memory_region_add_subregion(address_space, 0xf0000000, + sysbus_mmio_get_region(sysbus, 1)); memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000); memory_region_add_subregion(address_space, 0x8000d000, dma_dummy); @@ -246,7 +247,7 @@ static void mips_jazz_init(MachineState *machine, sysbus = SYS_BUS_DEVICE(dev); sysbus_mmio_map(sysbus, 0, 0x60080000); sysbus_mmio_map(sysbus, 1, 0x40000000); - sysbus_connect_irq(sysbus, 0, rc4030[3]); + sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 3)); { /* Simple ROM, so user doesn't have to provide one */ MemoryRegion *rom_mr = g_new(MemoryRegion, 1); @@ -272,8 +273,17 @@ static void mips_jazz_init(MachineState *machine, if (!nd->model) nd->model = g_strdup("dp83932"); if (strcmp(nd->model, "dp83932") == 0) { - dp83932_init(nd, 0x80001000, 2, get_system_memory(), rc4030[4], - rc4030_opaque, rc4030_dma_memory_rw); + qemu_check_nic_model(nd, "dp83932"); + + dev = qdev_create(NULL, "dp8393x"); + qdev_set_nic_properties(dev, nd); + qdev_prop_set_uint8(dev, "it_shift", 2); + qdev_prop_set_ptr(dev, "dma_mr", rc4030_dma_mr); + qdev_init_nofail(dev); + sysbus = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(sysbus, 0, 0x80001000); + sysbus_mmio_map(sysbus, 1, 0x8000b000); + sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 4)); break; } else if (is_help_option(nd->model)) { fprintf(stderr, "qemu: Supported NICs: dp83932\n"); @@ -287,7 +297,7 @@ static void mips_jazz_init(MachineState *machine, /* SCSI adapter */ esp_init(0x80002000, 0, rc4030_dma_read, rc4030_dma_write, dmas[0], - rc4030[5], &esp_reset, &dma_enable); + qdev_get_gpio_in(rc4030, 5), &esp_reset, &dma_enable); /* Floppy */ if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) { @@ -297,7 +307,7 @@ static void mips_jazz_init(MachineState *machine, for (n = 0; n < MAX_FD; n++) { fds[n] = drive_get(IF_FLOPPY, 0, n); } - fdctrl_init_sysbus(rc4030[1], 0, 0x80003000, fds); + fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), 0, 0x80003000, fds); /* Real time clock */ rtc_init(isa_bus, 1980, NULL); @@ -305,23 +315,26 @@ static void mips_jazz_init(MachineState *machine, memory_region_add_subregion(address_space, 0x80004000, rtc); /* Keyboard (i8042) */ - i8042_mm_init(rc4030[6], rc4030[7], i8042, 0x1000, 0x1); + i8042_mm_init(qdev_get_gpio_in(rc4030, 6), qdev_get_gpio_in(rc4030, 7), + i8042, 0x1000, 0x1); memory_region_add_subregion(address_space, 0x80005000, i8042); /* Serial ports */ if (serial_hds[0]) { - serial_mm_init(address_space, 0x80006000, 0, rc4030[8], 8000000/16, + serial_mm_init(address_space, 0x80006000, 0, + qdev_get_gpio_in(rc4030, 8), 8000000/16, serial_hds[0], DEVICE_NATIVE_ENDIAN); } if (serial_hds[1]) { - serial_mm_init(address_space, 0x80007000, 0, rc4030[9], 8000000/16, + serial_mm_init(address_space, 0x80007000, 0, + qdev_get_gpio_in(rc4030, 9), 8000000/16, serial_hds[1], DEVICE_NATIVE_ENDIAN); } /* Parallel port */ if (parallel_hds[0]) - parallel_mm_init(address_space, 0x80008000, 0, rc4030[0], - parallel_hds[0]); + parallel_mm_init(address_space, 0x80008000, 0, + qdev_get_gpio_in(rc4030, 0), parallel_hds[0]); /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */ diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 5140882c00..786a8f0638 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -97,7 +97,7 @@ typedef struct { static ISADevice *pit; static struct _loaderparams { - int ram_size; + int ram_size, ram_low_size; const char *kernel_filename; const char *kernel_cmdline; const char *initrd_filename; @@ -641,8 +641,8 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, stl_p(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */ stl_p(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */ stl_p(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */ - stl_p(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(ram_size) */ - stl_p(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(ram_size) */ + stl_p(p++, 0x3c070000 | (loaderparams.ram_low_size >> 16)); /* lui a3, high(ram_low_size) */ + stl_p(p++, 0x34e70000 | (loaderparams.ram_low_size & 0xffff)); /* ori a3, a3, low(ram_low_size) */ /* Load BAR registers as done by YAMON */ stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */ @@ -851,8 +851,10 @@ static int64_t load_kernel (void) } prom_set(prom_buf, prom_index++, "memsize"); - prom_set(prom_buf, prom_index++, "%i", - MIN(loaderparams.ram_size, 256 << 20)); + prom_set(prom_buf, prom_index++, "%u", loaderparams.ram_low_size); + + prom_set(prom_buf, prom_index++, "ememsize"); + prom_set(prom_buf, prom_index++, "%u", loaderparams.ram_size); prom_set(prom_buf, prom_index++, "modetty0"); prom_set(prom_buf, prom_index++, "38400n8r"); @@ -1054,7 +1056,8 @@ void mips_malta_init(MachineState *machine) } /* Write a small bootloader to the flash location. */ - loaderparams.ram_size = ram_low_size; + loaderparams.ram_size = ram_size; + loaderparams.ram_low_size = ram_low_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index 7ce13d2b46..cd889bce86 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -17,20 +17,15 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include "hw/hw.h" -#include "qemu/timer.h" +#include "hw/sysbus.h" +#include "hw/devices.h" #include "net/net.h" -#include "hw/mips/mips.h" +#include "qemu/timer.h" +#include <zlib.h> //#define DEBUG_SONIC -/* Calculate CRCs properly on Rx packets */ -#define SONIC_CALCULATE_RXCRC - -#if defined(SONIC_CALCULATE_RXCRC) -/* For crc32 */ -#include <zlib.h> -#endif +#define SONIC_PROM_SIZE 0x1000 #ifdef DEBUG_SONIC #define DPRINTF(fmt, ...) \ @@ -145,9 +140,14 @@ do { printf("sonic ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0) #define SONIC_ISR_PINT 0x0800 #define SONIC_ISR_LCD 0x1000 +#define TYPE_DP8393X "dp8393x" +#define DP8393X(obj) OBJECT_CHECK(dp8393xState, (obj), TYPE_DP8393X) + typedef struct dp8393xState { + SysBusDevice parent_obj; + /* Hardware */ - int it_shift; + uint8_t it_shift; qemu_irq irq; #ifdef DEBUG_SONIC int irq_level; @@ -156,8 +156,8 @@ typedef struct dp8393xState { int64_t wt_last_update; NICConf conf; NICState *nic; - MemoryRegion *address_space; MemoryRegion mmio; + MemoryRegion prom; /* Registers */ uint8_t cam[16][6]; @@ -168,8 +168,8 @@ typedef struct dp8393xState { int loopback_packet; /* Memory access */ - void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf, int len, int is_write); - void* mem_opaque; + void *dma_mr; + AddressSpace as; } dp8393xState; static void dp8393x_update_irq(dp8393xState *s) @@ -190,7 +190,7 @@ static void dp8393x_update_irq(dp8393xState *s) qemu_set_irq(s->irq, level); } -static void do_load_cam(dp8393xState *s) +static void dp8393x_do_load_cam(dp8393xState *s) { uint16_t data[8]; int width, size; @@ -201,9 +201,9 @@ static void do_load_cam(dp8393xState *s) while (s->regs[SONIC_CDC] & 0x1f) { /* Fill current entry */ - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP], - (uint8_t *)data, size, 0); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0); s->cam[index][0] = data[1 * width] & 0xff; s->cam[index][1] = data[1 * width] >> 8; s->cam[index][2] = data[2 * width] & 0xff; @@ -220,9 +220,9 @@ static void do_load_cam(dp8393xState *s) } /* Read CAM enable */ - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP], - (uint8_t *)data, size, 0); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0); s->regs[SONIC_CE] = data[0 * width]; DPRINTF("load cam done. cam enable mask 0x%04x\n", s->regs[SONIC_CE]); @@ -232,7 +232,7 @@ static void do_load_cam(dp8393xState *s) dp8393x_update_irq(s); } -static void do_read_rra(dp8393xState *s) +static void dp8393x_do_read_rra(dp8393xState *s) { uint16_t data[8]; int width, size; @@ -240,9 +240,9 @@ static void do_read_rra(dp8393xState *s) /* Read memory */ width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1; size = sizeof(uint16_t) * 4 * width; - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_RRP], - (uint8_t *)data, size, 0); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0); /* Update SONIC registers */ s->regs[SONIC_CRBA0] = data[0 * width]; @@ -272,7 +272,7 @@ static void do_read_rra(dp8393xState *s) s->regs[SONIC_CR] &= ~SONIC_CR_RRRA; } -static void do_software_reset(dp8393xState *s) +static void dp8393x_do_software_reset(dp8393xState *s) { timer_del(s->watchdog); @@ -280,7 +280,7 @@ static void do_software_reset(dp8393xState *s) s->regs[SONIC_CR] |= SONIC_CR_RST | SONIC_CR_RXDIS; } -static void set_next_tick(dp8393xState *s) +static void dp8393x_set_next_tick(dp8393xState *s) { uint32_t ticks; int64_t delay; @@ -296,7 +296,7 @@ static void set_next_tick(dp8393xState *s) timer_mod(s->watchdog, s->wt_last_update + delay); } -static void update_wt_regs(dp8393xState *s) +static void dp8393x_update_wt_regs(dp8393xState *s) { int64_t elapsed; uint32_t val; @@ -311,33 +311,33 @@ static void update_wt_regs(dp8393xState *s) val -= elapsed / 5000000; s->regs[SONIC_WT1] = (val >> 16) & 0xffff; s->regs[SONIC_WT0] = (val >> 0) & 0xffff; - set_next_tick(s); + dp8393x_set_next_tick(s); } -static void do_start_timer(dp8393xState *s) +static void dp8393x_do_start_timer(dp8393xState *s) { s->regs[SONIC_CR] &= ~SONIC_CR_STP; - set_next_tick(s); + dp8393x_set_next_tick(s); } -static void do_stop_timer(dp8393xState *s) +static void dp8393x_do_stop_timer(dp8393xState *s) { s->regs[SONIC_CR] &= ~SONIC_CR_ST; - update_wt_regs(s); + dp8393x_update_wt_regs(s); } -static void do_receiver_enable(dp8393xState *s) +static void dp8393x_do_receiver_enable(dp8393xState *s) { s->regs[SONIC_CR] &= ~SONIC_CR_RXDIS; } -static void do_receiver_disable(dp8393xState *s) +static void dp8393x_do_receiver_disable(dp8393xState *s) { s->regs[SONIC_CR] &= ~SONIC_CR_RXEN; } -static void do_transmit_packets(dp8393xState *s) +static void dp8393x_do_transmit_packets(dp8393xState *s) { NetClientState *nc = qemu_get_queue(s->nic); uint16_t data[12]; @@ -353,9 +353,9 @@ static void do_transmit_packets(dp8393xState *s) (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_CTDA]); size = sizeof(uint16_t) * 6 * width; s->regs[SONIC_TTDA] = s->regs[SONIC_CTDA]; - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, ((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) + sizeof(uint16_t) * width, - (uint8_t *)data, size, 0); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0); tx_len = 0; /* Update registers */ @@ -379,18 +379,18 @@ static void do_transmit_packets(dp8393xState *s) if (tx_len + len > sizeof(s->tx_buffer)) { len = sizeof(s->tx_buffer) - tx_len; } - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, (s->regs[SONIC_TSA1] << 16) | s->regs[SONIC_TSA0], - &s->tx_buffer[tx_len], len, 0); + MEMTXATTRS_UNSPECIFIED, &s->tx_buffer[tx_len], len, 0); tx_len += len; i++; if (i != s->regs[SONIC_TFC]) { /* Read next fragment details */ size = sizeof(uint16_t) * 3 * width; - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, ((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) + sizeof(uint16_t) * (4 + 3 * i) * width, - (uint8_t *)data, size, 0); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0); s->regs[SONIC_TSA0] = data[0 * width]; s->regs[SONIC_TSA1] = data[1 * width]; s->regs[SONIC_TFS] = data[2 * width]; @@ -422,16 +422,16 @@ static void do_transmit_packets(dp8393xState *s) /* Write status */ data[0 * width] = s->regs[SONIC_TCR] & 0x0fff; /* status */ size = sizeof(uint16_t) * width; - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA], - (uint8_t *)data, size, 1); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 1); if (!(s->regs[SONIC_CR] & SONIC_CR_HTX)) { /* Read footer of packet */ size = sizeof(uint16_t) * width; - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, ((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) + sizeof(uint16_t) * (4 + 3 * s->regs[SONIC_TFC]) * width, - (uint8_t *)data, size, 0); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0); s->regs[SONIC_CTDA] = data[0 * width] & ~0x1; if (data[0 * width] & 0x1) { /* EOL detected */ @@ -446,12 +446,12 @@ static void do_transmit_packets(dp8393xState *s) dp8393x_update_irq(s); } -static void do_halt_transmission(dp8393xState *s) +static void dp8393x_do_halt_transmission(dp8393xState *s) { /* Nothing to do */ } -static void do_command(dp8393xState *s, uint16_t command) +static void dp8393x_do_command(dp8393xState *s, uint16_t command) { if ((s->regs[SONIC_CR] & SONIC_CR_RST) && !(command & SONIC_CR_RST)) { s->regs[SONIC_CR] &= ~SONIC_CR_RST; @@ -461,34 +461,36 @@ static void do_command(dp8393xState *s, uint16_t command) s->regs[SONIC_CR] |= (command & SONIC_CR_MASK); if (command & SONIC_CR_HTX) - do_halt_transmission(s); + dp8393x_do_halt_transmission(s); if (command & SONIC_CR_TXP) - do_transmit_packets(s); + dp8393x_do_transmit_packets(s); if (command & SONIC_CR_RXDIS) - do_receiver_disable(s); + dp8393x_do_receiver_disable(s); if (command & SONIC_CR_RXEN) - do_receiver_enable(s); + dp8393x_do_receiver_enable(s); if (command & SONIC_CR_STP) - do_stop_timer(s); + dp8393x_do_stop_timer(s); if (command & SONIC_CR_ST) - do_start_timer(s); + dp8393x_do_start_timer(s); if (command & SONIC_CR_RST) - do_software_reset(s); + dp8393x_do_software_reset(s); if (command & SONIC_CR_RRRA) - do_read_rra(s); + dp8393x_do_read_rra(s); if (command & SONIC_CR_LCAM) - do_load_cam(s); + dp8393x_do_load_cam(s); } -static uint16_t read_register(dp8393xState *s, int reg) +static uint64_t dp8393x_read(void *opaque, hwaddr addr, unsigned int size) { + dp8393xState *s = opaque; + int reg = addr >> s->it_shift; uint16_t val = 0; switch (reg) { /* Update data before reading it */ case SONIC_WT0: case SONIC_WT1: - update_wt_regs(s); + dp8393x_update_wt_regs(s); val = s->regs[reg]; break; /* Accept read to some registers only when in reset mode */ @@ -510,14 +512,18 @@ static uint16_t read_register(dp8393xState *s, int reg) return val; } -static void write_register(dp8393xState *s, int reg, uint16_t val) +static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) { - DPRINTF("write 0x%04x to reg %s\n", val, reg_names[reg]); + dp8393xState *s = opaque; + int reg = addr >> s->it_shift; + + DPRINTF("write 0x%04x to reg %s\n", (uint16_t)data, reg_names[reg]); switch (reg) { /* Command register */ case SONIC_CR: - do_command(s, val); + dp8393x_do_command(s, data); break; /* Prevent write to read-only registers */ case SONIC_CAP2: @@ -530,37 +536,37 @@ static void write_register(dp8393xState *s, int reg, uint16_t val) /* Accept write to some registers only when in reset mode */ case SONIC_DCR: if (s->regs[SONIC_CR] & SONIC_CR_RST) { - s->regs[reg] = val & 0xbfff; + s->regs[reg] = data & 0xbfff; } else { DPRINTF("writing to DCR invalid\n"); } break; case SONIC_DCR2: if (s->regs[SONIC_CR] & SONIC_CR_RST) { - s->regs[reg] = val & 0xf017; + s->regs[reg] = data & 0xf017; } else { DPRINTF("writing to DCR2 invalid\n"); } break; /* 12 lower bytes are Read Only */ case SONIC_TCR: - s->regs[reg] = val & 0xf000; + s->regs[reg] = data & 0xf000; break; /* 9 lower bytes are Read Only */ case SONIC_RCR: - s->regs[reg] = val & 0xffe0; + s->regs[reg] = data & 0xffe0; break; /* Ignore most significant bit */ case SONIC_IMR: - s->regs[reg] = val & 0x7fff; + s->regs[reg] = data & 0x7fff; dp8393x_update_irq(s); break; /* Clear bits by writing 1 to them */ case SONIC_ISR: - val &= s->regs[reg]; - s->regs[reg] &= ~val; - if (val & SONIC_ISR_RBE) { - do_read_rra(s); + data &= s->regs[reg]; + s->regs[reg] &= ~data; + if (data & SONIC_ISR_RBE) { + dp8393x_do_read_rra(s); } dp8393x_update_irq(s); break; @@ -569,24 +575,32 @@ static void write_register(dp8393xState *s, int reg, uint16_t val) case SONIC_REA: case SONIC_RRP: case SONIC_RWP: - s->regs[reg] = val & 0xfffe; + s->regs[reg] = data & 0xfffe; break; /* Invert written value for some registers */ case SONIC_CRCT: case SONIC_FAET: case SONIC_MPT: - s->regs[reg] = val ^ 0xffff; + s->regs[reg] = data ^ 0xffff; break; /* All other registers have no special contrainst */ default: - s->regs[reg] = val; + s->regs[reg] = data; } if (reg == SONIC_WT0 || reg == SONIC_WT1) { - set_next_tick(s); + dp8393x_set_next_tick(s); } } +static const MemoryRegionOps dp8393x_ops = { + .read = dp8393x_read, + .write = dp8393x_write, + .impl.min_access_size = 2, + .impl.max_access_size = 2, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + static void dp8393x_watchdog(void *opaque) { dp8393xState *s = opaque; @@ -597,84 +611,14 @@ static void dp8393x_watchdog(void *opaque) s->regs[SONIC_WT1] = 0xffff; s->regs[SONIC_WT0] = 0xffff; - set_next_tick(s); + dp8393x_set_next_tick(s); /* Signal underflow */ s->regs[SONIC_ISR] |= SONIC_ISR_TC; dp8393x_update_irq(s); } -static uint32_t dp8393x_readw(void *opaque, hwaddr addr) -{ - dp8393xState *s = opaque; - int reg; - - if ((addr & ((1 << s->it_shift) - 1)) != 0) { - return 0; - } - - reg = addr >> s->it_shift; - return read_register(s, reg); -} - -static uint32_t dp8393x_readb(void *opaque, hwaddr addr) -{ - uint16_t v = dp8393x_readw(opaque, addr & ~0x1); - return (v >> (8 * (addr & 0x1))) & 0xff; -} - -static uint32_t dp8393x_readl(void *opaque, hwaddr addr) -{ - uint32_t v; - v = dp8393x_readw(opaque, addr); - v |= dp8393x_readw(opaque, addr + 2) << 16; - return v; -} - -static void dp8393x_writew(void *opaque, hwaddr addr, uint32_t val) -{ - dp8393xState *s = opaque; - int reg; - - if ((addr & ((1 << s->it_shift) - 1)) != 0) { - return; - } - - reg = addr >> s->it_shift; - - write_register(s, reg, (uint16_t)val); -} - -static void dp8393x_writeb(void *opaque, hwaddr addr, uint32_t val) -{ - uint16_t old_val = dp8393x_readw(opaque, addr & ~0x1); - - switch (addr & 3) { - case 0: - val = val | (old_val & 0xff00); - break; - case 1: - val = (val << 8) | (old_val & 0x00ff); - break; - } - dp8393x_writew(opaque, addr & ~0x1, val); -} - -static void dp8393x_writel(void *opaque, hwaddr addr, uint32_t val) -{ - dp8393x_writew(opaque, addr, val & 0xffff); - dp8393x_writew(opaque, addr + 2, (val >> 16) & 0xffff); -} - -static const MemoryRegionOps dp8393x_ops = { - .old_mmio = { - .read = { dp8393x_readb, dp8393x_readw, dp8393x_readl, }, - .write = { dp8393x_writeb, dp8393x_writew, dp8393x_writel, }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int nic_can_receive(NetClientState *nc) +static int dp8393x_can_receive(NetClientState *nc) { dp8393xState *s = qemu_get_nic_opaque(nc); @@ -685,7 +629,8 @@ static int nic_can_receive(NetClientState *nc) return 1; } -static int receive_filter(dp8393xState *s, const uint8_t * buf, int size) +static int dp8393x_receive_filter(dp8393xState *s, const uint8_t * buf, + int size) { static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; int i; @@ -723,7 +668,8 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size) return -1; } -static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) +static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf, + size_t size) { dp8393xState *s = qemu_get_nic_opaque(nc); uint16_t data[10]; @@ -737,7 +683,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) s->regs[SONIC_RCR] &= ~(SONIC_RCR_PRX | SONIC_RCR_LBK | SONIC_RCR_FAER | SONIC_RCR_CRCR | SONIC_RCR_LPKT | SONIC_RCR_BC | SONIC_RCR_MC); - packet_type = receive_filter(s, buf, size); + packet_type = dp8393x_receive_filter(s, buf, size); if (packet_type < 0) { DPRINTF("packet not for netcard\n"); return -1; @@ -750,7 +696,8 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) /* Are we still in resource exhaustion? */ size = sizeof(uint16_t) * 1 * width; address = ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 5 * width; - s->memory_rw(s->mem_opaque, address, (uint8_t*)data, size, 0); + address_space_rw(&s->as, address, MEMTXATTRS_UNSPECIFIED, + (uint8_t *)data, size, 0); if (data[0 * width] & 0x1) { /* Still EOL ; stop reception */ return -1; @@ -764,18 +711,16 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) s->regs[SONIC_TRBA0] = s->regs[SONIC_CRBA0]; /* Calculate the ethernet checksum */ -#ifdef SONIC_CALCULATE_RXCRC checksum = cpu_to_le32(crc32(0, buf, rx_len)); -#else - checksum = 0; -#endif /* Put packet into RBA */ DPRINTF("Receive packet at %08x\n", (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0]); address = (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0]; - s->memory_rw(s->mem_opaque, address, (uint8_t*)buf, rx_len, 1); + address_space_rw(&s->as, address, + MEMTXATTRS_UNSPECIFIED, (uint8_t *)buf, rx_len, 1); address += rx_len; - s->memory_rw(s->mem_opaque, address, (uint8_t*)&checksum, 4, 1); + address_space_rw(&s->as, address, + MEMTXATTRS_UNSPECIFIED, (uint8_t *)&checksum, 4, 1); rx_len += 4; s->regs[SONIC_CRBA1] = address >> 16; s->regs[SONIC_CRBA0] = address & 0xffff; @@ -803,29 +748,30 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) data[3 * width] = s->regs[SONIC_TRBA1]; /* pkt_ptr1 */ data[4 * width] = s->regs[SONIC_RSC]; /* seq_no */ size = sizeof(uint16_t) * 5 * width; - s->memory_rw(s->mem_opaque, (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA], (uint8_t *)data, size, 1); + address_space_rw(&s->as, (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA], + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 1); /* Move to next descriptor */ size = sizeof(uint16_t) * width; - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 5 * width, - (uint8_t *)data, size, 0); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0); s->regs[SONIC_LLFA] = data[0 * width]; if (s->regs[SONIC_LLFA] & 0x1) { /* EOL detected */ s->regs[SONIC_ISR] |= SONIC_ISR_RDE; } else { data[0 * width] = 0; /* in_use */ - s->memory_rw(s->mem_opaque, + address_space_rw(&s->as, ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 6 * width, - (uint8_t *)data, size, 1); + MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, sizeof(uint16_t), 1); s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA]; s->regs[SONIC_ISR] |= SONIC_ISR_PKTRX; s->regs[SONIC_RSC] = (s->regs[SONIC_RSC] & 0xff00) | (((s->regs[SONIC_RSC] & 0x00ff) + 1) & 0x00ff); if (s->regs[SONIC_RCR] & SONIC_RCR_LPKT) { /* Read next RRA */ - do_read_rra(s); + dp8393x_do_read_rra(s); } } @@ -835,11 +781,12 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) return size; } -static void nic_reset(void *opaque) +static void dp8393x_reset(DeviceState *dev) { - dp8393xState *s = opaque; + dp8393xState *s = DP8393X(dev); timer_del(s->watchdog); + memset(s->regs, 0, sizeof(s->regs)); s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS; s->regs[SONIC_DCR] &= ~(SONIC_DCR_EXBUS | SONIC_DCR_LBR); s->regs[SONIC_RCR] &= ~(SONIC_RCR_LB0 | SONIC_RCR_LB1 | SONIC_RCR_BRD | SONIC_RCR_RNT); @@ -862,39 +809,91 @@ static void nic_reset(void *opaque) static NetClientInfo net_dp83932_info = { .type = NET_CLIENT_OPTIONS_KIND_NIC, .size = sizeof(NICState), - .can_receive = nic_can_receive, - .receive = nic_receive, + .can_receive = dp8393x_can_receive, + .receive = dp8393x_receive, }; -void dp83932_init(NICInfo *nd, hwaddr base, int it_shift, - MemoryRegion *address_space, - qemu_irq irq, void* mem_opaque, - void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf, int len, int is_write)) +static void dp8393x_instance_init(Object *obj) { - dp8393xState *s; + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + dp8393xState *s = DP8393X(obj); + + sysbus_init_mmio(sbd, &s->mmio); + sysbus_init_mmio(sbd, &s->prom); + sysbus_init_irq(sbd, &s->irq); +} - qemu_check_nic_model(nd, "dp83932"); +static void dp8393x_realize(DeviceState *dev, Error **errp) +{ + dp8393xState *s = DP8393X(dev); + int i, checksum; + uint8_t *prom; - s = g_malloc0(sizeof(dp8393xState)); + address_space_init(&s->as, s->dma_mr, "dp8393x"); + memory_region_init_io(&s->mmio, OBJECT(dev), &dp8393x_ops, s, + "dp8393x-regs", 0x40 << s->it_shift); + + s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, + object_get_typename(OBJECT(dev)), dev->id, s); + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); - s->address_space = address_space; - s->mem_opaque = mem_opaque; - s->memory_rw = memory_rw; - s->it_shift = it_shift; - s->irq = irq; s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s); s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */ - s->conf.macaddr = nd->macaddr; - s->conf.peers.ncs[0] = nd->netdev; + memory_region_init_rom_device(&s->prom, OBJECT(dev), NULL, NULL, + "dp8393x-prom", SONIC_PROM_SIZE, NULL); + prom = memory_region_get_ram_ptr(&s->prom); + checksum = 0; + for (i = 0; i < 6; i++) { + prom[i] = s->conf.macaddr.a[i]; + checksum += prom[i]; + if (checksum > 0xff) { + checksum = (checksum + 1) & 0xff; + } + } + prom[7] = 0xff - checksum; +} - s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s); +static const VMStateDescription vmstate_dp8393x = { + .name = "dp8393x", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField []) { + VMSTATE_BUFFER_UNSAFE(cam, dp8393xState, 0, 16 * 6), + VMSTATE_UINT16_ARRAY(regs, dp8393xState, 0x40), + VMSTATE_END_OF_LIST() + } +}; - qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); - qemu_register_reset(nic_reset, s); - nic_reset(s); +static Property dp8393x_properties[] = { + DEFINE_NIC_PROPERTIES(dp8393xState, conf), + DEFINE_PROP_PTR("dma_mr", dp8393xState, dma_mr), + DEFINE_PROP_UINT8("it_shift", dp8393xState, it_shift, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void dp8393x_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); - memory_region_init_io(&s->mmio, NULL, &dp8393x_ops, s, - "dp8393x", 0x40 << it_shift); - memory_region_add_subregion(address_space, base, &s->mmio); + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); + dc->realize = dp8393x_realize; + dc->reset = dp8393x_reset; + dc->vmsd = &vmstate_dp8393x; + dc->props = dp8393x_properties; } + +static const TypeInfo dp8393x_info = { + .name = TYPE_DP8393X, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(dp8393xState), + .instance_init = dp8393x_instance_init, + .class_init = dp8393x_class_init, +}; + +static void dp8393x_register_types(void) +{ + type_register_static(&dp8393x_info); +} + +type_init(dp8393x_register_types) diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 091d61acc3..bab8e2abfb 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -1370,6 +1370,7 @@ static const VMStateDescription vmstate_e1000_mit_state = { .name = "e1000/mit_state", .version_id = 1, .minimum_version_id = 1, + .needed = e1000_mit_state_needed, .fields = (VMStateField[]) { VMSTATE_UINT32(mac_reg[RDTR], E1000State), VMSTATE_UINT32(mac_reg[RADV], E1000State), @@ -1457,13 +1458,9 @@ static const VMStateDescription vmstate_e1000 = { VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA, 128), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_e1000_mit_state, - .needed = e1000_mit_state_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_e1000_mit_state, + NULL } }; diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index f868108dfe..e0db4727ae 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -3240,6 +3240,7 @@ static const VMStateDescription vmstate_rtl8139_hotplug_ready ={ .name = "rtl8139/hotplug_ready", .version_id = 1, .minimum_version_id = 1, + .needed = rtl8139_hotplug_ready_needed, .fields = (VMStateField[]) { VMSTATE_END_OF_LIST() } @@ -3335,13 +3336,9 @@ static const VMStateDescription vmstate_rtl8139 = { VMSTATE_UINT32_V(cplus_enabled, RTL8139State, 4), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_rtl8139_hotplug_ready, - .needed = rtl8139_hotplug_ready_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_rtl8139_hotplug_ready, + NULL } }; diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index dfb328debd..8bcdf3ed77 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2226,6 +2226,7 @@ static const VMStateDescription vmxstate_vmxnet3_mcast_list = { .version_id = 1, .minimum_version_id = 1, .pre_load = vmxnet3_mcast_list_pre_load, + .needed = vmxnet3_mc_list_needed, .fields = (VMStateField[]) { VMSTATE_VBUFFER_UINT32(mcast_list, VMXNET3State, 0, NULL, 0, mcast_list_buff_size), @@ -2470,14 +2471,9 @@ static const VMStateDescription vmstate_vmxnet3 = { VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmxstate_vmxnet3_mcast_list, - .needed = vmxnet3_mc_list_needed - }, - { - /* empty element. */ - } + .subsections = (const VMStateDescription*[]) { + &vmxstate_vmxnet3_mcast_list, + NULL } }; diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index f1712b86fe..ed2424c4cd 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -582,6 +582,7 @@ static const VMStateDescription vmstate_piix3_rcr = { .name = "PIIX3/rcr", .version_id = 1, .minimum_version_id = 1, + .needed = piix3_rcr_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(rcr, PIIX3State), VMSTATE_END_OF_LIST() @@ -600,12 +601,9 @@ static const VMStateDescription vmstate_piix3 = { PIIX_NUM_PIRQS, 3), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_piix3_rcr, - .needed = piix3_rcr_needed, - }, - { 0 } + .subsections = (const VMStateDescription*[]) { + &vmstate_piix3_rcr, + NULL } }; diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index bd2c0e4caa..f50b2f08af 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1968,6 +1968,7 @@ static const VMStateDescription vmstate_scsi_sense_state = { .name = "SCSIDevice/sense", .version_id = 1, .minimum_version_id = 1, + .needed = scsi_sense_state_needed, .fields = (VMStateField[]) { VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice, SCSI_SENSE_BUF_SIZE_OLD, @@ -1998,13 +1999,9 @@ const VMStateDescription vmstate_scsi_device = { }, VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_scsi_sense_state, - .needed = scsi_sense_state_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_scsi_sense_state, + NULL } }; diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index 4221060308..5e22ed79b2 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -127,7 +127,7 @@ static void r2d_fpga_irq_set(void *opaque, int n, int level) update_irl(fpga); } -static uint32_t r2d_fpga_read(void *opaque, hwaddr addr) +static uint64_t r2d_fpga_read(void *opaque, hwaddr addr, unsigned int size) { r2d_fpga_t *s = opaque; @@ -146,7 +146,7 @@ static uint32_t r2d_fpga_read(void *opaque, hwaddr addr) } static void -r2d_fpga_write(void *opaque, hwaddr addr, uint32_t value) +r2d_fpga_write(void *opaque, hwaddr addr, uint64_t value, unsigned int size) { r2d_fpga_t *s = opaque; @@ -170,10 +170,10 @@ r2d_fpga_write(void *opaque, hwaddr addr, uint32_t value) } static const MemoryRegionOps r2d_fpga_ops = { - .old_mmio = { - .read = { r2d_fpga_read, r2d_fpga_read, NULL, }, - .write = { r2d_fpga_write, r2d_fpga_write, NULL, }, - }, + .read = r2d_fpga_read, + .write = r2d_fpga_write, + .impl.min_access_size = 2, + .impl.max_access_size = 2, .endianness = DEVICE_NATIVE_ENDIAN, }; diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index b6b8a2063d..b50071ef93 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -283,6 +283,7 @@ static const VMStateDescription vmstate_hpet_rtc_irq_level = { .name = "hpet/rtc_irq_level", .version_id = 1, .minimum_version_id = 1, + .needed = hpet_rtc_irq_level_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(rtc_irq_level, HPETState), VMSTATE_END_OF_LIST() @@ -322,13 +323,9 @@ static const VMStateDescription vmstate_hpet = { vmstate_hpet_timer, HPETTimer), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_hpet_rtc_irq_level, - .needed = hpet_rtc_irq_level_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_hpet_rtc_irq_level, + NULL } }; diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index f2b77fa118..32048258c9 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -733,22 +733,23 @@ static int rtc_post_load(void *opaque, int version_id) return 0; } +static bool rtc_irq_reinject_on_ack_count_needed(void *opaque) +{ + RTCState *s = (RTCState *)opaque; + return s->irq_reinject_on_ack_count != 0; +} + static const VMStateDescription vmstate_rtc_irq_reinject_on_ack_count = { .name = "mc146818rtc/irq_reinject_on_ack_count", .version_id = 1, .minimum_version_id = 1, + .needed = rtc_irq_reinject_on_ack_count_needed, .fields = (VMStateField[]) { VMSTATE_UINT16(irq_reinject_on_ack_count, RTCState), VMSTATE_END_OF_LIST() } }; -static bool rtc_irq_reinject_on_ack_count_needed(void *opaque) -{ - RTCState *s = (RTCState *)opaque; - return s->irq_reinject_on_ack_count != 0; -} - static const VMStateDescription vmstate_rtc = { .name = "mc146818rtc", .version_id = 3, @@ -770,13 +771,9 @@ static const VMStateDescription vmstate_rtc = { VMSTATE_UINT64_V(next_alarm_time, RTCState, 3), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_rtc_irq_reinject_on_ack_count, - .needed = rtc_irq_reinject_on_ack_count_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_rtc_irq_reinject_on_ack_count, + NULL } }; diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 1a22c9c0cb..7d65818064 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -2034,6 +2034,7 @@ static const VMStateDescription vmstate_ohci_eof_timer = { .version_id = 1, .minimum_version_id = 1, .pre_load = ohci_eof_timer_pre_load, + .needed = ohci_eof_timer_needed, .fields = (VMStateField[]) { VMSTATE_TIMER_PTR(eof_timer, OHCIState), VMSTATE_END_OF_LIST() @@ -2081,13 +2082,9 @@ static const VMStateDescription vmstate_ohci_state = { VMSTATE_BOOL(async_complete, OHCIState), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection []) { - { - .vmsd = &vmstate_ohci_eof_timer, - .needed = ohci_eof_timer_needed, - } , { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &vmstate_ohci_eof_timer, + NULL } }; diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 242a654583..6b4218c037 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -2257,40 +2257,42 @@ static const VMStateInfo usbredir_ep_bufpq_vmstate_info = { /* For endp_data migration */ +static bool usbredir_bulk_receiving_needed(void *priv) +{ + struct endp_data *endp = priv; + + return endp->bulk_receiving_started; +} + static const VMStateDescription usbredir_bulk_receiving_vmstate = { .name = "usb-redir-ep/bulk-receiving", .version_id = 1, .minimum_version_id = 1, + .needed = usbredir_bulk_receiving_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(bulk_receiving_started, struct endp_data), VMSTATE_END_OF_LIST() } }; -static bool usbredir_bulk_receiving_needed(void *priv) +static bool usbredir_stream_needed(void *priv) { struct endp_data *endp = priv; - return endp->bulk_receiving_started; + return endp->max_streams; } static const VMStateDescription usbredir_stream_vmstate = { .name = "usb-redir-ep/stream-state", .version_id = 1, .minimum_version_id = 1, + .needed = usbredir_stream_needed, .fields = (VMStateField[]) { VMSTATE_UINT32(max_streams, struct endp_data), VMSTATE_END_OF_LIST() } }; -static bool usbredir_stream_needed(void *priv) -{ - struct endp_data *endp = priv; - - return endp->max_streams; -} - static const VMStateDescription usbredir_ep_vmstate = { .name = "usb-redir-ep", .version_id = 1, @@ -2318,16 +2320,10 @@ static const VMStateDescription usbredir_ep_vmstate = { VMSTATE_INT32(bufpq_target_size, struct endp_data), VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &usbredir_bulk_receiving_vmstate, - .needed = usbredir_bulk_receiving_needed, - }, { - .vmsd = &usbredir_stream_vmstate, - .needed = usbredir_stream_needed, - }, { - /* empty */ - } + .subsections = (const VMStateDescription*[]) { + &usbredir_bulk_receiving_vmstate, + &usbredir_stream_vmstate, + NULL } }; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index fb49ffcb2d..ee4e07c5e7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1053,6 +1053,7 @@ static const VMStateDescription vmstate_virtio_device_endian = { .name = "virtio/device_endian", .version_id = 1, .minimum_version_id = 1, + .needed = &virtio_device_endian_needed, .fields = (VMStateField[]) { VMSTATE_UINT8(device_endian, VirtIODevice), VMSTATE_END_OF_LIST() @@ -1063,6 +1064,7 @@ static const VMStateDescription vmstate_virtio_64bit_features = { .name = "virtio/64bit_features", .version_id = 1, .minimum_version_id = 1, + .needed = &virtio_64bit_features_needed, .fields = (VMStateField[]) { VMSTATE_UINT64(guest_features, VirtIODevice), VMSTATE_END_OF_LIST() @@ -1077,16 +1079,10 @@ static const VMStateDescription vmstate_virtio = { .fields = (VMStateField[]) { VMSTATE_END_OF_LIST() }, - .subsections = (VMStateSubsection[]) { - { - .vmsd = &vmstate_virtio_device_endian, - .needed = &virtio_device_endian_needed - }, - { - .vmsd = &vmstate_virtio_64bit_features, - .needed = &virtio_64bit_features_needed - }, - { 0 } + .subsections = (const VMStateDescription*[]) { + &vmstate_virtio_device_endian, + &vmstate_virtio_64bit_features, + NULL } }; |