|  | /* | 
|  | * djMEMC, macintosh memory and interrupt controller | 
|  | * (Quadra 610/650/800 & Centris 610/650) | 
|  | * | 
|  | *    https://mac68k.info/wiki/display/mac68k/djMEMC+Information | 
|  | * | 
|  | * SPDX-License-Identifier: GPL-2.0-or-later | 
|  | */ | 
|  |  | 
|  | #include "qemu/osdep.h" | 
|  | #include "qemu/log.h" | 
|  | #include "migration/vmstate.h" | 
|  | #include "hw/misc/djmemc.h" | 
|  | #include "hw/qdev-properties.h" | 
|  | #include "trace.h" | 
|  |  | 
|  |  | 
|  | #define DJMEMC_INTERLEAVECONF   0x0 | 
|  | #define DJMEMC_BANK0CONF        0x4 | 
|  | #define DJMEMC_BANK1CONF        0x8 | 
|  | #define DJMEMC_BANK2CONF        0xc | 
|  | #define DJMEMC_BANK3CONF        0x10 | 
|  | #define DJMEMC_BANK4CONF        0x14 | 
|  | #define DJMEMC_BANK5CONF        0x18 | 
|  | #define DJMEMC_BANK6CONF        0x1c | 
|  | #define DJMEMC_BANK7CONF        0x20 | 
|  | #define DJMEMC_BANK8CONF        0x24 | 
|  | #define DJMEMC_BANK9CONF        0x28 | 
|  | #define DJMEMC_MEMTOP           0x2c | 
|  | #define DJMEMC_CONFIG           0x30 | 
|  | #define DJMEMC_REFRESH          0x34 | 
|  |  | 
|  |  | 
|  | static uint64_t djmemc_read(void *opaque, hwaddr addr, unsigned size) | 
|  | { | 
|  | DJMEMCState *s = opaque; | 
|  | uint64_t val = 0; | 
|  |  | 
|  | switch (addr) { | 
|  | case DJMEMC_INTERLEAVECONF: | 
|  | case DJMEMC_BANK0CONF ... DJMEMC_BANK9CONF: | 
|  | case DJMEMC_MEMTOP: | 
|  | case DJMEMC_CONFIG: | 
|  | case DJMEMC_REFRESH: | 
|  | val = s->regs[addr >> 2]; | 
|  | break; | 
|  | default: | 
|  | qemu_log_mask(LOG_UNIMP, "djMEMC: unimplemented read addr=0x%"PRIx64 | 
|  | " val=0x%"PRIx64 " size=%d\n", | 
|  | addr, val, size); | 
|  | } | 
|  |  | 
|  | trace_djmemc_read(addr, val, size); | 
|  | return val; | 
|  | } | 
|  |  | 
|  | static void djmemc_write(void *opaque, hwaddr addr, uint64_t val, | 
|  | unsigned size) | 
|  | { | 
|  | DJMEMCState *s = opaque; | 
|  |  | 
|  | trace_djmemc_write(addr, val, size); | 
|  |  | 
|  | switch (addr) { | 
|  | case DJMEMC_INTERLEAVECONF: | 
|  | case DJMEMC_BANK0CONF ... DJMEMC_BANK9CONF: | 
|  | case DJMEMC_MEMTOP: | 
|  | case DJMEMC_CONFIG: | 
|  | case DJMEMC_REFRESH: | 
|  | s->regs[addr >> 2] = val; | 
|  | break; | 
|  | default: | 
|  | qemu_log_mask(LOG_UNIMP, "djMEMC: unimplemented write addr=0x%"PRIx64 | 
|  | " val=0x%"PRIx64 " size=%d\n", | 
|  | addr, val, size); | 
|  | } | 
|  | } | 
|  |  | 
|  | static const MemoryRegionOps djmemc_mmio_ops = { | 
|  | .read = djmemc_read, | 
|  | .write = djmemc_write, | 
|  | .impl = { | 
|  | .min_access_size = 4, | 
|  | .max_access_size = 4, | 
|  | }, | 
|  | .endianness = DEVICE_BIG_ENDIAN, | 
|  | }; | 
|  |  | 
|  | static void djmemc_init(Object *obj) | 
|  | { | 
|  | DJMEMCState *s = DJMEMC(obj); | 
|  | SysBusDevice *sbd = SYS_BUS_DEVICE(obj); | 
|  |  | 
|  | memory_region_init_io(&s->mem_regs, obj, &djmemc_mmio_ops, s, "djMEMC", | 
|  | DJMEMC_SIZE); | 
|  | sysbus_init_mmio(sbd, &s->mem_regs); | 
|  | } | 
|  |  | 
|  | static void djmemc_reset_hold(Object *obj, ResetType type) | 
|  | { | 
|  | DJMEMCState *s = DJMEMC(obj); | 
|  |  | 
|  | memset(s->regs, 0, sizeof(s->regs)); | 
|  | } | 
|  |  | 
|  | static const VMStateDescription vmstate_djmemc = { | 
|  | .name = "djMEMC", | 
|  | .version_id = 1, | 
|  | .minimum_version_id = 1, | 
|  | .fields = (const VMStateField[]) { | 
|  | VMSTATE_UINT32_ARRAY(regs, DJMEMCState, DJMEMC_NUM_REGS), | 
|  | VMSTATE_END_OF_LIST() | 
|  | } | 
|  | }; | 
|  |  | 
|  | static void djmemc_class_init(ObjectClass *oc, void *data) | 
|  | { | 
|  | DeviceClass *dc = DEVICE_CLASS(oc); | 
|  | ResettableClass *rc = RESETTABLE_CLASS(oc); | 
|  |  | 
|  | dc->vmsd = &vmstate_djmemc; | 
|  | rc->phases.hold = djmemc_reset_hold; | 
|  | } | 
|  |  | 
|  | static const TypeInfo djmemc_info_types[] = { | 
|  | { | 
|  | .name          = TYPE_DJMEMC, | 
|  | .parent        = TYPE_SYS_BUS_DEVICE, | 
|  | .instance_size = sizeof(DJMEMCState), | 
|  | .instance_init = djmemc_init, | 
|  | .class_init    = djmemc_class_init, | 
|  | }, | 
|  | }; | 
|  |  | 
|  | DEFINE_TYPES(djmemc_info_types) |