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 "exec/address-spaces.h"
24#include "hw/arm/nrf51.h"
25#include "hw/nvram/nrf51_nvm.h"
26
27
28
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
65static const uint32_t ficr_content[64] = {
66 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000400,
67 0x00000100, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00002000,
68 0x00002000, 0x00002000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
69 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
70 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
71 0x12345678, 0x9ABCDEF1, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
72 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
73 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
74 0xFFFFFFFF, 0xFFFFFFFF, 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
79};
80
81static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
82{
83 assert(offset < sizeof(ficr_content));
84 return ficr_content[offset / 4];
85}
86
87static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
88 unsigned int size)
89{
90
91}
92
93static const MemoryRegionOps ficr_ops = {
94 .read = ficr_read,
95 .write = ficr_write,
96 .impl.min_access_size = 4,
97 .impl.max_access_size = 4,
98 .endianness = DEVICE_LITTLE_ENDIAN
99};
100
101
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
169static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
170{
171 NRF51NVMState *s = NRF51_NVM(opaque);
172
173 assert(offset < sizeof(s->uicr_content));
174 return s->uicr_content[offset / 4];
175}
176
177static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
178 unsigned int size)
179{
180 NRF51NVMState *s = NRF51_NVM(opaque);
181
182 assert(offset < sizeof(s->uicr_content));
183 s->uicr_content[offset / 4] = value;
184}
185
186static const MemoryRegionOps uicr_ops = {
187 .read = uicr_read,
188 .write = uicr_write,
189 .impl.min_access_size = 4,
190 .impl.max_access_size = 4,
191 .endianness = DEVICE_LITTLE_ENDIAN
192};
193
194
195static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
196{
197 NRF51NVMState *s = NRF51_NVM(opaque);
198 uint64_t r = 0;
199
200 switch (offset) {
201 case NRF51_NVMC_READY:
202 r = NRF51_NVMC_READY_READY;
203 break;
204 case NRF51_NVMC_CONFIG:
205 r = s->config;
206 break;
207 default:
208 qemu_log_mask(LOG_GUEST_ERROR,
209 "%s: bad read offset 0x%" HWADDR_PRIx "\n", __func__, offset);
210 break;
211 }
212
213 return r;
214}
215
216static void io_write(void *opaque, hwaddr offset, uint64_t value,
217 unsigned int size)
218{
219 NRF51NVMState *s = NRF51_NVM(opaque);
220
221 switch (offset) {
222 case NRF51_NVMC_CONFIG:
223 s->config = value & NRF51_NVMC_CONFIG_MASK;
224 break;
225 case NRF51_NVMC_ERASEPCR0:
226 case NRF51_NVMC_ERASEPCR1:
227 if (s->config & NRF51_NVMC_CONFIG_EEN) {
228
229 value &= ~(NRF51_PAGE_SIZE - 1);
230 if (value <= (s->flash_size - NRF51_PAGE_SIZE)) {
231 memset(s->storage + value, 0xFF, NRF51_PAGE_SIZE);
232 memory_region_flush_rom_device(&s->flash, value,
233 NRF51_PAGE_SIZE);
234 }
235 } else {
236 qemu_log_mask(LOG_GUEST_ERROR,
237 "%s: Flash erase at 0x%" HWADDR_PRIx" while flash not erasable.\n",
238 __func__, offset);
239 }
240 break;
241 case NRF51_NVMC_ERASEALL:
242 if (value == NRF51_NVMC_ERASE) {
243 if (s->config & NRF51_NVMC_CONFIG_EEN) {
244 memset(s->storage, 0xFF, s->flash_size);
245 memory_region_flush_rom_device(&s->flash, 0, s->flash_size);
246 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
247 } else {
248 qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash not erasable.\n",
249 __func__);
250 }
251 }
252 break;
253 case NRF51_NVMC_ERASEUICR:
254 if (value == NRF51_NVMC_ERASE) {
255 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
256 }
257 break;
258
259 default:
260 qemu_log_mask(LOG_GUEST_ERROR,
261 "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
262 }
263}
264
265static const MemoryRegionOps io_ops = {
266 .read = io_read,
267 .write = io_write,
268 .impl.min_access_size = 4,
269 .impl.max_access_size = 4,
270 .endianness = DEVICE_LITTLE_ENDIAN,
271};
272
273
274static void flash_write(void *opaque, hwaddr offset, uint64_t value,
275 unsigned int size)
276{
277 NRF51NVMState *s = NRF51_NVM(opaque);
278
279 if (s->config & NRF51_NVMC_CONFIG_WEN) {
280 uint32_t oldval;
281
282 assert(offset + size <= s->flash_size);
283
284
285 oldval = ldl_le_p(s->storage + offset);
286 oldval &= value;
287 stl_le_p(s->storage + offset, oldval);
288
289 memory_region_flush_rom_device(&s->flash, offset, size);
290 } else {
291 qemu_log_mask(LOG_GUEST_ERROR,
292 "%s: Flash write 0x%" HWADDR_PRIx" while flash not writable.\n",
293 __func__, offset);
294 }
295}
296
297
298
299static const MemoryRegionOps flash_ops = {
300 .write = flash_write,
301 .valid.min_access_size = 4,
302 .valid.max_access_size = 4,
303 .endianness = DEVICE_LITTLE_ENDIAN,
304};
305
306static void nrf51_nvm_init(Object *obj)
307{
308 NRF51NVMState *s = NRF51_NVM(obj);
309 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
310
311 memory_region_init_io(&s->mmio, obj, &io_ops, s, "nrf51_soc.nvmc",
312 NRF51_NVMC_SIZE);
313 sysbus_init_mmio(sbd, &s->mmio);
314
315 memory_region_init_io(&s->ficr, obj, &ficr_ops, s, "nrf51_soc.ficr",
316 sizeof(ficr_content));
317 sysbus_init_mmio(sbd, &s->ficr);
318
319 memory_region_init_io(&s->uicr, obj, &uicr_ops, s, "nrf51_soc.uicr",
320 sizeof(s->uicr_content));
321 sysbus_init_mmio(sbd, &s->uicr);
322}
323
324static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
325{
326 NRF51NVMState *s = NRF51_NVM(dev);
327 Error *err = NULL;
328
329 memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
330 "nrf51_soc.flash", s->flash_size, &err);
331 if (err) {
332 error_propagate(errp, err);
333 return;
334 }
335
336 s->storage = memory_region_get_ram_ptr(&s->flash);
337 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
338}
339
340static void nrf51_nvm_reset(DeviceState *dev)
341{
342 NRF51NVMState *s = NRF51_NVM(dev);
343
344 s->config = 0x00;
345 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
346}
347
348static Property nrf51_nvm_properties[] = {
349 DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
350 DEFINE_PROP_END_OF_LIST(),
351};
352
353static const VMStateDescription vmstate_nvm = {
354 .name = "nrf51_soc.nvm",
355 .version_id = 1,
356 .minimum_version_id = 1,
357 .fields = (VMStateField[]) {
358 VMSTATE_UINT32_ARRAY(uicr_content, NRF51NVMState,
359 NRF51_UICR_FIXTURE_SIZE),
360 VMSTATE_UINT32(config, NRF51NVMState),
361 VMSTATE_END_OF_LIST()
362 }
363};
364
365static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
366{
367 DeviceClass *dc = DEVICE_CLASS(klass);
368
369 dc->props = nrf51_nvm_properties;
370 dc->vmsd = &vmstate_nvm;
371 dc->realize = nrf51_nvm_realize;
372 dc->reset = nrf51_nvm_reset;
373}
374
375static const TypeInfo nrf51_nvm_info = {
376 .name = TYPE_NRF51_NVM,
377 .parent = TYPE_SYS_BUS_DEVICE,
378 .instance_size = sizeof(NRF51NVMState),
379 .instance_init = nrf51_nvm_init,
380 .class_init = nrf51_nvm_class_init
381};
382
383static void nrf51_nvm_register_types(void)
384{
385 type_register_static(&nrf51_nvm_info);
386}
387
388type_init(nrf51_nvm_register_types)
389