xref: /openbmc/qemu/hw/misc/max78000_gcr.c (revision a017f53e093a9018e33fb33bbdaa322c2de3dbe7)
1 /*
2  * MAX78000 Global Control Registers
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 "system/runstate.h"
14 #include "migration/vmstate.h"
15 #include "hw/qdev-properties.h"
16 #include "hw/char/max78000_uart.h"
17 #include "hw/misc/max78000_gcr.h"
18 
19 
20 static void max78000_gcr_reset_hold(Object *obj, ResetType type)
21 {
22     DeviceState *dev = DEVICE(obj);
23     Max78000GcrState *s = MAX78000_GCR(dev);
24     s->sysctrl = 0x21002;
25     s->rst0 = 0;
26     /* All clocks are always ready */
27     s->clkctrl = 0x3e140008;
28     s->pm = 0x3f000;
29     s->pclkdiv = 0;
30     s->pclkdis0 = 0xffffffff;
31     s->memctrl = 0x5;
32     s->memz = 0;
33     s->sysst = 0;
34     s->rst1 = 0;
35     s->pckdis1 = 0xffffffff;
36     s->eventen = 0;
37     s->revision = 0xa1;
38     s->sysie = 0;
39     s->eccerr = 0;
40     s->ecced = 0;
41     s->eccie = 0;
42     s->eccaddr = 0;
43 }
44 
45 static uint64_t max78000_gcr_read(void *opaque, hwaddr addr,
46                                      unsigned int size)
47 {
48     Max78000GcrState *s = opaque;
49 
50     switch (addr) {
51     case SYSCTRL:
52         return s->sysctrl;
53 
54     case RST0:
55         return s->rst0;
56 
57     case CLKCTRL:
58         return s->clkctrl;
59 
60     case PM:
61         return s->pm;
62 
63     case PCLKDIV:
64         return s->pclkdiv;
65 
66     case PCLKDIS0:
67         return s->pclkdis0;
68 
69     case MEMCTRL:
70         return s->memctrl;
71 
72     case MEMZ:
73         return s->memz;
74 
75     case SYSST:
76         return s->sysst;
77 
78     case RST1:
79         return s->rst1;
80 
81     case PCKDIS1:
82         return s->pckdis1;
83 
84     case EVENTEN:
85         return s->eventen;
86 
87     case REVISION:
88         return s->revision;
89 
90     case SYSIE:
91         return s->sysie;
92 
93     case ECCERR:
94         return s->eccerr;
95 
96     case ECCED:
97         return s->ecced;
98 
99     case ECCIE:
100         return s->eccie;
101 
102     case ECCADDR:
103         return s->eccaddr;
104 
105     default:
106         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"
107             HWADDR_PRIx "\n", __func__, addr);
108         return 0;
109 
110     }
111 }
112 
113 static void max78000_gcr_write(void *opaque, hwaddr addr,
114                        uint64_t val64, unsigned int size)
115 {
116     Max78000GcrState *s = opaque;
117     uint32_t val = val64;
118     uint8_t zero[0xc000] = {0};
119     switch (addr) {
120     case SYSCTRL:
121         /* Checksum calculations always pass immediately */
122         s->sysctrl = (val & 0x30000) | 0x1002;
123         break;
124 
125     case RST0:
126         if (val & SYSTEM_RESET) {
127             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
128         }
129         if (val & PERIPHERAL_RESET) {
130             /*
131              * Peripheral reset resets all peripherals. The CPU
132              * retains its state. The GPIO, watchdog timers, AoD,
133              * RAM retention, and general control registers (GCR),
134              * including the clock configuration, are unaffected.
135              */
136             val = UART2_RESET | UART1_RESET | UART0_RESET |
137                     ADC_RESET | CNN_RESET | TRNG_RESET |
138                     RTC_RESET | I2C0_RESET | SPI1_RESET |
139                     TMR3_RESET | TMR2_RESET | TMR1_RESET |
140                     TMR0_RESET | WDT0_RESET | DMA_RESET;
141         }
142         if (val & SOFT_RESET) {
143             /* Soft reset also resets GPIO */
144             val = UART2_RESET | UART1_RESET | UART0_RESET |
145                     ADC_RESET | CNN_RESET | TRNG_RESET |
146                     RTC_RESET | I2C0_RESET | SPI1_RESET |
147                     TMR3_RESET | TMR2_RESET | TMR1_RESET |
148                     TMR0_RESET | GPIO1_RESET | GPIO0_RESET |
149                     DMA_RESET;
150         }
151         if (val & UART2_RESET) {
152             device_cold_reset(s->uart2);
153         }
154         if (val & UART1_RESET) {
155             device_cold_reset(s->uart1);
156         }
157         if (val & UART0_RESET) {
158             device_cold_reset(s->uart0);
159         }
160         /* TODO: As other devices are implemented, add them here */
161         break;
162 
163     case CLKCTRL:
164         s->clkctrl = val | SYSCLK_RDY;
165         break;
166 
167     case PM:
168         s->pm = val;
169         break;
170 
171     case PCLKDIV:
172         s->pclkdiv = val;
173         break;
174 
175     case PCLKDIS0:
176         s->pclkdis0 = val;
177         break;
178 
179     case MEMCTRL:
180         s->memctrl = val;
181         break;
182 
183     case MEMZ:
184         if (val & ram0) {
185             address_space_write(&s->sram_as, SYSRAM0_START,
186                                 MEMTXATTRS_UNSPECIFIED, zero, 0x8000);
187         }
188         if (val & ram1) {
189             address_space_write(&s->sram_as, SYSRAM1_START,
190                                 MEMTXATTRS_UNSPECIFIED, zero, 0x8000);
191         }
192         if (val & ram2) {
193             address_space_write(&s->sram_as, SYSRAM2_START,
194                                 MEMTXATTRS_UNSPECIFIED, zero, 0xC000);
195         }
196         if (val & ram3) {
197             address_space_write(&s->sram_as, SYSRAM3_START,
198                                 MEMTXATTRS_UNSPECIFIED, zero, 0x4000);
199         }
200         break;
201 
202     case SYSST:
203         s->sysst = val;
204         break;
205 
206     case RST1:
207         /* TODO: As other devices are implemented, add them here */
208         s->rst1 = val;
209         break;
210 
211     case PCKDIS1:
212         s->pckdis1 = val;
213         break;
214 
215     case EVENTEN:
216         s->eventen = val;
217         break;
218 
219     case REVISION:
220         s->revision = val;
221         break;
222 
223     case SYSIE:
224         s->sysie = val;
225         break;
226 
227     case ECCERR:
228         s->eccerr = val;
229         break;
230 
231     case ECCED:
232         s->ecced = val;
233         break;
234 
235     case ECCIE:
236         s->eccie = val;
237         break;
238 
239     case ECCADDR:
240         s->eccaddr = val;
241         break;
242 
243     default:
244         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
245                       __func__, addr);
246         break;
247 
248     }
249 }
250 
251 static const Property max78000_gcr_properties[] = {
252     DEFINE_PROP_LINK("sram", Max78000GcrState, sram,
253                      TYPE_MEMORY_REGION, MemoryRegion*),
254     DEFINE_PROP_LINK("uart0", Max78000GcrState, uart0,
255                      TYPE_MAX78000_UART, DeviceState*),
256     DEFINE_PROP_LINK("uart1", Max78000GcrState, uart1,
257                      TYPE_MAX78000_UART, DeviceState*),
258     DEFINE_PROP_LINK("uart2", Max78000GcrState, uart2,
259                      TYPE_MAX78000_UART, DeviceState*),
260 };
261 
262 static const MemoryRegionOps max78000_gcr_ops = {
263     .read = max78000_gcr_read,
264     .write = max78000_gcr_write,
265     .endianness = DEVICE_LITTLE_ENDIAN,
266     .valid.min_access_size = 4,
267     .valid.max_access_size = 4,
268 };
269 
270 static const VMStateDescription vmstate_max78000_gcr = {
271     .name = TYPE_MAX78000_GCR,
272     .version_id = 1,
273     .minimum_version_id = 1,
274     .fields = (const VMStateField[]) {
275         VMSTATE_UINT32(sysctrl, Max78000GcrState),
276         VMSTATE_UINT32(rst0, Max78000GcrState),
277         VMSTATE_UINT32(clkctrl, Max78000GcrState),
278         VMSTATE_UINT32(pm, Max78000GcrState),
279         VMSTATE_UINT32(pclkdiv, Max78000GcrState),
280         VMSTATE_UINT32(pclkdis0, Max78000GcrState),
281         VMSTATE_UINT32(memctrl, Max78000GcrState),
282         VMSTATE_UINT32(memz, Max78000GcrState),
283         VMSTATE_UINT32(sysst, Max78000GcrState),
284         VMSTATE_UINT32(rst1, Max78000GcrState),
285         VMSTATE_UINT32(pckdis1, Max78000GcrState),
286         VMSTATE_UINT32(eventen, Max78000GcrState),
287         VMSTATE_UINT32(revision, Max78000GcrState),
288         VMSTATE_UINT32(sysie, Max78000GcrState),
289         VMSTATE_UINT32(eccerr, Max78000GcrState),
290         VMSTATE_UINT32(ecced, Max78000GcrState),
291         VMSTATE_UINT32(eccie, Max78000GcrState),
292         VMSTATE_UINT32(eccaddr, Max78000GcrState),
293         VMSTATE_END_OF_LIST()
294     }
295 };
296 
297 static void max78000_gcr_init(Object *obj)
298 {
299     Max78000GcrState *s = MAX78000_GCR(obj);
300 
301     memory_region_init_io(&s->mmio, obj, &max78000_gcr_ops, s,
302                           TYPE_MAX78000_GCR, 0x400);
303     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
304 
305 }
306 
307 static void max78000_gcr_realize(DeviceState *dev, Error **errp)
308 {
309     Max78000GcrState *s = MAX78000_GCR(dev);
310 
311     address_space_init(&s->sram_as, s->sram, "sram");
312 }
313 
314 static void max78000_gcr_class_init(ObjectClass *klass, const void *data)
315 {
316     DeviceClass *dc = DEVICE_CLASS(klass);
317     ResettableClass *rc = RESETTABLE_CLASS(klass);
318 
319     device_class_set_props(dc, max78000_gcr_properties);
320 
321     dc->realize = max78000_gcr_realize;
322     dc->vmsd = &vmstate_max78000_gcr;
323     rc->phases.hold = max78000_gcr_reset_hold;
324 }
325 
326 static const TypeInfo max78000_gcr_info = {
327     .name          = TYPE_MAX78000_GCR,
328     .parent        = TYPE_SYS_BUS_DEVICE,
329     .instance_size = sizeof(Max78000GcrState),
330     .instance_init = max78000_gcr_init,
331     .class_init     = max78000_gcr_class_init,
332 };
333 
334 static void max78000_gcr_register_types(void)
335 {
336     type_register_static(&max78000_gcr_info);
337 }
338 
339 type_init(max78000_gcr_register_types)
340