]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Update MF624 emulation for QEMU 2.0 and 2.1 infrastructure.
authorPavel Pisa <pisa@cmp.felk.cvut.cz>
Tue, 5 Aug 2014 14:51:27 +0000 (16:51 +0200)
committerPavel Pisa <pisa@cmp.felk.cvut.cz>
Tue, 5 Aug 2014 14:51:27 +0000 (16:51 +0200)
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
src/qemu/hw/mf624.c

index 8c804d8ca75d0adda329280a0df2d4792de30094..3912c973eedb16522a06ca99dccc8ac21886645c 100644 (file)
@@ -5,17 +5,18 @@
  *
  * Licensed under GPLv2 license
  */
-#include "hw.h"
-#include "pci.h"
-#include "qemu-thread.h"
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-/* #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)