xics/spapr: Rename xics_kvm_init()
[qemu/ar7.git] / hw / nvram / nrf51_nvm.c
blobeca0cb35b5204a53adc6a979d7de62030f2fb470
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 "qemu/module.h"
24 #include "exec/address-spaces.h"
25 #include "hw/arm/nrf51.h"
26 #include "hw/nvram/nrf51_nvm.h"
29 * FICR Registers Assignments
30 * CODEPAGESIZE 0x010
31 * CODESIZE 0x014
32 * CLENR0 0x028
33 * PPFC 0x02C
34 * NUMRAMBLOCK 0x034
35 * SIZERAMBLOCKS 0x038
36 * SIZERAMBLOCK[0] 0x038
37 * SIZERAMBLOCK[1] 0x03C
38 * SIZERAMBLOCK[2] 0x040
39 * SIZERAMBLOCK[3] 0x044
40 * CONFIGID 0x05C
41 * DEVICEID[0] 0x060
42 * DEVICEID[1] 0x064
43 * ER[0] 0x080
44 * ER[1] 0x084
45 * ER[2] 0x088
46 * ER[3] 0x08C
47 * IR[0] 0x090
48 * IR[1] 0x094
49 * IR[2] 0x098
50 * IR[3] 0x09C
51 * DEVICEADDRTYPE 0x0A0
52 * DEVICEADDR[0] 0x0A4
53 * DEVICEADDR[1] 0x0A8
54 * OVERRIDEEN 0x0AC
55 * NRF_1MBIT[0] 0x0B0
56 * NRF_1MBIT[1] 0x0B4
57 * NRF_1MBIT[2] 0x0B8
58 * NRF_1MBIT[3] 0x0BC
59 * NRF_1MBIT[4] 0x0C0
60 * BLE_1MBIT[0] 0x0EC
61 * BLE_1MBIT[1] 0x0F0
62 * BLE_1MBIT[2] 0x0F4
63 * BLE_1MBIT[3] 0x0F8
64 * BLE_1MBIT[4] 0x0FC
66 static const uint32_t ficr_content[64] = {
67 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000400,
68 0x00000100, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00002000,
69 0x00002000, 0x00002000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
70 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
71 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
72 0x12345678, 0x9ABCDEF1, 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, 0xFFFFFFFF,
79 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
82 static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
84 assert(offset < sizeof(ficr_content));
85 return ficr_content[offset / 4];
88 static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
89 unsigned int size)
91 /* Intentionally do nothing */
94 static const MemoryRegionOps ficr_ops = {
95 .read = ficr_read,
96 .write = ficr_write,
97 .impl.min_access_size = 4,
98 .impl.max_access_size = 4,
99 .endianness = DEVICE_LITTLE_ENDIAN
103 * UICR Registers Assignments
104 * CLENR0 0x000
105 * RBPCONF 0x004
106 * XTALFREQ 0x008
107 * FWID 0x010
108 * BOOTLOADERADDR 0x014
109 * NRFFW[0] 0x014
110 * NRFFW[1] 0x018
111 * NRFFW[2] 0x01C
112 * NRFFW[3] 0x020
113 * NRFFW[4] 0x024
114 * NRFFW[5] 0x028
115 * NRFFW[6] 0x02C
116 * NRFFW[7] 0x030
117 * NRFFW[8] 0x034
118 * NRFFW[9] 0x038
119 * NRFFW[10] 0x03C
120 * NRFFW[11] 0x040
121 * NRFFW[12] 0x044
122 * NRFFW[13] 0x048
123 * NRFFW[14] 0x04C
124 * NRFHW[0] 0x050
125 * NRFHW[1] 0x054
126 * NRFHW[2] 0x058
127 * NRFHW[3] 0x05C
128 * NRFHW[4] 0x060
129 * NRFHW[5] 0x064
130 * NRFHW[6] 0x068
131 * NRFHW[7] 0x06C
132 * NRFHW[8] 0x070
133 * NRFHW[9] 0x074
134 * NRFHW[10] 0x078
135 * NRFHW[11] 0x07C
136 * CUSTOMER[0] 0x080
137 * CUSTOMER[1] 0x084
138 * CUSTOMER[2] 0x088
139 * CUSTOMER[3] 0x08C
140 * CUSTOMER[4] 0x090
141 * CUSTOMER[5] 0x094
142 * CUSTOMER[6] 0x098
143 * CUSTOMER[7] 0x09C
144 * CUSTOMER[8] 0x0A0
145 * CUSTOMER[9] 0x0A4
146 * CUSTOMER[10] 0x0A8
147 * CUSTOMER[11] 0x0AC
148 * CUSTOMER[12] 0x0B0
149 * CUSTOMER[13] 0x0B4
150 * CUSTOMER[14] 0x0B8
151 * CUSTOMER[15] 0x0BC
152 * CUSTOMER[16] 0x0C0
153 * CUSTOMER[17] 0x0C4
154 * CUSTOMER[18] 0x0C8
155 * CUSTOMER[19] 0x0CC
156 * CUSTOMER[20] 0x0D0
157 * CUSTOMER[21] 0x0D4
158 * CUSTOMER[22] 0x0D8
159 * CUSTOMER[23] 0x0DC
160 * CUSTOMER[24] 0x0E0
161 * CUSTOMER[25] 0x0E4
162 * CUSTOMER[26] 0x0E8
163 * CUSTOMER[27] 0x0EC
164 * CUSTOMER[28] 0x0F0
165 * CUSTOMER[29] 0x0F4
166 * CUSTOMER[30] 0x0F8
167 * CUSTOMER[31] 0x0FC
170 static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
172 NRF51NVMState *s = NRF51_NVM(opaque);
174 assert(offset < sizeof(s->uicr_content));
175 return s->uicr_content[offset / 4];
178 static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
179 unsigned int size)
181 NRF51NVMState *s = NRF51_NVM(opaque);
183 assert(offset < sizeof(s->uicr_content));
184 s->uicr_content[offset / 4] = value;
187 static const MemoryRegionOps uicr_ops = {
188 .read = uicr_read,
189 .write = uicr_write,
190 .impl.min_access_size = 4,
191 .impl.max_access_size = 4,
192 .endianness = DEVICE_LITTLE_ENDIAN
196 static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
198 NRF51NVMState *s = NRF51_NVM(opaque);
199 uint64_t r = 0;
201 switch (offset) {
202 case NRF51_NVMC_READY:
203 r = NRF51_NVMC_READY_READY;
204 break;
205 case NRF51_NVMC_CONFIG:
206 r = s->config;
207 break;
208 default:
209 qemu_log_mask(LOG_GUEST_ERROR,
210 "%s: bad read offset 0x%" HWADDR_PRIx "\n", __func__, offset);
211 break;
214 return r;
217 static void io_write(void *opaque, hwaddr offset, uint64_t value,
218 unsigned int size)
220 NRF51NVMState *s = NRF51_NVM(opaque);
222 switch (offset) {
223 case NRF51_NVMC_CONFIG:
224 s->config = value & NRF51_NVMC_CONFIG_MASK;
225 break;
226 case NRF51_NVMC_ERASEPCR0:
227 case NRF51_NVMC_ERASEPCR1:
228 if (s->config & NRF51_NVMC_CONFIG_EEN) {
229 /* Mask in-page sub address */
230 value &= ~(NRF51_PAGE_SIZE - 1);
231 if (value <= (s->flash_size - NRF51_PAGE_SIZE)) {
232 memset(s->storage + value, 0xFF, NRF51_PAGE_SIZE);
233 memory_region_flush_rom_device(&s->flash, value,
234 NRF51_PAGE_SIZE);
236 } else {
237 qemu_log_mask(LOG_GUEST_ERROR,
238 "%s: Flash erase at 0x%" HWADDR_PRIx" while flash not erasable.\n",
239 __func__, offset);
241 break;
242 case NRF51_NVMC_ERASEALL:
243 if (value == NRF51_NVMC_ERASE) {
244 if (s->config & NRF51_NVMC_CONFIG_EEN) {
245 memset(s->storage, 0xFF, s->flash_size);
246 memory_region_flush_rom_device(&s->flash, 0, s->flash_size);
247 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
248 } else {
249 qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash not erasable.\n",
250 __func__);
253 break;
254 case NRF51_NVMC_ERASEUICR:
255 if (value == NRF51_NVMC_ERASE) {
256 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
258 break;
260 default:
261 qemu_log_mask(LOG_GUEST_ERROR,
262 "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
266 static const MemoryRegionOps io_ops = {
267 .read = io_read,
268 .write = io_write,
269 .impl.min_access_size = 4,
270 .impl.max_access_size = 4,
271 .endianness = DEVICE_LITTLE_ENDIAN,
275 static void flash_write(void *opaque, hwaddr offset, uint64_t value,
276 unsigned int size)
278 NRF51NVMState *s = NRF51_NVM(opaque);
280 if (s->config & NRF51_NVMC_CONFIG_WEN) {
281 uint32_t oldval;
283 assert(offset + size <= s->flash_size);
285 /* NOR Flash only allows bits to be flipped from 1's to 0's on write */
286 oldval = ldl_le_p(s->storage + offset);
287 oldval &= value;
288 stl_le_p(s->storage + offset, oldval);
290 memory_region_flush_rom_device(&s->flash, offset, size);
291 } else {
292 qemu_log_mask(LOG_GUEST_ERROR,
293 "%s: Flash write 0x%" HWADDR_PRIx" while flash not writable.\n",
294 __func__, offset);
300 static const MemoryRegionOps flash_ops = {
301 .write = flash_write,
302 .valid.min_access_size = 4,
303 .valid.max_access_size = 4,
304 .endianness = DEVICE_LITTLE_ENDIAN,
307 static void nrf51_nvm_init(Object *obj)
309 NRF51NVMState *s = NRF51_NVM(obj);
310 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
312 memory_region_init_io(&s->mmio, obj, &io_ops, s, "nrf51_soc.nvmc",
313 NRF51_NVMC_SIZE);
314 sysbus_init_mmio(sbd, &s->mmio);
316 memory_region_init_io(&s->ficr, obj, &ficr_ops, s, "nrf51_soc.ficr",
317 sizeof(ficr_content));
318 sysbus_init_mmio(sbd, &s->ficr);
320 memory_region_init_io(&s->uicr, obj, &uicr_ops, s, "nrf51_soc.uicr",
321 sizeof(s->uicr_content));
322 sysbus_init_mmio(sbd, &s->uicr);
325 static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
327 NRF51NVMState *s = NRF51_NVM(dev);
328 Error *err = NULL;
330 memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
331 "nrf51_soc.flash", s->flash_size, &err);
332 if (err) {
333 error_propagate(errp, err);
334 return;
337 s->storage = memory_region_get_ram_ptr(&s->flash);
338 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
341 static void nrf51_nvm_reset(DeviceState *dev)
343 NRF51NVMState *s = NRF51_NVM(dev);
345 s->config = 0x00;
346 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
349 static Property nrf51_nvm_properties[] = {
350 DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
351 DEFINE_PROP_END_OF_LIST(),
354 static const VMStateDescription vmstate_nvm = {
355 .name = "nrf51_soc.nvm",
356 .version_id = 1,
357 .minimum_version_id = 1,
358 .fields = (VMStateField[]) {
359 VMSTATE_UINT32_ARRAY(uicr_content, NRF51NVMState,
360 NRF51_UICR_FIXTURE_SIZE),
361 VMSTATE_UINT32(config, NRF51NVMState),
362 VMSTATE_END_OF_LIST()
366 static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
368 DeviceClass *dc = DEVICE_CLASS(klass);
370 dc->props = nrf51_nvm_properties;
371 dc->vmsd = &vmstate_nvm;
372 dc->realize = nrf51_nvm_realize;
373 dc->reset = nrf51_nvm_reset;
376 static const TypeInfo nrf51_nvm_info = {
377 .name = TYPE_NRF51_NVM,
378 .parent = TYPE_SYS_BUS_DEVICE,
379 .instance_size = sizeof(NRF51NVMState),
380 .instance_init = nrf51_nvm_init,
381 .class_init = nrf51_nvm_class_init
384 static void nrf51_nvm_register_types(void)
386 type_register_static(&nrf51_nvm_info);
389 type_init(nrf51_nvm_register_types)