1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "qapi/error.h"
22#include "qemu/log.h"
23#include "qemu/module.h"
24#include "exec/address-spaces.h"
25#include "hw/arm/nrf51.h"
26#include "hw/nvram/nrf51_nvm.h"
27#include "hw/qdev-properties.h"
28#include "migration/vmstate.h"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68static const uint32_t ficr_content[64] = {
69 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000400,
70 0x00000100, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00002000,
71 0x00002000, 0x00002000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
72 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
73 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
74 0x12345678, 0x9ABCDEF1, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
75 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
76 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
77 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
78 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
79 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
80 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
81 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
82};
83
84static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
85{
86 assert(offset < sizeof(ficr_content));
87 return ficr_content[offset / 4];
88}
89
90static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
91 unsigned int size)
92{
93
94}
95
96static const MemoryRegionOps ficr_ops = {
97 .read = ficr_read,
98 .write = ficr_write,
99 .impl.min_access_size = 4,
100 .impl.max_access_size = 4,
101 .endianness = DEVICE_LITTLE_ENDIAN
102};
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
173{
174 NRF51NVMState *s = NRF51_NVM(opaque);
175
176 assert(offset < sizeof(s->uicr_content));
177 return s->uicr_content[offset / 4];
178}
179
180static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
181 unsigned int size)
182{
183 NRF51NVMState *s = NRF51_NVM(opaque);
184
185 assert(offset < sizeof(s->uicr_content));
186 s->uicr_content[offset / 4] = value;
187}
188
189static const MemoryRegionOps uicr_ops = {
190 .read = uicr_read,
191 .write = uicr_write,
192 .impl.min_access_size = 4,
193 .impl.max_access_size = 4,
194 .endianness = DEVICE_LITTLE_ENDIAN
195};
196
197
198static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
199{
200 NRF51NVMState *s = NRF51_NVM(opaque);
201 uint64_t r = 0;
202
203 switch (offset) {
204 case NRF51_NVMC_READY:
205 r = NRF51_NVMC_READY_READY;
206 break;
207 case NRF51_NVMC_CONFIG:
208 r = s->config;
209 break;
210 default:
211 qemu_log_mask(LOG_GUEST_ERROR,
212 "%s: bad read offset 0x%" HWADDR_PRIx "\n", __func__, offset);
213 break;
214 }
215
216 return r;
217}
218
219static void io_write(void *opaque, hwaddr offset, uint64_t value,
220 unsigned int size)
221{
222 NRF51NVMState *s = NRF51_NVM(opaque);
223
224 switch (offset) {
225 case NRF51_NVMC_CONFIG:
226 s->config = value & NRF51_NVMC_CONFIG_MASK;
227 break;
228 case NRF51_NVMC_ERASEPCR0:
229 case NRF51_NVMC_ERASEPCR1:
230 if (s->config & NRF51_NVMC_CONFIG_EEN) {
231
232 value &= ~(NRF51_PAGE_SIZE - 1);
233 if (value <= (s->flash_size - NRF51_PAGE_SIZE)) {
234 memset(s->storage + value, 0xFF, NRF51_PAGE_SIZE);
235 memory_region_flush_rom_device(&s->flash, value,
236 NRF51_PAGE_SIZE);
237 }
238 } else {
239 qemu_log_mask(LOG_GUEST_ERROR,
240 "%s: Flash erase at 0x%" HWADDR_PRIx" while flash not erasable.\n",
241 __func__, offset);
242 }
243 break;
244 case NRF51_NVMC_ERASEALL:
245 if (value == NRF51_NVMC_ERASE) {
246 if (s->config & NRF51_NVMC_CONFIG_EEN) {
247 memset(s->storage, 0xFF, s->flash_size);
248 memory_region_flush_rom_device(&s->flash, 0, s->flash_size);
249 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
250 } else {
251 qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash not erasable.\n",
252 __func__);
253 }
254 }
255 break;
256 case NRF51_NVMC_ERASEUICR:
257 if (value == NRF51_NVMC_ERASE) {
258 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
259 }
260 break;
261
262 default:
263 qemu_log_mask(LOG_GUEST_ERROR,
264 "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
265 }
266}
267
268static const MemoryRegionOps io_ops = {
269 .read = io_read,
270 .write = io_write,
271 .impl.min_access_size = 4,
272 .impl.max_access_size = 4,
273 .endianness = DEVICE_LITTLE_ENDIAN,
274};
275
276
277static void flash_write(void *opaque, hwaddr offset, uint64_t value,
278 unsigned int size)
279{
280 NRF51NVMState *s = NRF51_NVM(opaque);
281
282 if (s->config & NRF51_NVMC_CONFIG_WEN) {
283 uint32_t oldval;
284
285 assert(offset + size <= s->flash_size);
286
287
288 oldval = ldl_le_p(s->storage + offset);
289 oldval &= value;
290 stl_le_p(s->storage + offset, oldval);
291
292 memory_region_flush_rom_device(&s->flash, offset, size);
293 } else {
294 qemu_log_mask(LOG_GUEST_ERROR,
295 "%s: Flash write 0x%" HWADDR_PRIx" while flash not writable.\n",
296 __func__, offset);
297 }
298}
299
300
301
302static const MemoryRegionOps flash_ops = {
303 .write = flash_write,
304 .valid.min_access_size = 4,
305 .valid.max_access_size = 4,
306 .endianness = DEVICE_LITTLE_ENDIAN,
307};
308
309static void nrf51_nvm_init(Object *obj)
310{
311 NRF51NVMState *s = NRF51_NVM(obj);
312 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
313
314 memory_region_init_io(&s->mmio, obj, &io_ops, s, "nrf51_soc.nvmc",
315 NRF51_NVMC_SIZE);
316 sysbus_init_mmio(sbd, &s->mmio);
317
318 memory_region_init_io(&s->ficr, obj, &ficr_ops, s, "nrf51_soc.ficr",
319 sizeof(ficr_content));
320 sysbus_init_mmio(sbd, &s->ficr);
321
322 memory_region_init_io(&s->uicr, obj, &uicr_ops, s, "nrf51_soc.uicr",
323 sizeof(s->uicr_content));
324 sysbus_init_mmio(sbd, &s->uicr);
325}
326
327static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
328{
329 NRF51NVMState *s = NRF51_NVM(dev);
330 Error *err = NULL;
331
332 memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
333 "nrf51_soc.flash", s->flash_size, &err);
334 if (err) {
335 error_propagate(errp, err);
336 return;
337 }
338
339 s->storage = memory_region_get_ram_ptr(&s->flash);
340 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
341}
342
343static void nrf51_nvm_reset(DeviceState *dev)
344{
345 NRF51NVMState *s = NRF51_NVM(dev);
346
347 s->config = 0x00;
348 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
349}
350
351static Property nrf51_nvm_properties[] = {
352 DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
353 DEFINE_PROP_END_OF_LIST(),
354};
355
356static const VMStateDescription vmstate_nvm = {
357 .name = "nrf51_soc.nvm",
358 .version_id = 1,
359 .minimum_version_id = 1,
360 .fields = (VMStateField[]) {
361 VMSTATE_UINT32_ARRAY(uicr_content, NRF51NVMState,
362 NRF51_UICR_FIXTURE_SIZE),
363 VMSTATE_UINT32(config, NRF51NVMState),
364 VMSTATE_END_OF_LIST()
365 }
366};
367
368static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
369{
370 DeviceClass *dc = DEVICE_CLASS(klass);
371
372 dc->props = nrf51_nvm_properties;
373 dc->vmsd = &vmstate_nvm;
374 dc->realize = nrf51_nvm_realize;
375 dc->reset = nrf51_nvm_reset;
376}
377
378static const TypeInfo nrf51_nvm_info = {
379 .name = TYPE_NRF51_NVM,
380 .parent = TYPE_SYS_BUS_DEVICE,
381 .instance_size = sizeof(NRF51NVMState),
382 .instance_init = nrf51_nvm_init,
383 .class_init = nrf51_nvm_class_init
384};
385
386static void nrf51_nvm_register_types(void)
387{
388 type_register_static(&nrf51_nvm_info);
389}
390
391type_init(nrf51_nvm_register_types)
392