xref: /openbmc/qemu/hw/arm/stm32l4x5_soc.c (revision d884e272)
1 /*
2  * STM32L4x5 SoC family
3  *
4  * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5  * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  *
12  * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
13  * Original code is licensed under the MIT License:
14  *
15  * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
16  */
17 
18 /*
19  * The reference used is the STMicroElectronics RM0351 Reference manual
20  * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
21  * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
22  */
23 
24 #include "qemu/osdep.h"
25 #include "qemu/units.h"
26 #include "qapi/error.h"
27 #include "exec/address-spaces.h"
28 #include "sysemu/sysemu.h"
29 #include "hw/or-irq.h"
30 #include "hw/arm/stm32l4x5_soc.h"
31 #include "hw/gpio/stm32l4x5_gpio.h"
32 #include "hw/qdev-clock.h"
33 #include "hw/misc/unimp.h"
34 
35 #define FLASH_BASE_ADDRESS 0x08000000
36 #define SRAM1_BASE_ADDRESS 0x20000000
37 #define SRAM1_SIZE (96 * KiB)
38 #define SRAM2_BASE_ADDRESS 0x10000000
39 #define SRAM2_SIZE (32 * KiB)
40 
41 #define EXTI_ADDR 0x40010400
42 #define SYSCFG_ADDR 0x40010000
43 
44 #define NUM_EXTI_IRQ 40
45 /* Match exti line connections with their CPU IRQ number */
46 /* See Vector Table (Reference Manual p.396) */
47 /*
48  * Some IRQs are connected to the same CPU IRQ (denoted by -1)
49  * and require an intermediary OR gate to function correctly.
50  */
51 static const int exti_irq[NUM_EXTI_IRQ] = {
52     6,                      /* GPIO[0]                 */
53     7,                      /* GPIO[1]                 */
54     8,                      /* GPIO[2]                 */
55     9,                      /* GPIO[3]                 */
56     10,                     /* GPIO[4]                 */
57     -1, -1, -1, -1, -1,     /* GPIO[5..9] OR gate 23   */
58     -1, -1, -1, -1, -1, -1, /* GPIO[10..15] OR gate 40 */
59     -1,                     /* PVD OR gate 1           */
60     67,                     /* OTG_FS_WKUP, Direct     */
61     41,                     /* RTC_ALARM               */
62     2,                      /* RTC_TAMP_STAMP2/CSS_LSE */
63     3,                      /* RTC wakeup timer        */
64     -1, -1,                 /* COMP[1..2] OR gate 63   */
65     31,                     /* I2C1 wakeup, Direct     */
66     33,                     /* I2C2 wakeup, Direct     */
67     72,                     /* I2C3 wakeup, Direct     */
68     37,                     /* USART1 wakeup, Direct   */
69     38,                     /* USART2 wakeup, Direct   */
70     39,                     /* USART3 wakeup, Direct   */
71     52,                     /* UART4 wakeup, Direct    */
72     53,                     /* UART4 wakeup, Direct    */
73     70,                     /* LPUART1 wakeup, Direct  */
74     65,                     /* LPTIM1, Direct          */
75     66,                     /* LPTIM2, Direct          */
76     76,                     /* SWPMI1 wakeup, Direct   */
77     -1, -1, -1, -1,         /* PVM[1..4] OR gate 1     */
78     78                      /* LCD wakeup, Direct      */
79 };
80 #define RCC_BASE_ADDRESS 0x40021000
81 #define RCC_IRQ 5
82 
83 static const int exti_or_gates_out[NUM_EXTI_OR_GATES] = {
84     23, 40, 63, 1,
85 };
86 
87 static const int exti_or_gates_num_lines_in[NUM_EXTI_OR_GATES] = {
88     5, 6, 2, 5,
89 };
90 
91 /* 3 OR gates with consecutive inputs */
92 #define NUM_EXTI_SIMPLE_OR_GATES 3
93 static const int exti_or_gates_first_line_in[NUM_EXTI_SIMPLE_OR_GATES] = {
94     5, 10, 21,
95 };
96 
97 /* 1 OR gate with non-consecutive inputs */
98 #define EXTI_OR_GATE1_NUM_LINES_IN 5
99 static const int exti_or_gate1_lines_in[EXTI_OR_GATE1_NUM_LINES_IN] = {
100     16, 35, 36, 37, 38,
101 };
102 
103 static const struct {
104     uint32_t addr;
105     uint32_t moder_reset;
106     uint32_t ospeedr_reset;
107     uint32_t pupdr_reset;
108 } stm32l4x5_gpio_cfg[NUM_GPIOS] = {
109     { 0x48000000, 0xABFFFFFF, 0x0C000000, 0x64000000 },
110     { 0x48000400, 0xFFFFFEBF, 0x00000000, 0x00000100 },
111     { 0x48000800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
112     { 0x48000C00, 0xFFFFFFFF, 0x00000000, 0x00000000 },
113     { 0x48001000, 0xFFFFFFFF, 0x00000000, 0x00000000 },
114     { 0x48001400, 0xFFFFFFFF, 0x00000000, 0x00000000 },
115     { 0x48001800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
116     { 0x48001C00, 0x0000000F, 0x00000000, 0x00000000 },
117 };
118 
119 static void stm32l4x5_soc_initfn(Object *obj)
120 {
121     Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
122 
123     object_initialize_child(obj, "exti", &s->exti, TYPE_STM32L4X5_EXTI);
124     for (unsigned i = 0; i < NUM_EXTI_OR_GATES; i++) {
125         object_initialize_child(obj, "exti_or_gates[*]", &s->exti_or_gates[i],
126                                 TYPE_OR_IRQ);
127     }
128     object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_STM32L4X5_SYSCFG);
129     object_initialize_child(obj, "rcc", &s->rcc, TYPE_STM32L4X5_RCC);
130 
131     for (unsigned i = 0; i < NUM_GPIOS; i++) {
132         g_autofree char *name = g_strdup_printf("gpio%c", 'a' + i);
133         object_initialize_child(obj, name, &s->gpio[i], TYPE_STM32L4X5_GPIO);
134     }
135 }
136 
137 static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
138 {
139     ERRP_GUARD();
140     Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
141     const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
142     MemoryRegion *system_memory = get_system_memory();
143     DeviceState *armv7m, *dev;
144     SysBusDevice *busdev;
145     uint32_t pin_index;
146 
147     if (!memory_region_init_rom(&s->flash, OBJECT(dev_soc), "flash",
148                                 sc->flash_size, errp)) {
149         return;
150     }
151     memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc),
152                              "flash_boot_alias", &s->flash, 0,
153                              sc->flash_size);
154 
155     memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
156     memory_region_add_subregion(system_memory, 0, &s->flash_alias);
157 
158     if (!memory_region_init_ram(&s->sram1, OBJECT(dev_soc), "SRAM1", SRAM1_SIZE,
159                                 errp)) {
160         return;
161     }
162     memory_region_add_subregion(system_memory, SRAM1_BASE_ADDRESS, &s->sram1);
163 
164     if (!memory_region_init_ram(&s->sram2, OBJECT(dev_soc), "SRAM2", SRAM2_SIZE,
165                                 errp)) {
166         return;
167     }
168     memory_region_add_subregion(system_memory, SRAM2_BASE_ADDRESS, &s->sram2);
169 
170     object_initialize_child(OBJECT(dev_soc), "armv7m", &s->armv7m, TYPE_ARMV7M);
171     armv7m = DEVICE(&s->armv7m);
172     qdev_prop_set_uint32(armv7m, "num-irq", 96);
173     qdev_prop_set_uint32(armv7m, "num-prio-bits", 4);
174     qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
175     qdev_prop_set_bit(armv7m, "enable-bitband", true);
176     qdev_connect_clock_in(armv7m, "cpuclk",
177         qdev_get_clock_out(DEVICE(&(s->rcc)), "cortex-fclk-out"));
178     qdev_connect_clock_in(armv7m, "refclk",
179         qdev_get_clock_out(DEVICE(&(s->rcc)), "cortex-refclk-out"));
180     object_property_set_link(OBJECT(&s->armv7m), "memory",
181                              OBJECT(system_memory), &error_abort);
182     if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {
183         return;
184     }
185 
186     /* GPIOs */
187     for (unsigned i = 0; i < NUM_GPIOS; i++) {
188         g_autofree char *name = g_strdup_printf("%c", 'A' + i);
189         dev = DEVICE(&s->gpio[i]);
190         qdev_prop_set_string(dev, "name", name);
191         qdev_prop_set_uint32(dev, "mode-reset",
192                              stm32l4x5_gpio_cfg[i].moder_reset);
193         qdev_prop_set_uint32(dev, "ospeed-reset",
194                              stm32l4x5_gpio_cfg[i].ospeedr_reset);
195         qdev_prop_set_uint32(dev, "pupd-reset",
196                             stm32l4x5_gpio_cfg[i].pupdr_reset);
197         busdev = SYS_BUS_DEVICE(&s->gpio[i]);
198         g_free(name);
199         name = g_strdup_printf("gpio%c-out", 'a' + i);
200         qdev_connect_clock_in(DEVICE(&s->gpio[i]), "clk",
201             qdev_get_clock_out(DEVICE(&(s->rcc)), name));
202         if (!sysbus_realize(busdev, errp)) {
203             return;
204         }
205         sysbus_mmio_map(busdev, 0, stm32l4x5_gpio_cfg[i].addr);
206     }
207 
208     /* System configuration controller */
209     busdev = SYS_BUS_DEVICE(&s->syscfg);
210     if (!sysbus_realize(busdev, errp)) {
211         return;
212     }
213     sysbus_mmio_map(busdev, 0, SYSCFG_ADDR);
214 
215     for (unsigned i = 0; i < NUM_GPIOS; i++) {
216         for (unsigned j = 0; j < GPIO_NUM_PINS; j++) {
217             pin_index = GPIO_NUM_PINS * i + j;
218             qdev_connect_gpio_out(DEVICE(&s->gpio[i]), j,
219                                   qdev_get_gpio_in(DEVICE(&s->syscfg),
220                                   pin_index));
221         }
222     }
223 
224     /* EXTI device */
225     busdev = SYS_BUS_DEVICE(&s->exti);
226     if (!sysbus_realize(busdev, errp)) {
227         return;
228     }
229     sysbus_mmio_map(busdev, 0, EXTI_ADDR);
230 
231     /* IRQs with fan-in that require an OR gate */
232     for (unsigned i = 0; i < NUM_EXTI_OR_GATES; i++) {
233         if (!object_property_set_int(OBJECT(&s->exti_or_gates[i]), "num-lines",
234                                      exti_or_gates_num_lines_in[i], errp)) {
235             return;
236         }
237         if (!qdev_realize(DEVICE(&s->exti_or_gates[i]), NULL, errp)) {
238             return;
239         }
240 
241         qdev_connect_gpio_out(DEVICE(&s->exti_or_gates[i]), 0,
242             qdev_get_gpio_in(armv7m, exti_or_gates_out[i]));
243 
244         if (i < NUM_EXTI_SIMPLE_OR_GATES) {
245             /* consecutive inputs for OR gates 23, 40, 63 */
246             for (unsigned j = 0; j < exti_or_gates_num_lines_in[i]; j++) {
247                 sysbus_connect_irq(SYS_BUS_DEVICE(&s->exti),
248                     exti_or_gates_first_line_in[i] + j,
249                     qdev_get_gpio_in(DEVICE(&s->exti_or_gates[i]), j));
250             }
251         } else {
252             /* non-consecutive inputs for OR gate 1 */
253             for (unsigned j = 0; j < EXTI_OR_GATE1_NUM_LINES_IN; j++) {
254                 sysbus_connect_irq(SYS_BUS_DEVICE(&s->exti),
255                     exti_or_gate1_lines_in[j],
256                     qdev_get_gpio_in(DEVICE(&s->exti_or_gates[i]), j));
257             }
258         }
259     }
260 
261     /* IRQs that don't require fan-in */
262     for (unsigned i = 0; i < NUM_EXTI_IRQ; i++) {
263         if (exti_irq[i] != -1) {
264             sysbus_connect_irq(busdev, i,
265                                qdev_get_gpio_in(armv7m, exti_irq[i]));
266         }
267     }
268 
269     for (unsigned i = 0; i < GPIO_NUM_PINS; i++) {
270         qdev_connect_gpio_out(DEVICE(&s->syscfg), i,
271                               qdev_get_gpio_in(DEVICE(&s->exti), i));
272     }
273 
274     /* RCC device */
275     busdev = SYS_BUS_DEVICE(&s->rcc);
276     if (!sysbus_realize(busdev, errp)) {
277         return;
278     }
279     sysbus_mmio_map(busdev, 0, RCC_BASE_ADDRESS);
280     sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, RCC_IRQ));
281 
282     /* APB1 BUS */
283     create_unimplemented_device("TIM2",      0x40000000, 0x400);
284     create_unimplemented_device("TIM3",      0x40000400, 0x400);
285     create_unimplemented_device("TIM4",      0x40000800, 0x400);
286     create_unimplemented_device("TIM5",      0x40000C00, 0x400);
287     create_unimplemented_device("TIM6",      0x40001000, 0x400);
288     create_unimplemented_device("TIM7",      0x40001400, 0x400);
289     /* RESERVED:    0x40001800, 0x1000 */
290     create_unimplemented_device("RTC",       0x40002800, 0x400);
291     create_unimplemented_device("WWDG",      0x40002C00, 0x400);
292     create_unimplemented_device("IWDG",      0x40003000, 0x400);
293     /* RESERVED:    0x40001800, 0x400 */
294     create_unimplemented_device("SPI2",      0x40003800, 0x400);
295     create_unimplemented_device("SPI3",      0x40003C00, 0x400);
296     /* RESERVED:    0x40004000, 0x400 */
297     create_unimplemented_device("USART2",    0x40004400, 0x400);
298     create_unimplemented_device("USART3",    0x40004800, 0x400);
299     create_unimplemented_device("UART4",     0x40004C00, 0x400);
300     create_unimplemented_device("UART5",     0x40005000, 0x400);
301     create_unimplemented_device("I2C1",      0x40005400, 0x400);
302     create_unimplemented_device("I2C2",      0x40005800, 0x400);
303     create_unimplemented_device("I2C3",      0x40005C00, 0x400);
304     /* RESERVED:    0x40006000, 0x400 */
305     create_unimplemented_device("CAN1",      0x40006400, 0x400);
306     /* RESERVED:    0x40006800, 0x400 */
307     create_unimplemented_device("PWR",       0x40007000, 0x400);
308     create_unimplemented_device("DAC1",      0x40007400, 0x400);
309     create_unimplemented_device("OPAMP",     0x40007800, 0x400);
310     create_unimplemented_device("LPTIM1",    0x40007C00, 0x400);
311     create_unimplemented_device("LPUART1",   0x40008000, 0x400);
312     /* RESERVED:    0x40008400, 0x400 */
313     create_unimplemented_device("SWPMI1",    0x40008800, 0x400);
314     /* RESERVED:    0x40008C00, 0x800 */
315     create_unimplemented_device("LPTIM2",    0x40009400, 0x400);
316     /* RESERVED:    0x40009800, 0x6800 */
317 
318     /* APB2 BUS */
319     create_unimplemented_device("VREFBUF",   0x40010030, 0x1D0);
320     create_unimplemented_device("COMP",      0x40010200, 0x200);
321     /* RESERVED:    0x40010800, 0x1400 */
322     create_unimplemented_device("FIREWALL",  0x40011C00, 0x400);
323     /* RESERVED:    0x40012000, 0x800 */
324     create_unimplemented_device("SDMMC1",    0x40012800, 0x400);
325     create_unimplemented_device("TIM1",      0x40012C00, 0x400);
326     create_unimplemented_device("SPI1",      0x40013000, 0x400);
327     create_unimplemented_device("TIM8",      0x40013400, 0x400);
328     create_unimplemented_device("USART1",    0x40013800, 0x400);
329     /* RESERVED:    0x40013C00, 0x400 */
330     create_unimplemented_device("TIM15",     0x40014000, 0x400);
331     create_unimplemented_device("TIM16",     0x40014400, 0x400);
332     create_unimplemented_device("TIM17",     0x40014800, 0x400);
333     /* RESERVED:    0x40014C00, 0x800 */
334     create_unimplemented_device("SAI1",      0x40015400, 0x400);
335     create_unimplemented_device("SAI2",      0x40015800, 0x400);
336     /* RESERVED:    0x40015C00, 0x400 */
337     create_unimplemented_device("DFSDM1",    0x40016000, 0x400);
338     /* RESERVED:    0x40016400, 0x9C00 */
339 
340     /* AHB1 BUS */
341     create_unimplemented_device("DMA1",      0x40020000, 0x400);
342     create_unimplemented_device("DMA2",      0x40020400, 0x400);
343     /* RESERVED:    0x40020800, 0x800 */
344     /* RESERVED:    0x40021400, 0xC00 */
345     create_unimplemented_device("FLASH",     0x40022000, 0x400);
346     /* RESERVED:    0x40022400, 0xC00 */
347     create_unimplemented_device("CRC",       0x40023000, 0x400);
348     /* RESERVED:    0x40023400, 0x400 */
349     create_unimplemented_device("TSC",       0x40024000, 0x400);
350 
351     /* RESERVED:    0x40024400, 0x7FDBC00 */
352 
353     /* AHB2 BUS */
354     /* RESERVED:    0x48002000, 0x7FDBC00 */
355     create_unimplemented_device("OTG_FS",    0x50000000, 0x40000);
356     create_unimplemented_device("ADC",       0x50040000, 0x400);
357     /* RESERVED:    0x50040400, 0x20400 */
358     create_unimplemented_device("RNG",       0x50060800, 0x400);
359 
360     /* AHB3 BUS */
361     create_unimplemented_device("FMC",       0xA0000000, 0x1000);
362     create_unimplemented_device("QUADSPI",   0xA0001000, 0x400);
363 }
364 
365 static void stm32l4x5_soc_class_init(ObjectClass *klass, void *data)
366 {
367 
368     DeviceClass *dc = DEVICE_CLASS(klass);
369 
370     dc->realize = stm32l4x5_soc_realize;
371     /* Reason: Mapped at fixed location on the system bus */
372     dc->user_creatable = false;
373     /* No vmstate or reset required: device has no internal state */
374 }
375 
376 static void stm32l4x5xc_soc_class_init(ObjectClass *oc, void *data)
377 {
378     Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
379 
380     ssc->flash_size = 256 * KiB;
381 }
382 
383 static void stm32l4x5xe_soc_class_init(ObjectClass *oc, void *data)
384 {
385     Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
386 
387     ssc->flash_size = 512 * KiB;
388 }
389 
390 static void stm32l4x5xg_soc_class_init(ObjectClass *oc, void *data)
391 {
392     Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
393 
394     ssc->flash_size = 1 * MiB;
395 }
396 
397 static const TypeInfo stm32l4x5_soc_types[] = {
398     {
399         .name           = TYPE_STM32L4X5XC_SOC,
400         .parent         = TYPE_STM32L4X5_SOC,
401         .class_init     = stm32l4x5xc_soc_class_init,
402     }, {
403         .name           = TYPE_STM32L4X5XE_SOC,
404         .parent         = TYPE_STM32L4X5_SOC,
405         .class_init     = stm32l4x5xe_soc_class_init,
406     }, {
407         .name           = TYPE_STM32L4X5XG_SOC,
408         .parent         = TYPE_STM32L4X5_SOC,
409         .class_init     = stm32l4x5xg_soc_class_init,
410     }, {
411         .name           = TYPE_STM32L4X5_SOC,
412         .parent         = TYPE_SYS_BUS_DEVICE,
413         .instance_size  = sizeof(Stm32l4x5SocState),
414         .instance_init  = stm32l4x5_soc_initfn,
415         .class_size     = sizeof(Stm32l4x5SocClass),
416         .class_init     = stm32l4x5_soc_class_init,
417         .abstract       = true,
418     }
419 };
420 
421 DEFINE_TYPES(stm32l4x5_soc_types)
422