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