docs: add note about stibp CPU feature for spectre v2
[qemu/ar7.git] / hw / nvram / nrf51_nvm.c
blob7d94cef1db32023f630ff7be6d2f09c9cba7e666
1 /*
2 * Nordic Semiconductor nRF51 non-volatile memory
4 * It provides an interface to erase regions in flash memory.
5 * Furthermore it provides the user and factory information registers.
7 * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
9 * See nRF51 reference manual and product sheet sections:
10 * + Non-Volatile Memory Controller (NVMC)
11 * + Factory Information Configuration Registers (FICR)
12 * + User Information Configuration Registers (UICR)
14 * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
16 * This code is licensed under the GPL version 2 or later. See
17 * the COPYING file in the top-level directory.
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"
28 * FICR Registers Assignments
29 * CODEPAGESIZE 0x010
30 * CODESIZE 0x014
31 * CLENR0 0x028
32 * PPFC 0x02C
33 * NUMRAMBLOCK 0x034
34 * SIZERAMBLOCKS 0x038
35 * SIZERAMBLOCK[0] 0x038
36 * SIZERAMBLOCK[1] 0x03C
37 * SIZERAMBLOCK[2] 0x040
38 * SIZERAMBLOCK[3] 0x044
39 * CONFIGID 0x05C
40 * DEVICEID[0] 0x060
41 * DEVICEID[1] 0x064
42 * ER[0] 0x080
43 * ER[1] 0x084
44 * ER[2] 0x088
45 * ER[3] 0x08C
46 * IR[0] 0x090
47 * IR[1] 0x094
48 * IR[2] 0x098
49 * IR[3] 0x09C
50 * DEVICEADDRTYPE 0x0A0
51 * DEVICEADDR[0] 0x0A4
52 * DEVICEADDR[1] 0x0A8
53 * OVERRIDEEN 0x0AC
54 * NRF_1MBIT[0] 0x0B0
55 * NRF_1MBIT[1] 0x0B4
56 * NRF_1MBIT[2] 0x0B8
57 * NRF_1MBIT[3] 0x0BC
58 * NRF_1MBIT[4] 0x0C0
59 * BLE_1MBIT[0] 0x0EC
60 * BLE_1MBIT[1] 0x0F0
61 * BLE_1MBIT[2] 0x0F4
62 * BLE_1MBIT[3] 0x0F8
63 * BLE_1MBIT[4] 0x0FC
65 static 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
81 static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
83 assert(offset < sizeof(ficr_content));
84 return ficr_content[offset / 4];
87 static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
88 unsigned int size)
90 /* Intentionally do nothing */
93 static 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
102 * UICR Registers Assignments
103 * CLENR0 0x000
104 * RBPCONF 0x004
105 * XTALFREQ 0x008
106 * FWID 0x010
107 * BOOTLOADERADDR 0x014
108 * NRFFW[0] 0x014
109 * NRFFW[1] 0x018
110 * NRFFW[2] 0x01C
111 * NRFFW[3] 0x020
112 * NRFFW[4] 0x024
113 * NRFFW[5] 0x028
114 * NRFFW[6] 0x02C
115 * NRFFW[7] 0x030
116 * NRFFW[8] 0x034
117 * NRFFW[9] 0x038
118 * NRFFW[10] 0x03C
119 * NRFFW[11] 0x040
120 * NRFFW[12] 0x044
121 * NRFFW[13] 0x048
122 * NRFFW[14] 0x04C
123 * NRFHW[0] 0x050
124 * NRFHW[1] 0x054
125 * NRFHW[2] 0x058
126 * NRFHW[3] 0x05C
127 * NRFHW[4] 0x060
128 * NRFHW[5] 0x064
129 * NRFHW[6] 0x068
130 * NRFHW[7] 0x06C
131 * NRFHW[8] 0x070
132 * NRFHW[9] 0x074
133 * NRFHW[10] 0x078
134 * NRFHW[11] 0x07C
135 * CUSTOMER[0] 0x080
136 * CUSTOMER[1] 0x084
137 * CUSTOMER[2] 0x088
138 * CUSTOMER[3] 0x08C
139 * CUSTOMER[4] 0x090
140 * CUSTOMER[5] 0x094
141 * CUSTOMER[6] 0x098
142 * CUSTOMER[7] 0x09C
143 * CUSTOMER[8] 0x0A0
144 * CUSTOMER[9] 0x0A4
145 * CUSTOMER[10] 0x0A8
146 * CUSTOMER[11] 0x0AC
147 * CUSTOMER[12] 0x0B0
148 * CUSTOMER[13] 0x0B4
149 * CUSTOMER[14] 0x0B8
150 * CUSTOMER[15] 0x0BC
151 * CUSTOMER[16] 0x0C0
152 * CUSTOMER[17] 0x0C4
153 * CUSTOMER[18] 0x0C8
154 * CUSTOMER[19] 0x0CC
155 * CUSTOMER[20] 0x0D0
156 * CUSTOMER[21] 0x0D4
157 * CUSTOMER[22] 0x0D8
158 * CUSTOMER[23] 0x0DC
159 * CUSTOMER[24] 0x0E0
160 * CUSTOMER[25] 0x0E4
161 * CUSTOMER[26] 0x0E8
162 * CUSTOMER[27] 0x0EC
163 * CUSTOMER[28] 0x0F0
164 * CUSTOMER[29] 0x0F4
165 * CUSTOMER[30] 0x0F8
166 * CUSTOMER[31] 0x0FC
169 static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
171 NRF51NVMState *s = NRF51_NVM(opaque);
173 assert(offset < sizeof(s->uicr_content));
174 return s->uicr_content[offset / 4];
177 static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
178 unsigned int size)
180 NRF51NVMState *s = NRF51_NVM(opaque);
182 assert(offset < sizeof(s->uicr_content));
183 s->uicr_content[offset / 4] = value;
186 static 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
195 static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
197 NRF51NVMState *s = NRF51_NVM(opaque);
198 uint64_t r = 0;
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;
213 return r;
216 static void io_write(void *opaque, hwaddr offset, uint64_t value,
217 unsigned int size)
219 NRF51NVMState *s = NRF51_NVM(opaque);
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 /* Mask in-page sub address */
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);
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);
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__);
252 break;
253 case NRF51_NVMC_ERASEUICR:
254 if (value == NRF51_NVMC_ERASE) {
255 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
257 break;
259 default:
260 qemu_log_mask(LOG_GUEST_ERROR,
261 "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
265 static 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,
274 static void flash_write(void *opaque, hwaddr offset, uint64_t value,
275 unsigned int size)
277 NRF51NVMState *s = NRF51_NVM(opaque);
279 if (s->config & NRF51_NVMC_CONFIG_WEN) {
280 uint32_t oldval;
282 assert(offset + size <= s->flash_size);
284 /* NOR Flash only allows bits to be flipped from 1's to 0's on write */
285 oldval = ldl_le_p(s->storage + offset);
286 oldval &= value;
287 stl_le_p(s->storage + offset, oldval);
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);
299 static 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,
306 static void nrf51_nvm_init(Object *obj)
308 NRF51NVMState *s = NRF51_NVM(obj);
309 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
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);
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);
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);
324 static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
326 NRF51NVMState *s = NRF51_NVM(dev);
327 Error *err = NULL;
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;
336 s->storage = memory_region_get_ram_ptr(&s->flash);
337 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
340 static void nrf51_nvm_reset(DeviceState *dev)
342 NRF51NVMState *s = NRF51_NVM(dev);
344 s->config = 0x00;
345 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
348 static Property nrf51_nvm_properties[] = {
349 DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
350 DEFINE_PROP_END_OF_LIST(),
353 static 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()
365 static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
367 DeviceClass *dc = DEVICE_CLASS(klass);
369 dc->props = nrf51_nvm_properties;
370 dc->vmsd = &vmstate_nvm;
371 dc->realize = nrf51_nvm_realize;
372 dc->reset = nrf51_nvm_reset;
375 static 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
383 static void nrf51_nvm_register_types(void)
385 type_register_static(&nrf51_nvm_info);
388 type_init(nrf51_nvm_register_types)