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