From: Pavel Pisa Date: Tue, 5 Aug 2014 14:51:27 +0000 (+0200) Subject: Update MF624 emulation for QEMU 2.0 and 2.1 infrastructure. X-Git-Url: http://rtime.felk.cvut.cz/gitweb/mf6xx.git/commitdiff_plain/b1598d12ab39b598df034047a6d901b8ba25978b Update MF624 emulation for QEMU 2.0 and 2.1 infrastructure. Signed-off-by: Pavel Pisa --- diff --git a/src/qemu/hw/mf624.c b/src/qemu/hw/mf624.c index 8c804d8..3912c97 100644 --- a/src/qemu/hw/mf624.c +++ b/src/qemu/hw/mf624.c @@ -5,17 +5,18 @@ * * Licensed under GPLv2 license */ -#include "hw.h" -#include "pci.h" -#include "qemu-thread.h" -#include -#include -#include -#include -#include -#include - -/* #define QEMU_VER_ABOVE_015 */ +#include "hw/hw.h" +#include "hw/pci/pci.h" +#include "qemu/event_notifier.h" +#include "qemu/osdep.h" +#include "qemu/thread.h" +#include "qemu/sockets.h" +#include "sysemu/char.h" + +#define TYPE_MF624_DEV "mf624" + +#define MF624_DEV(obj) \ + OBJECT_CHECK(mf624_state_t, (obj), TYPE_MF624_DEV) #define PCI_VENDOR_ID_HUMUSOFT 0x186c #define PCI_DEVICE_ID_MF624 0x0624 @@ -95,12 +96,12 @@ typedef struct { typedef struct { PCIDevice dev; - #ifdef QEMU_VER_ABOVE_015 MemoryRegion mmio_bar0; MemoryRegion mmio_bar2; MemoryRegion mmio_bar4; - #endif /*QEMU_VER_ABOVE_015*/ + qemu_irq irq; + QemuThread socket_thread; int socket_srv; int socket_tmp; uint32_t port; @@ -189,6 +190,14 @@ static void mf624_init_registers(mf624_state_t* s) s->ADDATA_FIFO_POSITION = 0; } +static void +mf624_reset(void *opaque) +{ + mf624_state_t *s = (mf624_state_t *)opaque; + + mf624_init_registers(s); +} + /* After some widget's value is changed, new value is send via socket to Qemu */ static void socket_write(mf624_state_t *s, const char* reg, double val) { @@ -312,6 +321,7 @@ static void* init_socket(void* ptr) dev->socket_tmp = accept(dev->socket_srv, (struct sockaddr*) &addr_client, &len_client); if (dev->socket_tmp == -1) { perror("accept()"); + return NULL; } printf("Client connected\n"); @@ -327,7 +337,7 @@ static void* init_socket(void* ptr) //----------------------------------------------------------------------------- -static void mf624_BAR0_write32(void *opaque, target_phys_addr_t addr, uint32_t value) +static void mf624_BAR0_write32(void *opaque, hwaddr addr, uint64_t value, unsigned size) { mf624_state_t *s = opaque; @@ -371,13 +381,13 @@ static void mf624_BAR0_write32(void *opaque, target_phys_addr_t addr, uint32_t v break; default: - printf("mf624_BAR0_write32(): addr = " TARGET_FMT_plx "; value = %d\n", addr, value); + printf("mf624_BAR0_write32(): addr = " TARGET_FMT_plx + "; value = 0x%" PRIx64 "\n", addr, value); break; } } - -static uint32_t mf624_BAR0_read32(void *opaque, target_phys_addr_t addr) +static uint64_t mf624_BAR0_read32(void *opaque, hwaddr addr, unsigned size) { mf624_state_t *s = opaque; @@ -389,13 +399,13 @@ static uint32_t mf624_BAR0_read32(void *opaque, target_phys_addr_t addr) return s->BAR0.GPIOC; default: - printf("mf624_BAR0_read32(): addr = " TARGET_FMT_plx "\n", addr); + printf("mf624_BAR0_read32(): addr = " + TARGET_FMT_plx "\n", addr); return 0x0; } } - -static uint32_t mf624_BAR2_read16(void *opaque, target_phys_addr_t addr) +static uint64_t mf624_BAR2_read16(void *opaque, hwaddr addr, unsigned size) { int i; int ADDATA_val = 0xFFFF; @@ -483,13 +493,13 @@ static uint32_t mf624_BAR2_read16(void *opaque, target_phys_addr_t addr) return 0xFFFF; // Semirandom value default: - printf("mf624_BAR2_read16(): addr = " TARGET_FMT_plx "\n", addr); + printf("mf624_BAR2_read16(): addr = " + TARGET_FMT_plx "\n", addr); return 0x0; } } - -static void mf624_BAR2_write16(void *opaque, target_phys_addr_t addr, uint32_t value) +static void mf624_BAR2_write16(void *opaque, hwaddr addr, uint64_t value, unsigned size) { mf624_state_t *s = opaque; @@ -570,18 +580,19 @@ static void mf624_BAR2_write16(void *opaque, target_phys_addr_t addr, uint32_t v break; default: - printf("mf624_BAR2_write16(): addr = " TARGET_FMT_plx "; value = %d\n", addr, value); + printf("mf624_BAR2_write16(): addr = " TARGET_FMT_plx + "; value = 0x%" PRIx64 "\n", addr, value); break; } } - -static void mf624_BAR4_write32(void *opaque, target_phys_addr_t addr, uint32_t value) +static void mf624_BAR4_write32(void *opaque, hwaddr addr, uint64_t value, unsigned size) { - printf("mf624_BAR4_write32(): addr = " TARGET_FMT_plx "; value = %d\n", addr, value); + printf("mf624_BAR4_write32(): addr = " TARGET_FMT_plx + "; value = 0x%" PRIx64 "\n", addr, value); } -static uint32_t mf624_BAR4_read32(void *opaque, target_phys_addr_t addr) +static uint64_t mf624_BAR4_read32(void *opaque, hwaddr addr, unsigned size) { printf("mf624_BAR4_read32(): addr = " TARGET_FMT_plx "\n", addr); return 0x0; @@ -589,207 +600,143 @@ static uint32_t mf624_BAR4_read32(void *opaque, target_phys_addr_t addr) //----------------------------------------------------------------------------- -#ifdef QEMU_VER_ABOVE_015 - static const MemoryRegionOps mf624_BAR0_mmio_ops = { - .old_mmio = { - .read = { - NULL, - NULL, - mf624_BAR0_read32, - }, - .write = { - NULL, - NULL, - mf624_BAR0_write32, - }, - }, + .read = mf624_BAR0_read32, + .write = mf624_BAR0_write32, .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, }; static const MemoryRegionOps mf624_BAR2_mmio_ops = { - .old_mmio = { - .read = { - NULL, - mf624_BAR2_read16, - NULL, - }, - .write = { - NULL, - mf624_BAR2_write16, - NULL, - }, - }, + .read = mf624_BAR2_read16, + .write = mf624_BAR2_write16, .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 2, + .max_access_size = 2, + }, }; static const MemoryRegionOps mf624_BAR4_mmio_ops = { - .old_mmio = { - .read = { - NULL, - NULL, - mf624_BAR4_read32, - }, - .write = { - NULL, - NULL, - mf624_BAR4_write32, - }, - }, + .read = mf624_BAR4_read32, + .write = mf624_BAR4_write32, .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, }; -#else /*QEMU_VER_ABOVE_015*/ +#define DEFAULT_PORT 55555 +static int mf624_init(PCIDevice *pci_dev) +{ + mf624_state_t *s = MF624_DEV(pci_dev); //alocation of mf624_state_t + uint8_t *pci_conf; -static CPUReadMemoryFunc * const mf624_BAR0_read[3] = { - NULL, /* read8 */ - NULL, /* read16 */ - mf624_BAR0_read32, -}; + if (s->port == DEFAULT_PORT) { + s->port += instance; // Each instance of the same device should have another port number + instance ++; + } -static CPUWriteMemoryFunc * const mf624_BAR0_write[3] = { - NULL, /* write8 */ - NULL, /* write16 */ - mf624_BAR0_write32, -}; + //Set all internal registers to default values + mf624_init_registers(s); -static CPUReadMemoryFunc * const mf624_BAR2_read[3] = { - NULL, /* read8 */ - mf624_BAR2_read16, - NULL, /* read32 */ -}; + pci_conf = pci_dev->config; + pci_conf[PCI_INTERRUPT_PIN] = 0x1; // interrupt pin 0 -static CPUWriteMemoryFunc * const mf624_BAR2_write[3] = { - NULL, /* write8 */ - mf624_BAR2_write16, - NULL, /* write32 */ -}; + s->irq = pci_allocate_irq(&s->dev); -static CPUReadMemoryFunc * const mf624_BAR4_read[3] = { - NULL, /* read8 */ - NULL, /* read16 */ - mf624_BAR4_read32, -}; + qemu_register_reset(mf624_reset, s); -static CPUWriteMemoryFunc * const mf624_BAR4_write[3] = { - NULL, /* write8 */ - NULL, /* write16 */ - mf624_BAR4_write32, -}; + memory_region_init_io(&s->mmio_bar0, OBJECT(s), &mf624_BAR0_mmio_ops, s, "mf624_bar0", BAR0_size); + memory_region_init_io(&s->mmio_bar2, OBJECT(s), &mf624_BAR2_mmio_ops, s, "mf624_bar2", BAR2_size); + memory_region_init_io(&s->mmio_bar4, OBJECT(s), &mf624_BAR4_mmio_ops, s, "mf624_bar4", BAR4_size); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar0); + pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar2); + pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar4); + //Create thread, which will be blocked on reading from socket (connected to "I/O GUI") -//----------------------------------------------------------------------------- + qemu_thread_create(&s->socket_thread, "mf624_io_thread", + init_socket, (void*) s, QEMU_THREAD_JOINABLE); + return 0; +} -static void mf624_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void qdev_mf624_reset(DeviceState *dev) { - mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev); - - switch (region_num) { - case 0: - //printf("reg%d, addr = %x\n", region_num, addr); - cpu_register_physical_memory(addr + 0x0, BAR0_size, s->BAR0_mem_table_index); - break; - case 2: - //printf("reg%d, addr = %x\n", region_num, addr); - cpu_register_physical_memory(addr + 0x0, BAR2_size, s->BAR2_mem_table_index); - break; - case 4: - //printf("reg%d, addr = %x\n", region_num, addr); - cpu_register_physical_memory(addr + 0x0, BAR4_size, s->BAR4_mem_table_index); - break; - default: - printf("FFFUUU\n"); - } - + mf624_state_t *s = MF624_DEV(dev); + mf624_init_registers(s); } -#endif /*QEMU_VER_ABOVE_015*/ - -#define DEFAULT_PORT 55555 -static int pci_mf624_init(PCIDevice *pci_dev) +static void mf624_exit(PCIDevice *pci_dev) { - mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev); //alocation of mf624_state_t - uint8_t *pci_conf; - QemuThread socket_thread; + mf624_state_t *s = MF624_DEV(pci_dev); - printf("MF624 Loaded.\n"); + close(s->socket_srv); - if (s->port == DEFAULT_PORT) { - s->port += instance; // Each instance of the same device should have another port number - instance ++; - } + qemu_thread_join(&s->socket_thread); - //Set all internal registers to default values - mf624_init_registers(s); - - pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_HUMUSOFT); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_MF624); - pci_config_set_class(pci_conf, PCI_CLASS_SIGNAL_PROCESSING_CONTROLLER); - pci_conf[PCI_SUBSYSTEM_VENDOR_ID] = PCI_VENDOR_ID_HUMUSOFT & 0xff; - pci_conf[PCI_SUBSYSTEM_VENDOR_ID + 1] = PCI_VENDOR_ID_HUMUSOFT >> 8; - pci_conf[PCI_SUBSYSTEM_ID] = PCI_DEVICE_ID_MF624 & 0xff; - pci_conf[PCI_SUBSYSTEM_ID + 1] = PCI_DEVICE_ID_MF624 >> 8; - - pci_conf[PCI_INTERRUPT_PIN] = 0x1; // interrupt pin 0 - - #ifdef QEMU_VER_ABOVE_015 - memory_region_init_io(&s->mmio_bar0, &mf624_BAR0_mmio_ops, s, "mf624_bar0", BAR0_size); - memory_region_init_io(&s->mmio_bar2, &mf624_BAR2_mmio_ops, s, "mf624_bar2", BAR2_size); - memory_region_init_io(&s->mmio_bar4, &mf624_BAR4_mmio_ops, s, "mf624_bar4", BAR4_size); - pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar0); - pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar2); - pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar4); - #else /*QEMU_VER_ABOVE_015*/ - s->BAR0_mem_table_index = cpu_register_io_memory(mf624_BAR0_read, - mf624_BAR0_write, - s, - DEVICE_NATIVE_ENDIAN); - - s->BAR2_mem_table_index = cpu_register_io_memory(mf624_BAR2_read, - mf624_BAR2_write, - s, - DEVICE_NATIVE_ENDIAN); - - s->BAR4_mem_table_index = cpu_register_io_memory(mf624_BAR4_read, - mf624_BAR4_write, - s, - DEVICE_NATIVE_ENDIAN); - - pci_register_bar(&s->dev, 0, BAR0_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map); - pci_register_bar(&s->dev, 2, BAR2_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map); - pci_register_bar(&s->dev, 4, BAR4_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map); - #endif /*QEMU_VER_ABOVE_015*/ - - //Create thread, which will be blocked on reading from socket (connected to "I/O GUI") - qemu_thread_create(&socket_thread, init_socket, (void*) s); - return 0; -} + qemu_unregister_reset(mf624_reset, s); -static int pci_mf624_exit(PCIDevice *pci_dev) -{ - mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev); - close(s->socket_srv); + memory_region_destroy(&s->mmio_bar0); + memory_region_destroy(&s->mmio_bar2); + memory_region_destroy(&s->mmio_bar4); - return 0; + qemu_free_irq(s->irq); } +static const VMStateDescription vmstate_mf624 = { + .name = "mf624", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, -static PCIDeviceInfo mf624_info = { - .qdev.name = "mf624", - .qdev.size = sizeof(mf624_state_t), - .init = pci_mf624_init, - .exit = pci_mf624_exit, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("port", mf624_state_t, port, DEFAULT_PORT), - DEFINE_PROP_END_OF_LIST(), - } + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, mf624_state_t), + VMSTATE_UINT32(port, mf624_state_t), + VMSTATE_END_OF_LIST() + } + +}; + +static Property mf624_properties[] = { + DEFINE_PROP_UINT32("port", mf624_state_t, port, DEFAULT_PORT), + DEFINE_PROP_END_OF_LIST(), +}; + +static void mf624_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = mf624_init; + k->exit = mf624_exit; + k->vendor_id = PCI_VENDOR_ID_HUMUSOFT; + k->device_id = PCI_DEVICE_ID_MF624; + k->revision = 0x00; + k->class_id = PCI_CLASS_SIGNAL_PROCESSING_CONTROLLER; + k->subsystem_vendor_id = PCI_VENDOR_ID_HUMUSOFT; + k->subsystem_id = PCI_DEVICE_ID_MF624; + dc->desc = "Humusoft MF624"; + dc->props = mf624_properties; + dc->vmsd = &vmstate_mf624; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->reset = qdev_mf624_reset; +} + +static const TypeInfo mf624_info = { + .name = TYPE_MF624_DEV, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof( mf624_state_t), + .class_init = mf624_class_init, }; -static void mf624_register_device(void) +static void mf624_register_types(void) { - pci_qdev_register(&mf624_info); + type_register_static(&mf624_info); } -device_init(mf624_register_device) +type_init(mf624_register_types)