1*3ec680e6SJackson Donaldson /* 2*3ec680e6SJackson Donaldson * MAX78000 Instruction Cache 3*3ec680e6SJackson Donaldson * 4*3ec680e6SJackson Donaldson * Copyright (c) 2025 Jackson Donaldson <jcksn@duck.com> 5*3ec680e6SJackson Donaldson * 6*3ec680e6SJackson Donaldson * SPDX-License-Identifier: GPL-2.0-or-later 7*3ec680e6SJackson Donaldson */ 8*3ec680e6SJackson Donaldson 9*3ec680e6SJackson Donaldson #include "qemu/osdep.h" 10*3ec680e6SJackson Donaldson #include "qemu/log.h" 11*3ec680e6SJackson Donaldson #include "trace.h" 12*3ec680e6SJackson Donaldson #include "hw/irq.h" 13*3ec680e6SJackson Donaldson #include "migration/vmstate.h" 14*3ec680e6SJackson Donaldson #include "hw/misc/max78000_icc.h" 15*3ec680e6SJackson Donaldson 16*3ec680e6SJackson Donaldson 17*3ec680e6SJackson Donaldson static uint64_t max78000_icc_read(void *opaque, hwaddr addr, 18*3ec680e6SJackson Donaldson unsigned int size) 19*3ec680e6SJackson Donaldson { 20*3ec680e6SJackson Donaldson Max78000IccState *s = opaque; 21*3ec680e6SJackson Donaldson switch (addr) { 22*3ec680e6SJackson Donaldson case ICC_INFO: 23*3ec680e6SJackson Donaldson return s->info; 24*3ec680e6SJackson Donaldson 25*3ec680e6SJackson Donaldson case ICC_SZ: 26*3ec680e6SJackson Donaldson return s->sz; 27*3ec680e6SJackson Donaldson 28*3ec680e6SJackson Donaldson case ICC_CTRL: 29*3ec680e6SJackson Donaldson return s->ctrl; 30*3ec680e6SJackson Donaldson 31*3ec680e6SJackson Donaldson default: 32*3ec680e6SJackson Donaldson qemu_log_mask(LOG_GUEST_ERROR, 33*3ec680e6SJackson Donaldson "%s: Bad offset 0x%" HWADDR_PRIx "\n", 34*3ec680e6SJackson Donaldson __func__, addr); 35*3ec680e6SJackson Donaldson return 0; 36*3ec680e6SJackson Donaldson 37*3ec680e6SJackson Donaldson } 38*3ec680e6SJackson Donaldson } 39*3ec680e6SJackson Donaldson 40*3ec680e6SJackson Donaldson static void max78000_icc_write(void *opaque, hwaddr addr, 41*3ec680e6SJackson Donaldson uint64_t val64, unsigned int size) 42*3ec680e6SJackson Donaldson { 43*3ec680e6SJackson Donaldson Max78000IccState *s = opaque; 44*3ec680e6SJackson Donaldson 45*3ec680e6SJackson Donaldson switch (addr) { 46*3ec680e6SJackson Donaldson case ICC_CTRL: 47*3ec680e6SJackson Donaldson s->ctrl = 0x10000 | (val64 & 1); 48*3ec680e6SJackson Donaldson break; 49*3ec680e6SJackson Donaldson 50*3ec680e6SJackson Donaldson case ICC_INVALIDATE: 51*3ec680e6SJackson Donaldson break; 52*3ec680e6SJackson Donaldson 53*3ec680e6SJackson Donaldson default: 54*3ec680e6SJackson Donaldson qemu_log_mask(LOG_GUEST_ERROR, 55*3ec680e6SJackson Donaldson "%s: Bad offset 0x%" HWADDR_PRIx "\n", 56*3ec680e6SJackson Donaldson __func__, addr); 57*3ec680e6SJackson Donaldson break; 58*3ec680e6SJackson Donaldson } 59*3ec680e6SJackson Donaldson } 60*3ec680e6SJackson Donaldson 61*3ec680e6SJackson Donaldson static const MemoryRegionOps max78000_icc_ops = { 62*3ec680e6SJackson Donaldson .read = max78000_icc_read, 63*3ec680e6SJackson Donaldson .write = max78000_icc_write, 64*3ec680e6SJackson Donaldson .endianness = DEVICE_LITTLE_ENDIAN, 65*3ec680e6SJackson Donaldson .valid.min_access_size = 4, 66*3ec680e6SJackson Donaldson .valid.max_access_size = 4, 67*3ec680e6SJackson Donaldson }; 68*3ec680e6SJackson Donaldson 69*3ec680e6SJackson Donaldson static const VMStateDescription max78000_icc_vmstate = { 70*3ec680e6SJackson Donaldson .name = TYPE_MAX78000_ICC, 71*3ec680e6SJackson Donaldson .version_id = 1, 72*3ec680e6SJackson Donaldson .minimum_version_id = 1, 73*3ec680e6SJackson Donaldson .fields = (const VMStateField[]) { 74*3ec680e6SJackson Donaldson VMSTATE_UINT32(info, Max78000IccState), 75*3ec680e6SJackson Donaldson VMSTATE_UINT32(sz, Max78000IccState), 76*3ec680e6SJackson Donaldson VMSTATE_UINT32(ctrl, Max78000IccState), 77*3ec680e6SJackson Donaldson VMSTATE_END_OF_LIST() 78*3ec680e6SJackson Donaldson } 79*3ec680e6SJackson Donaldson }; 80*3ec680e6SJackson Donaldson 81*3ec680e6SJackson Donaldson static void max78000_icc_reset_hold(Object *obj, ResetType type) 82*3ec680e6SJackson Donaldson { 83*3ec680e6SJackson Donaldson Max78000IccState *s = MAX78000_ICC(obj); 84*3ec680e6SJackson Donaldson s->info = 0; 85*3ec680e6SJackson Donaldson s->sz = 0x10000010; 86*3ec680e6SJackson Donaldson s->ctrl = 0x10000; 87*3ec680e6SJackson Donaldson } 88*3ec680e6SJackson Donaldson 89*3ec680e6SJackson Donaldson static void max78000_icc_init(Object *obj) 90*3ec680e6SJackson Donaldson { 91*3ec680e6SJackson Donaldson Max78000IccState *s = MAX78000_ICC(obj); 92*3ec680e6SJackson Donaldson 93*3ec680e6SJackson Donaldson memory_region_init_io(&s->mmio, obj, &max78000_icc_ops, s, 94*3ec680e6SJackson Donaldson TYPE_MAX78000_ICC, 0x800); 95*3ec680e6SJackson Donaldson sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); 96*3ec680e6SJackson Donaldson } 97*3ec680e6SJackson Donaldson 98*3ec680e6SJackson Donaldson static void max78000_icc_class_init(ObjectClass *klass, const void *data) 99*3ec680e6SJackson Donaldson { 100*3ec680e6SJackson Donaldson DeviceClass *dc = DEVICE_CLASS(klass); 101*3ec680e6SJackson Donaldson ResettableClass *rc = RESETTABLE_CLASS(klass); 102*3ec680e6SJackson Donaldson 103*3ec680e6SJackson Donaldson rc->phases.hold = max78000_icc_reset_hold; 104*3ec680e6SJackson Donaldson dc->vmsd = &max78000_icc_vmstate; 105*3ec680e6SJackson Donaldson } 106*3ec680e6SJackson Donaldson 107*3ec680e6SJackson Donaldson static const TypeInfo max78000_icc_info = { 108*3ec680e6SJackson Donaldson .name = TYPE_MAX78000_ICC, 109*3ec680e6SJackson Donaldson .parent = TYPE_SYS_BUS_DEVICE, 110*3ec680e6SJackson Donaldson .instance_size = sizeof(Max78000IccState), 111*3ec680e6SJackson Donaldson .instance_init = max78000_icc_init, 112*3ec680e6SJackson Donaldson .class_init = max78000_icc_class_init, 113*3ec680e6SJackson Donaldson }; 114*3ec680e6SJackson Donaldson 115*3ec680e6SJackson Donaldson static void max78000_icc_register_types(void) 116*3ec680e6SJackson Donaldson { 117*3ec680e6SJackson Donaldson type_register_static(&max78000_icc_info); 118*3ec680e6SJackson Donaldson } 119*3ec680e6SJackson Donaldson 120*3ec680e6SJackson Donaldson type_init(max78000_icc_register_types) 121