]> Git Repo - qemu.git/blame - hw/arm/nrf51_soc.c
tests/microbit-test: Add Tests for nRF51 Timer
[qemu.git] / hw / arm / nrf51_soc.c
CommitLineData
673b2d42
JS
1/*
2 * Nordic Semiconductor nRF51 SoC
3 * http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.1.pdf
4 *
5 * Copyright 2018 Joel Stanley <[email protected]>
6 *
7 * This code is licensed under the GPL version 2 or later. See
8 * the COPYING file in the top-level directory.
9 */
10
11#include "qemu/osdep.h"
12#include "qapi/error.h"
13#include "qemu-common.h"
14#include "hw/arm/arm.h"
15#include "hw/sysbus.h"
16#include "hw/boards.h"
17#include "hw/devices.h"
18#include "hw/misc/unimp.h"
19#include "exec/address-spaces.h"
20#include "sysemu/sysemu.h"
21#include "qemu/log.h"
22#include "cpu.h"
23
659b85e4 24#include "hw/arm/nrf51.h"
673b2d42
JS
25#include "hw/arm/nrf51_soc.h"
26
673b2d42
JS
27/*
28 * The size and base is for the NRF51822 part. If other parts
29 * are supported in the future, add a sub-class of NRF51SoC for
30 * the specific variants
31 */
659b85e4
SG
32#define NRF51822_FLASH_SIZE (256 * NRF51_PAGE_SIZE)
33#define NRF51822_SRAM_SIZE (16 * NRF51_PAGE_SIZE)
673b2d42 34
b0014913
JS
35#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
36
673b2d42
JS
37static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
38{
39 NRF51State *s = NRF51_SOC(dev_soc);
b0014913 40 MemoryRegion *mr;
673b2d42 41 Error *err = NULL;
60facd90
SG
42 uint8_t i = 0;
43 hwaddr base_addr = 0;
673b2d42
JS
44
45 if (!s->board_memory) {
46 error_setg(errp, "memory property was not set");
47 return;
48 }
49
50 object_property_set_link(OBJECT(&s->cpu), OBJECT(&s->container), "memory",
51 &err);
52 if (err) {
53 error_propagate(errp, err);
54 return;
55 }
56 object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
57 if (err) {
58 error_propagate(errp, err);
59 return;
60 }
61
62 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
63
64 memory_region_init_rom(&s->flash, OBJECT(s), "nrf51.flash", s->flash_size,
65 &err);
66 if (err) {
67 error_propagate(errp, err);
68 return;
69 }
659b85e4 70 memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
673b2d42
JS
71
72 memory_region_init_ram(&s->sram, NULL, "nrf51.sram", s->sram_size, &err);
73 if (err) {
74 error_propagate(errp, err);
75 return;
76 }
659b85e4 77 memory_region_add_subregion(&s->container, NRF51_SRAM_BASE, &s->sram);
673b2d42 78
b0014913
JS
79 /* UART */
80 object_property_set_bool(OBJECT(&s->uart), true, "realized", &err);
81 if (err) {
82 error_propagate(errp, err);
83 return;
84 }
85 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0);
659b85e4 86 memory_region_add_subregion_overlap(&s->container, NRF51_UART_BASE, mr, 0);
b0014913
JS
87 sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart), 0,
88 qdev_get_gpio_in(DEVICE(&s->cpu),
659b85e4 89 BASE_TO_IRQ(NRF51_UART_BASE)));
b0014913 90
f30890de
SG
91 /* RNG */
92 object_property_set_bool(OBJECT(&s->rng), true, "realized", &err);
93 if (err) {
94 error_propagate(errp, err);
95 return;
96 }
97
98 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0);
99 memory_region_add_subregion_overlap(&s->container, NRF51_RNG_BASE, mr, 0);
100 sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng), 0,
101 qdev_get_gpio_in(DEVICE(&s->cpu),
102 BASE_TO_IRQ(NRF51_RNG_BASE)));
103
bb42c4cb
SG
104 /* GPIO */
105 object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
106 if (err) {
107 error_propagate(errp, err);
108 return;
109 }
110
111 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0);
112 memory_region_add_subregion_overlap(&s->container, NRF51_GPIO_BASE, mr, 0);
113
114 /* Pass all GPIOs to the SOC layer so they are available to the board */
115 qdev_pass_gpios(DEVICE(&s->gpio), dev_soc, NULL);
116
60facd90
SG
117 /* TIMER */
118 for (i = 0; i < NRF51_NUM_TIMERS; i++) {
119 object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
120 if (err) {
121 error_propagate(errp, err);
122 return;
123 }
124
125 base_addr = NRF51_TIMER_BASE + i * NRF51_TIMER_SIZE;
126
127 sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr);
128 sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0,
129 qdev_get_gpio_in(DEVICE(&s->cpu),
130 BASE_TO_IRQ(base_addr)));
131 }
132
659b85e4
SG
133 create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
134 NRF51_IOMEM_SIZE);
135 create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
136 NRF51_FICR_SIZE);
673b2d42 137 create_unimplemented_device("nrf51_soc.private",
659b85e4 138 NRF51_PRIVATE_BASE, NRF51_PRIVATE_SIZE);
673b2d42
JS
139}
140
141static void nrf51_soc_init(Object *obj)
142{
60facd90
SG
143 uint8_t i = 0;
144
673b2d42
JS
145 NRF51State *s = NRF51_SOC(obj);
146
147 memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX);
148
149 sysbus_init_child_obj(OBJECT(s), "armv6m", OBJECT(&s->cpu), sizeof(s->cpu),
150 TYPE_ARMV7M);
151 qdev_prop_set_string(DEVICE(&s->cpu), "cpu-type",
152 ARM_CPU_TYPE_NAME("cortex-m0"));
153 qdev_prop_set_uint32(DEVICE(&s->cpu), "num-irq", 32);
b0014913
JS
154
155 sysbus_init_child_obj(obj, "uart", &s->uart, sizeof(s->uart),
156 TYPE_NRF51_UART);
157 object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev",
158 &error_abort);
f30890de
SG
159
160 sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
161 TYPE_NRF51_RNG);
bb42c4cb
SG
162
163 sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
164 TYPE_NRF51_GPIO);
60facd90
SG
165
166 for (i = 0; i < NRF51_NUM_TIMERS; i++) {
167 sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
168 sizeof(s->timer[i]), TYPE_NRF51_TIMER);
169
170 }
673b2d42
JS
171}
172
173static Property nrf51_soc_properties[] = {
174 DEFINE_PROP_LINK("memory", NRF51State, board_memory, TYPE_MEMORY_REGION,
175 MemoryRegion *),
176 DEFINE_PROP_UINT32("sram-size", NRF51State, sram_size, NRF51822_SRAM_SIZE),
177 DEFINE_PROP_UINT32("flash-size", NRF51State, flash_size,
178 NRF51822_FLASH_SIZE),
179 DEFINE_PROP_END_OF_LIST(),
180};
181
182static void nrf51_soc_class_init(ObjectClass *klass, void *data)
183{
184 DeviceClass *dc = DEVICE_CLASS(klass);
185
186 dc->realize = nrf51_soc_realize;
187 dc->props = nrf51_soc_properties;
188}
189
190static const TypeInfo nrf51_soc_info = {
191 .name = TYPE_NRF51_SOC,
192 .parent = TYPE_SYS_BUS_DEVICE,
193 .instance_size = sizeof(NRF51State),
194 .instance_init = nrf51_soc_init,
195 .class_init = nrf51_soc_class_init,
196};
197
198static void nrf51_soc_types(void)
199{
200 type_register_static(&nrf51_soc_info);
201}
202type_init(nrf51_soc_types)
This page took 0.067471 seconds and 4 git commands to generate.