X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/ee6847d19be16c789b8bd4e553b7cd6701ba1245..f1a1a35638bf045a2b158c0cb23d92ef39c06792:/hw/eccmemctl.c diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c index c5d6449081..dbac2c2bbc 100644 --- a/hw/eccmemctl.c +++ b/hw/eccmemctl.c @@ -22,22 +22,17 @@ * 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 @@ -127,13 +122,15 @@ 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,61 +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->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_prop_set_uint32(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 SysBusDeviceInfo ecc_info = { - .init = ecc_init1, - .qdev.name = "eccmemctl", - .qdev.size = sizeof(ECCState), - .qdev.props = (Property[]) { - { - .name = "version", - .info = &qdev_prop_uint32, - .offset = offsetof(ECCState, version), - .defval = (uint32_t[]) { -1 }, - }, - {/* end of list */} - } +static const TypeInfo ecc_info = { + .name = "eccmemctl", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(ECCState), + .class_init = ecc_class_init, }; -static void ecc_register_devices(void) +static void ecc_register_types(void) { - sysbus_register_withprop(&ecc_info); + type_register_static(&ecc_info); } -device_init(ecc_register_devices) +type_init(ecc_register_types)