]> git.proxmox.com Git - qemu.git/blobdiff - hw/eccmemctl.c
virtio-scsi: factor checks for VIRTIO_SCSI_S_DRIVER_OK when reporting events
[qemu.git] / hw / eccmemctl.c
index d05962b70c69281db851664ce995c86a39081f6d..000bd08dee3cadb796ddb58f17e5cb36bab122a3 100644 (file)
  * THE SOFTWARE.
  */
 
-#include "sun4m.h"
 #include "sysbus.h"
-
-//#define DEBUG_ECC
-
-#ifdef DEBUG_ECC
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("ECC: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
+#include "trace.h"
 
 /* There are 3 versions of this chip used in SMP sun4m systems:
  * MCC (version 0, implementation 0) SS-600MP
  * EMC (version 0, implementation 1) SS-10
  * SMC (version 0, implementation 2) SS-10SX and SS-20
+ *
+ * Chipset docs:
+ * "Sun-4M System Architecture (revision 2.0) by Chuck Narad", 950-1373-01,
+ * http://mediacast.sun.com/users/Barton808/media/Sun4M_SystemArchitecture_edited2.pdf
  */
 
 #define ECC_MCC        0x00000000
 
 typedef struct ECCState {
     SysBusDevice busdev;
+    MemoryRegion iomem, iomem_diag;
     qemu_irq irq;
     uint32_t regs[ECC_NREGS];
     uint8_t diag[ECC_DIAG_SIZE];
     uint32_t version;
 } ECCState;
 
-static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void ecc_mem_write(void *opaque, hwaddr addr, uint64_t val,
+                          unsigned size)
 {
     ECCState *s = opaque;
 
@@ -145,37 +142,38 @@ static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
             s->regs[ECC_MER] = s->version | (val & ECC_MER_MASK_1);
         else if (s->version == ECC_SMC)
             s->regs[ECC_MER] = s->version | (val & ECC_MER_MASK_2);
-        DPRINTF("Write memory enable %08x\n", val);
+        trace_ecc_mem_writel_mer(val);
         break;
     case ECC_MDR:
         s->regs[ECC_MDR] =  val & ECC_MDR_MASK;
-        DPRINTF("Write memory delay %08x\n", val);
+        trace_ecc_mem_writel_mdr(val);
         break;
     case ECC_MFSR:
         s->regs[ECC_MFSR] =  val;
         qemu_irq_lower(s->irq);
-        DPRINTF("Write memory fault status %08x\n", val);
+        trace_ecc_mem_writel_mfsr(val);
         break;
     case ECC_VCR:
         s->regs[ECC_VCR] =  val;
-        DPRINTF("Write slot configuration %08x\n", val);
+        trace_ecc_mem_writel_vcr(val);
         break;
     case ECC_DR:
         s->regs[ECC_DR] =  val;
-        DPRINTF("Write diagnostic %08x\n", val);
+        trace_ecc_mem_writel_dr(val);
         break;
     case ECC_ECR0:
         s->regs[ECC_ECR0] =  val;
-        DPRINTF("Write event count 1 %08x\n", val);
+        trace_ecc_mem_writel_ecr0(val);
         break;
     case ECC_ECR1:
         s->regs[ECC_ECR0] =  val;
-        DPRINTF("Write event count 2 %08x\n", val);
+        trace_ecc_mem_writel_ecr1(val);
         break;
     }
 }
 
