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