aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/stm32f205_soc.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/stm32f205_soc.c')
-rw-r--r--hw/arm/stm32f205_soc.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index 9cd41bf..c6b75a3 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -29,6 +29,7 @@
#include "exec/address-spaces.h"
#include "hw/arm/stm32f205_soc.h"
#include "hw/qdev-properties.h"
+#include "hw/qdev-clock.h"
#include "sysemu/sysemu.h"
/* At the moment only Timer 2 to 5 are modelled */
@@ -74,6 +75,9 @@ static void stm32f205_soc_initfn(Object *obj)
for (i = 0; i < STM_NUM_SPIS; i++) {
object_initialize_child(obj, "spi[*]", &s->spi[i], TYPE_STM32F2XX_SPI);
}
+
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+ s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);
}
static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
@@ -84,26 +88,49 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
int i;
MemoryRegion *system_memory = get_system_memory();
- MemoryRegion *sram = g_new(MemoryRegion, 1);
- MemoryRegion *flash = g_new(MemoryRegion, 1);
- MemoryRegion *flash_alias = g_new(MemoryRegion, 1);
- memory_region_init_rom(flash, OBJECT(dev_soc), "STM32F205.flash",
+ /*
+ * We use s->refclk internally and only define it with qdev_init_clock_in()
+ * so it is correctly parented and not leaked on an init/deinit; it is not
+ * intended as an externally exposed clock.
+ */
+ if (clock_has_source(s->refclk)) {
+ error_setg(errp, "refclk clock must not be wired up by the board code");
+ return;
+ }
+
+ if (!clock_has_source(s->sysclk)) {
+ error_setg(errp, "sysclk clock must be wired up by the board code");
+ return;
+ }
+
+ /*
+ * TODO: ideally we should model the SoC RCC and its ability to
+ * change the sysclk frequency and define different sysclk sources.
+ */
+
+ /* The refclk always runs at frequency HCLK / 8 */
+ clock_set_mul_div(s->refclk, 8, 1);
+ clock_set_source(s->refclk, s->sysclk);
+
+ memory_region_init_rom(&s->flash, OBJECT(dev_soc), "STM32F205.flash",
FLASH_SIZE, &error_fatal);
- memory_region_init_alias(flash_alias, OBJECT(dev_soc),
- "STM32F205.flash.alias", flash, 0, FLASH_SIZE);
+ memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc),
+ "STM32F205.flash.alias", &s->flash, 0, FLASH_SIZE);
- memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
- memory_region_add_subregion(system_memory, 0, flash_alias);
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
+ memory_region_add_subregion(system_memory, 0, &s->flash_alias);
- memory_region_init_ram(sram, NULL, "STM32F205.sram", SRAM_SIZE,
+ memory_region_init_ram(&s->sram, NULL, "STM32F205.sram", SRAM_SIZE,
&error_fatal);
- memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
+ memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, &s->sram);
armv7m = DEVICE(&s->armv7m);
qdev_prop_set_uint32(armv7m, "num-irq", 96);
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
qdev_prop_set_bit(armv7m, "enable-bitband", true);
+ qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
+ qdev_connect_clock_in(armv7m, "refclk", s->refclk);
object_property_set_link(OBJECT(&s->armv7m), "memory",
OBJECT(get_system_memory()), &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {