static void stm32l152rbt6_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { //Préparation de la mémoire MemoryRegion *address_space_mem = get_system_memory(); uint16_t flash_size = stm32_board.f_size; //128KBits uint16_t sram_size = 0x0010; //16 KBits //Initialisation du processeur (+ mémoire) qemu_irq* pic = armv7m_init(address_space_mem, flash_size, sram_size, kernel_filename, cpu_model); stm32l_sys_init(0x1FF00000, pic[28], &stm32_board); //FIXME: Vérifier l'implémentation de la sys memory //Structures GPIO static const uint32_t gpio_addr[NB_GPIO] = { 0x40020000, //GPIO_A 0x40020400, //GPIO_B 0x40020800, //GPIO_C 0x40020C00, //GPIO_D 0x40021000, //GPIO_E 0x40021400 //GPIO_H }; // static const int gpio_idIrqNVIC[NB_NVIC_IRQ] = {6,7,8,9,10}; DeviceState* gpio_dev[NB_GPIO]; //Création du bouton DeviceState* button = sysbus_create_simple("stm32_button", -1, NULL); //Création des leds DeviceState* led_dev6 = sysbus_create_simple("stm32_led_blue", -1, NULL); DeviceState* led_dev7 = sysbus_create_simple("stm32_led_green", -1, NULL); //Initialisation du GPIO_A gpio_dev[GPIO_A] = sysbus_create_varargs("stm32_gpio_A", gpio_addr[GPIO_A], NULL); //, pic[gpio_idIrqNVIC[0]], pic[gpio_idIrqNVIC[1]], pic[gpio_idIrqNVIC[2]], pic[gpio_idIrqNVIC[3]], pic[gpio_idIrqNVIC[4]], NULL); qemu_irq entreeBouton = qdev_get_gpio_in(gpio_dev[GPIO_A], 0); qdev_connect_gpio_out(button, 0, entreeBouton); //Initialisation du GPIO_B gpio_dev[GPIO_B] = sysbus_create_varargs("stm32_gpio_B", gpio_addr[GPIO_B], NULL); //, pic[gpio_idIrqNVIC[0]], pic[gpio_idIrqNVIC[1]], pic[gpio_idIrqNVIC[2]], pic[gpio_idIrqNVIC[3]], pic[gpio_idIrqNVIC[4]], NULL); qemu_irq entreeLED6 = qdev_get_gpio_in(led_dev6, 0); qdev_connect_gpio_out(gpio_dev[GPIO_B], 6, entreeLED6); qemu_irq entreeLED7 = qdev_get_gpio_in(led_dev7, 0); qdev_connect_gpio_out(gpio_dev[GPIO_B], 7, entreeLED7); }
static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) { STM32F205State *s = STM32F205_SOC(dev_soc); DeviceState *syscfgdev, *usartdev, *timerdev, *nvic; SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev; Error *err = NULL; 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_ram(flash, NULL, "STM32F205.flash", FLASH_SIZE, &error_fatal); memory_region_init_alias(flash_alias, NULL, "STM32F205.flash.alias", flash, 0, FLASH_SIZE); vmstate_register_ram_global(flash); memory_region_set_readonly(flash, true); memory_region_set_readonly(flash_alias, true); memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash); memory_region_add_subregion(system_memory, 0, flash_alias); memory_region_init_ram(sram, NULL, "STM32F205.sram", SRAM_SIZE, &error_fatal); vmstate_register_ram_global(sram); memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram); nvic = armv7m_init(get_system_memory(), FLASH_SIZE, 96, s->kernel_filename, s->cpu_model); /* System configuration controller */ syscfgdev = DEVICE(&s->syscfg); object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } syscfgbusdev = SYS_BUS_DEVICE(syscfgdev); sysbus_mmio_map(syscfgbusdev, 0, 0x40013800); sysbus_connect_irq(syscfgbusdev, 0, qdev_get_gpio_in(nvic, 71)); /* Attach UART (uses USART registers) and USART controllers */ for (i = 0; i < STM_NUM_USARTS; i++) { usartdev = DEVICE(&(s->usart[i])); object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } usartbusdev = SYS_BUS_DEVICE(usartdev); sysbus_mmio_map(usartbusdev, 0, usart_addr[i]); sysbus_connect_irq(usartbusdev, 0, qdev_get_gpio_in(nvic, usart_irq[i])); } /* Timer 2 to 5 */ for (i = 0; i < STM_NUM_TIMERS; i++) { timerdev = DEVICE(&(s->timer[i])); qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000); object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } timerbusdev = SYS_BUS_DEVICE(timerdev); sysbus_mmio_map(timerbusdev, 0, timer_addr[i]); sysbus_connect_irq(timerbusdev, 0, qdev_get_gpio_in(nvic, timer_irq[i])); } }
void stm32_init( ram_addr_t flash_size, ram_addr_t ram_size, const char *kernel_filename, uint32_t osc_freq, uint32_t osc32_freq) { MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *flash_alias_mem = g_malloc(sizeof(MemoryRegion)); qemu_irq *pic; int i; Object *stm32_container = container_get(qdev_get_machine(), "/stm32"); pic = armv7m_init( stm32_container, address_space_mem, flash_size, ram_size, kernel_filename, "cortex-m3"); /* The STM32 family stores its Flash memory at some base address in memory * (0x08000000 for medium density devices), and then aliases it to the * boot memory space, which starts at 0x00000000 (the "System Memory" can also * be aliased to 0x00000000, but this is not implemented here). The processor * executes the code in the aliased memory at 0x00000000. We need to make a * QEMU alias so that reads in the 0x08000000 area are passed through to the * 0x00000000 area. Note that this is the opposite of real hardware, where the * memory at 0x00000000 passes reads through the "real" flash memory at * 0x08000000, but it works the same either way. */ /* TODO: Parameterize the base address of the aliased memory. */ memory_region_init_alias( flash_alias_mem, NULL, "stm32-flash-alias-mem", address_space_mem, 0, flash_size); memory_region_add_subregion(address_space_mem, 0x08000000, flash_alias_mem); DeviceState *rcc_dev = qdev_create(NULL, "stm32-rcc"); qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); object_property_add_child(stm32_container, "rcc", OBJECT(rcc_dev), NULL); stm32_init_periph(rcc_dev, STM32_RCC_PERIPH, 0x40021000, pic[STM32_RCC_IRQ]); DeviceState **gpio_dev = (DeviceState **)g_malloc0(sizeof(DeviceState *) * STM32_GPIO_COUNT); for(i = 0; i < STM32_GPIO_COUNT; i++) { char child_name[8]; stm32_periph_t periph = STM32_GPIOA + i; gpio_dev[i] = qdev_create(NULL, TYPE_STM32_GPIO); QDEV_PROP_SET_PERIPH_T(gpio_dev[i], "periph", periph); qdev_prop_set_ptr(gpio_dev[i], "stm32_rcc", rcc_dev); snprintf(child_name, sizeof(child_name), "gpio[%c]", 'a' + i); object_property_add_child(stm32_container, child_name, OBJECT(gpio_dev[i]), NULL); stm32_init_periph(gpio_dev[i], periph, 0x40010800 + (i * 0x400), NULL); } DeviceState *exti_dev = qdev_create(NULL, TYPE_STM32_EXTI); object_property_add_child(stm32_container, "exti", OBJECT(exti_dev), NULL); stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40010400, NULL); SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); sysbus_connect_irq(exti_busdev, 0, pic[STM32_EXTI0_IRQ]); sysbus_connect_irq(exti_busdev, 1, pic[STM32_EXTI1_IRQ]); sysbus_connect_irq(exti_busdev, 2, pic[STM32_EXTI2_IRQ]); sysbus_connect_irq(exti_busdev, 3, pic[STM32_EXTI3_IRQ]); sysbus_connect_irq(exti_busdev, 4, pic[STM32_EXTI4_IRQ]); sysbus_connect_irq(exti_busdev, 5, pic[STM32_EXTI9_5_IRQ]); sysbus_connect_irq(exti_busdev, 6, pic[STM32_EXTI15_10_IRQ]); sysbus_connect_irq(exti_busdev, 7, pic[STM32_PVD_IRQ]); sysbus_connect_irq(exti_busdev, 8, pic[STM32_RTCAlarm_IRQ]); sysbus_connect_irq(exti_busdev, 9, pic[STM32_OTG_FS_WKUP_IRQ]); DeviceState *afio_dev = qdev_create(NULL, TYPE_STM32_AFIO); qdev_prop_set_ptr(afio_dev, "stm32_rcc", rcc_dev); object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[0]), "gpio[a]", NULL); object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[1]), "gpio[b]", NULL); object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[2]), "gpio[c]", NULL); object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[3]), "gpio[d]", NULL); object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[4]), "gpio[e]", NULL); object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[5]), "gpio[f]", NULL); object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[6]), "gpio[g]", NULL); object_property_set_link(OBJECT(afio_dev), OBJECT(exti_dev), "exti", NULL); object_property_add_child(stm32_container, "afio", OBJECT(afio_dev), NULL); stm32_init_periph(afio_dev, STM32_AFIO_PERIPH, 0x40010000, NULL); stm32_create_uart_dev(stm32_container, STM32_UART1, 1, rcc_dev, gpio_dev, afio_dev, 0x40013800, pic[STM32_UART1_IRQ]); stm32_create_uart_dev(stm32_container, STM32_UART2, 2, rcc_dev, gpio_dev, afio_dev, 0x40004400, pic[STM32_UART2_IRQ]); stm32_create_uart_dev(stm32_container, STM32_UART3, 3, rcc_dev, gpio_dev, afio_dev, 0x40004800, pic[STM32_UART3_IRQ]); stm32_create_uart_dev(stm32_container, STM32_UART4, 4, rcc_dev, gpio_dev, afio_dev, 0x40004c00, pic[STM32_UART4_IRQ]); stm32_create_uart_dev(stm32_container, STM32_UART5, 5, rcc_dev, gpio_dev, afio_dev, 0x40005000, pic[STM32_UART5_IRQ]); }