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