-static uint32_t ecc_mem_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t ecc_mem_read(void *opaque, hwaddr addr,
+                             unsigned size)
 {
     ECCState *s = opaque;
     uint32_t ret = 0;
@@ -183,122 +181,99 @@ static uint32_t ecc_mem_readl(void *opaque, target_phys_addr_t addr)
     switch (addr >> 2) {
     case ECC_MER:
         ret = s->regs[ECC_MER];
-        DPRINTF("Read memory enable %08x\n", ret);
+        trace_ecc_mem_readl_mer(ret);
         break;
     case ECC_MDR:
         ret = s->regs[ECC_MDR];
-        DPRINTF("Read memory delay %08x\n", ret);
+        trace_ecc_mem_readl_mdr(ret);
         break;
     case ECC_MFSR:
         ret = s->regs[ECC_MFSR];
-        DPRINTF("Read memory fault status %08x\n", ret);
+        trace_ecc_mem_readl_mfsr(ret);
         break;
     case ECC_VCR:
         ret = s->regs[ECC_VCR];
-        DPRINTF("Read slot configuration %08x\n", ret);
+        trace_ecc_mem_readl_vcr(ret);
         break;
     case ECC_MFAR0:
         ret = s->regs[ECC_MFAR0];
-        DPRINTF("Read memory fault address 0 %08x\n", ret);
+        trace_ecc_mem_readl_mfar0(ret);
         break;
     case ECC_MFAR1:
         ret = s->regs[ECC_MFAR1];
-        DPRINTF("Read memory fault address 1 %08x\n", ret);
+        trace_ecc_mem_readl_mfar1(ret);
         break;
     case ECC_DR:
         ret = s->regs[ECC_DR];
-        DPRINTF("Read diagnostic %08x\n", ret);
+        trace_ecc_mem_readl_dr(ret);
         break;
     case ECC_ECR0:
         ret = s->regs[ECC_ECR0];
-        DPRINTF("Read event count 1 %08x\n", ret);
+        trace_ecc_mem_readl_ecr0(ret);
         break;
     case ECC_ECR1:
         ret = s->regs[ECC_ECR0];
-        DPRINTF("Read event count 2 %08x\n", ret);
+        trace_ecc_mem_readl_ecr1(ret);
         break;
     }
     return ret;
 }
 
