1*bdc2c77dSMark Cave-Ayland /* 2*bdc2c77dSMark Cave-Ayland * QEMU IOSB emulation 3*bdc2c77dSMark Cave-Ayland * 4*bdc2c77dSMark Cave-Ayland * Copyright (c) 2019 Laurent Vivier 5*bdc2c77dSMark Cave-Ayland * Copyright (c) 2022 Mark Cave-Ayland 6*bdc2c77dSMark Cave-Ayland * 7*bdc2c77dSMark Cave-Ayland * SPDX-License-Identifier: GPL-2.0-or-later 8*bdc2c77dSMark Cave-Ayland */ 9*bdc2c77dSMark Cave-Ayland 10*bdc2c77dSMark Cave-Ayland #include "qemu/osdep.h" 11*bdc2c77dSMark Cave-Ayland #include "qemu/log.h" 12*bdc2c77dSMark Cave-Ayland #include "migration/vmstate.h" 13*bdc2c77dSMark Cave-Ayland #include "hw/sysbus.h" 14*bdc2c77dSMark Cave-Ayland #include "hw/misc/iosb.h" 15*bdc2c77dSMark Cave-Ayland #include "trace.h" 16*bdc2c77dSMark Cave-Ayland 17*bdc2c77dSMark Cave-Ayland #define IOSB_SIZE 0x2000 18*bdc2c77dSMark Cave-Ayland 19*bdc2c77dSMark Cave-Ayland #define IOSB_CONFIG 0x0 20*bdc2c77dSMark Cave-Ayland #define IOSB_CONFIG2 0x100 21*bdc2c77dSMark Cave-Ayland #define IOSB_SONIC_SCSI 0x200 22*bdc2c77dSMark Cave-Ayland #define IOSB_REVISION 0x300 23*bdc2c77dSMark Cave-Ayland #define IOSB_SCSI_RESID 0x400 24*bdc2c77dSMark Cave-Ayland #define IOSB_BRIGHTNESS 0x500 25*bdc2c77dSMark Cave-Ayland #define IOSB_TIMEOUT 0x600 26*bdc2c77dSMark Cave-Ayland 27*bdc2c77dSMark Cave-Ayland 28*bdc2c77dSMark Cave-Ayland static uint64_t iosb_read(void *opaque, hwaddr addr, 29*bdc2c77dSMark Cave-Ayland unsigned size) 30*bdc2c77dSMark Cave-Ayland { 31*bdc2c77dSMark Cave-Ayland IOSBState *s = IOSB(opaque); 32*bdc2c77dSMark Cave-Ayland uint64_t val = 0; 33*bdc2c77dSMark Cave-Ayland 34*bdc2c77dSMark Cave-Ayland switch (addr) { 35*bdc2c77dSMark Cave-Ayland case IOSB_CONFIG: 36*bdc2c77dSMark Cave-Ayland case IOSB_CONFIG2: 37*bdc2c77dSMark Cave-Ayland case IOSB_SONIC_SCSI: 38*bdc2c77dSMark Cave-Ayland case IOSB_REVISION: 39*bdc2c77dSMark Cave-Ayland case IOSB_SCSI_RESID: 40*bdc2c77dSMark Cave-Ayland case IOSB_BRIGHTNESS: 41*bdc2c77dSMark Cave-Ayland case IOSB_TIMEOUT: 42*bdc2c77dSMark Cave-Ayland val = s->regs[addr >> 8]; 43*bdc2c77dSMark Cave-Ayland break; 44*bdc2c77dSMark Cave-Ayland default: 45*bdc2c77dSMark Cave-Ayland qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented read addr=0x%"PRIx64 46*bdc2c77dSMark Cave-Ayland " val=0x%"PRIx64 " size=%d\n", 47*bdc2c77dSMark Cave-Ayland addr, val, size); 48*bdc2c77dSMark Cave-Ayland } 49*bdc2c77dSMark Cave-Ayland 50*bdc2c77dSMark Cave-Ayland trace_iosb_read(addr, val, size); 51*bdc2c77dSMark Cave-Ayland return val; 52*bdc2c77dSMark Cave-Ayland } 53*bdc2c77dSMark Cave-Ayland 54*bdc2c77dSMark Cave-Ayland static void iosb_write(void *opaque, hwaddr addr, uint64_t val, 55*bdc2c77dSMark Cave-Ayland unsigned size) 56*bdc2c77dSMark Cave-Ayland { 57*bdc2c77dSMark Cave-Ayland IOSBState *s = IOSB(opaque); 58*bdc2c77dSMark Cave-Ayland 59*bdc2c77dSMark Cave-Ayland switch (addr) { 60*bdc2c77dSMark Cave-Ayland case IOSB_CONFIG: 61*bdc2c77dSMark Cave-Ayland case IOSB_CONFIG2: 62*bdc2c77dSMark Cave-Ayland case IOSB_SONIC_SCSI: 63*bdc2c77dSMark Cave-Ayland case IOSB_REVISION: 64*bdc2c77dSMark Cave-Ayland case IOSB_SCSI_RESID: 65*bdc2c77dSMark Cave-Ayland case IOSB_BRIGHTNESS: 66*bdc2c77dSMark Cave-Ayland case IOSB_TIMEOUT: 67*bdc2c77dSMark Cave-Ayland s->regs[addr >> 8] = val; 68*bdc2c77dSMark Cave-Ayland break; 69*bdc2c77dSMark Cave-Ayland default: 70*bdc2c77dSMark Cave-Ayland qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented write addr=0x%"PRIx64 71*bdc2c77dSMark Cave-Ayland " val=0x%"PRIx64 " size=%d\n", 72*bdc2c77dSMark Cave-Ayland addr, val, size); 73*bdc2c77dSMark Cave-Ayland } 74*bdc2c77dSMark Cave-Ayland 75*bdc2c77dSMark Cave-Ayland trace_iosb_write(addr, val, size); 76*bdc2c77dSMark Cave-Ayland } 77*bdc2c77dSMark Cave-Ayland 78*bdc2c77dSMark Cave-Ayland static const MemoryRegionOps iosb_mmio_ops = { 79*bdc2c77dSMark Cave-Ayland .read = iosb_read, 80*bdc2c77dSMark Cave-Ayland .write = iosb_write, 81*bdc2c77dSMark Cave-Ayland .endianness = DEVICE_BIG_ENDIAN, 82*bdc2c77dSMark Cave-Ayland }; 83*bdc2c77dSMark Cave-Ayland 84*bdc2c77dSMark Cave-Ayland static void iosb_reset_hold(Object *obj) 85*bdc2c77dSMark Cave-Ayland { 86*bdc2c77dSMark Cave-Ayland IOSBState *s = IOSB(obj); 87*bdc2c77dSMark Cave-Ayland 88*bdc2c77dSMark Cave-Ayland memset(s->regs, 0, sizeof(s->regs)); 89*bdc2c77dSMark Cave-Ayland 90*bdc2c77dSMark Cave-Ayland /* BCLK 33 MHz */ 91*bdc2c77dSMark Cave-Ayland s->regs[IOSB_CONFIG >> 8] = 1; 92*bdc2c77dSMark Cave-Ayland } 93*bdc2c77dSMark Cave-Ayland 94*bdc2c77dSMark Cave-Ayland static void iosb_init(Object *obj) 95*bdc2c77dSMark Cave-Ayland { 96*bdc2c77dSMark Cave-Ayland IOSBState *s = IOSB(obj); 97*bdc2c77dSMark Cave-Ayland SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 98*bdc2c77dSMark Cave-Ayland 99*bdc2c77dSMark Cave-Ayland memory_region_init_io(&s->mem_regs, obj, &iosb_mmio_ops, s, "IOSB", 100*bdc2c77dSMark Cave-Ayland IOSB_SIZE); 101*bdc2c77dSMark Cave-Ayland sysbus_init_mmio(sbd, &s->mem_regs); 102*bdc2c77dSMark Cave-Ayland } 103*bdc2c77dSMark Cave-Ayland 104*bdc2c77dSMark Cave-Ayland static const VMStateDescription vmstate_iosb = { 105*bdc2c77dSMark Cave-Ayland .name = "IOSB", 106*bdc2c77dSMark Cave-Ayland .version_id = 1, 107*bdc2c77dSMark Cave-Ayland .minimum_version_id = 1, 108*bdc2c77dSMark Cave-Ayland .fields = (VMStateField[]) { 109*bdc2c77dSMark Cave-Ayland VMSTATE_UINT32_ARRAY(regs, IOSBState, IOSB_REGS), 110*bdc2c77dSMark Cave-Ayland VMSTATE_END_OF_LIST() 111*bdc2c77dSMark Cave-Ayland } 112*bdc2c77dSMark Cave-Ayland }; 113*bdc2c77dSMark Cave-Ayland 114*bdc2c77dSMark Cave-Ayland static void iosb_class_init(ObjectClass *oc, void *data) 115*bdc2c77dSMark Cave-Ayland { 116*bdc2c77dSMark Cave-Ayland DeviceClass *dc = DEVICE_CLASS(oc); 117*bdc2c77dSMark Cave-Ayland ResettableClass *rc = RESETTABLE_CLASS(oc); 118*bdc2c77dSMark Cave-Ayland 119*bdc2c77dSMark Cave-Ayland dc->vmsd = &vmstate_iosb; 120*bdc2c77dSMark Cave-Ayland rc->phases.hold = iosb_reset_hold; 121*bdc2c77dSMark Cave-Ayland } 122*bdc2c77dSMark Cave-Ayland 123*bdc2c77dSMark Cave-Ayland static const TypeInfo iosb_info_types[] = { 124*bdc2c77dSMark Cave-Ayland { 125*bdc2c77dSMark Cave-Ayland .name = TYPE_IOSB, 126*bdc2c77dSMark Cave-Ayland .parent = TYPE_SYS_BUS_DEVICE, 127*bdc2c77dSMark Cave-Ayland .instance_size = sizeof(IOSBState), 128*bdc2c77dSMark Cave-Ayland .instance_init = iosb_init, 129*bdc2c77dSMark Cave-Ayland .class_init = iosb_class_init, 130*bdc2c77dSMark Cave-Ayland }, 131*bdc2c77dSMark Cave-Ayland }; 132*bdc2c77dSMark Cave-Ayland 133*bdc2c77dSMark Cave-Ayland DEFINE_TYPES(iosb_info_types) 134