-static CPUReadMemoryFunc *ecc_mem_read[3] = {
-    NULL,
-    NULL,
-    ecc_mem_readl,
-};
-
-static CPUWriteMemoryFunc *ecc_mem_write[3] = {
-    NULL,
-    NULL,
-    ecc_mem_writel,
+static const MemoryRegionOps ecc_mem_ops = {
+    .read = ecc_mem_read,
+    .write = ecc_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
-static void ecc_diag_mem_writeb(void *opaque, target_phys_addr_t addr,
-                                uint32_t val)
+static void ecc_diag_mem_write(void *opaque, hwaddr addr,
+                               uint64_t val, unsigned size)
 {
     ECCState *s = opaque;
 
-    DPRINTF("Write diagnostic[%d] = %02x\n", (int)addr, val);
+    trace_ecc_diag_mem_writeb(addr, val);
     s->diag[addr & ECC_DIAG_MASK] = val;
 }
 
-static uint32_t ecc_diag_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t ecc_diag_mem_read(void *opaque, hwaddr addr,
+                                  unsigned size)
 {
     ECCState *s = opaque;
     uint32_t ret = s->diag[(int)addr];
 
-    DPRINTF("Read diagnostic[%d] = %02x\n", (int)addr, ret);
+    trace_ecc_diag_mem_readb(addr, ret);
     return ret;
 }
 
-static CPUReadMemoryFunc *ecc_diag_mem_read[3] = {
-    ecc_diag_mem_readb,
-    NULL,
-    NULL,
+static const MemoryRegionOps ecc_diag_mem_ops = {
+    .read = ecc_diag_mem_read,
+    .write = ecc_diag_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
 };
 
-static CPUWriteMemoryFunc *ecc_diag_mem_write[3] = {
-    ecc_diag_mem_writeb,
-    NULL,
-    NULL,
+static const VMStateDescription vmstate_ecc = {
+    .name ="ECC",
+    .version_id = 3,
+    .minimum_version_id = 3,
+    .minimum_version_id_old = 3,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32_ARRAY(regs, ECCState, ECC_NREGS),
+        VMSTATE_BUFFER(diag, ECCState),
+        VMSTATE_UINT32(version, ECCState),
+        VMSTATE_END_OF_LIST()
+    }
 };
 
-static int ecc_load(QEMUFile *f, void *opaque, int version_id)
+static void ecc_reset(DeviceState *d)
 {
-    ECCState *s = opaque;
-    int i;
-
-    if (version_id != 3)
-        return -EINVAL;
-
-    for (i = 0; i < ECC_NREGS; i++)
-        qemu_get_be32s(f, &s->regs[i]);
-
-    for (i = 0; i < ECC_DIAG_SIZE; i++)
-        qemu_get_8s(f, &s->diag[i]);
-
-    qemu_get_be32s(f, &s->version);
-
-    return 0;
-}
-
-static void ecc_save(QEMUFile *f, void *opaque)
-{
-    ECCState *s = opaque;
-    int i;
-
-    for (i = 0; i < ECC_NREGS; i++)
-        qemu_put_be32s(f, &s->regs[i]);
-
-    for (i = 0; i < ECC_DIAG_SIZE; i++)
-        qemu_put_8s(f, &s->diag[i]);
-
-    qemu_put_be32s(f, &s->version);
-}
-
-static void ecc_reset(void *opaque)
-{
-    ECCState *s = opaque;
+    ECCState *s = container_of(d, ECCState, busdev.qdev);
 
     if (s->version == ECC_MCC)
         s->regs[ECC_MER] &= ECC_MER_REU;
@@ -315,46 +290,51 @@ static void ecc_reset(void *opaque)
     s->regs[ECC_ECR1] = 0;
 }
 
-static void ecc_init1(SysBusDevice *dev)
+static int ecc_init1(SysBusDevice *dev)
 {
-    int ecc_io_memory;
     ECCState *s = FROM_SYSBUS(ECCState, dev);
 
     sysbus_init_irq(dev, &s->irq);
-    s->version = qdev_get_prop_int(&dev->qdev, "version", -1);
     s->regs[0] = s->version;
-    ecc_io_memory = cpu_register_io_memory(ecc_mem_read, ecc_mem_write, s);
-    sysbus_init_mmio(dev, ECC_SIZE, ecc_io_memory);
+    memory_region_init_io(&s->iomem, &ecc_mem_ops, s, "ecc", ECC_SIZE);
+    sysbus_init_mmio(dev, &s->iomem);
 
     if (s->version == ECC_MCC) { // SS-600MP only
-        ecc_io_memory = cpu_register_io_memory(ecc_diag_mem_read,
-                                               ecc_diag_mem_write, s);
-        sysbus_init_mmio(dev, ECC_DIAG_SIZE, ecc_io_memory);
+        memory_region_init_io(&s->iomem_diag, &ecc_diag_mem_ops, s,
+                              "ecc.diag", ECC_DIAG_SIZE);
+        sysbus_init_mmio(dev, &s->iomem_diag);
     }
-    register_savevm("ECC", -1, 3, ecc_save, ecc_load, s);
-    qemu_register_reset(ecc_reset, s);
-    ecc_reset(s);
+
+    return 0;
 }
 
-void ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version)
+static Property ecc_properties[] = {
+    DEFINE_PROP_HEX32("version", ECCState, version, -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ecc_class_init(ObjectClass *klass, void *data)
 {
-    DeviceState *dev;
-    SysBusDevice *s;
-
-    dev = qdev_create(NULL, "eccmemctl");
-    qdev_set_prop_int(dev, "version", version);
-    qdev_init(dev);
-    s = sysbus_from_qdev(dev);
-    sysbus_connect_irq(s, 0, irq);
-    sysbus_mmio_map(s, 0, base);
-    if (version == ECC_MCC) { // SS-600MP only
-        sysbus_mmio_map(s, 1, base + 0x1000);
-    }
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ecc_init1;
+    dc->reset = ecc_reset;
+    dc->vmsd = &vmstate_ecc;
+    dc->props = ecc_properties;
 }
 
-static void ecc_register_devices(void)
+static TypeInfo ecc_info = {
+    .name          = "eccmemctl",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(ECCState),
+    .class_init    = ecc_class_init,
+};
+
+
+static void ecc_register_types(void)
 {
-    sysbus_register_dev("eccmemctl", sizeof(ECCState), ecc_init1);
+    type_register_static(&ecc_info);
 }
 
-device_init(ecc_register_devices)
+type_init(ecc_register_types)