qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

nrf51_nvm.c (11507B)


      1 /*
      2  * Nordic Semiconductor nRF51 non-volatile memory
      3  *
      4  * It provides an interface to erase regions in flash memory.
      5  * Furthermore it provides the user and factory information registers.
      6  *
      7  * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
      8  *
      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)
     13  *
     14  * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
     15  *
     16  * This code is licensed under the GPL version 2 or later.  See
     17  * the COPYING file in the top-level directory.
     18  */
     19 
     20 #include "qemu/osdep.h"
     21 #include "qapi/error.h"
     22 #include "qemu/log.h"
     23 #include "qemu/module.h"
     24 #include "hw/arm/nrf51.h"
     25 #include "hw/nvram/nrf51_nvm.h"
     26 #include "hw/qdev-properties.h"
     27 #include "migration/vmstate.h"
     28 
     29 /*
     30  * FICR Registers Assignments
     31  * CODEPAGESIZE      0x010
     32  * CODESIZE          0x014
     33  * CLENR0            0x028
     34  * PPFC              0x02C
     35  * NUMRAMBLOCK       0x034
     36  * SIZERAMBLOCKS     0x038
     37  * SIZERAMBLOCK[0]   0x038
     38  * SIZERAMBLOCK[1]   0x03C
     39  * SIZERAMBLOCK[2]   0x040
     40  * SIZERAMBLOCK[3]   0x044
     41  * CONFIGID          0x05C
     42  * DEVICEID[0]       0x060
     43  * DEVICEID[1]       0x064
     44  * ER[0]             0x080
     45  * ER[1]             0x084
     46  * ER[2]             0x088
     47  * ER[3]             0x08C
     48  * IR[0]             0x090
     49  * IR[1]             0x094
     50  * IR[2]             0x098
     51  * IR[3]             0x09C
     52  * DEVICEADDRTYPE    0x0A0
     53  * DEVICEADDR[0]     0x0A4
     54  * DEVICEADDR[1]     0x0A8
     55  * OVERRIDEEN        0x0AC
     56  * NRF_1MBIT[0]      0x0B0
     57  * NRF_1MBIT[1]      0x0B4
     58  * NRF_1MBIT[2]      0x0B8
     59  * NRF_1MBIT[3]      0x0BC
     60  * NRF_1MBIT[4]      0x0C0
     61  * BLE_1MBIT[0]      0x0EC
     62  * BLE_1MBIT[1]      0x0F0
     63  * BLE_1MBIT[2]      0x0F4
     64  * BLE_1MBIT[3]      0x0F8
     65  * BLE_1MBIT[4]      0x0FC
     66  */
     67 static const uint32_t ficr_content[64] = {
     68     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000400,
     69     0x00000100, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00002000,
     70     0x00002000, 0x00002000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
     71     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
     72     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
     73     0x12345678, 0x9ABCDEF1, 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, 0xFFFFFFFF,
     80     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
     81 };
     82 
     83 static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
     84 {
     85     assert(offset < sizeof(ficr_content));
     86     return ficr_content[offset / 4];
     87 }
     88 
     89 static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
     90         unsigned int size)
     91 {
     92     /* Intentionally do nothing */
     93 }
     94 
     95 static const MemoryRegionOps ficr_ops = {
     96     .read = ficr_read,
     97     .write = ficr_write,
     98     .impl.min_access_size = 4,
     99     .impl.max_access_size = 4,
    100     .endianness = DEVICE_LITTLE_ENDIAN
    101 };
    102 
    103 /*
    104  * UICR Registers Assignments
    105  * CLENR0           0x000
    106  * RBPCONF          0x004
    107  * XTALFREQ         0x008
    108  * FWID             0x010
    109  * BOOTLOADERADDR   0x014
    110  * NRFFW[0]         0x014
    111  * NRFFW[1]         0x018
    112  * NRFFW[2]         0x01C
    113  * NRFFW[3]         0x020
    114  * NRFFW[4]         0x024
    115  * NRFFW[5]         0x028
    116  * NRFFW[6]         0x02C
    117  * NRFFW[7]         0x030
    118  * NRFFW[8]         0x034
    119  * NRFFW[9]         0x038
    120  * NRFFW[10]        0x03C
    121  * NRFFW[11]        0x040
    122  * NRFFW[12]        0x044
    123  * NRFFW[13]        0x048
    124  * NRFFW[14]        0x04C
    125  * NRFHW[0]         0x050
    126  * NRFHW[1]         0x054
    127  * NRFHW[2]         0x058
    128  * NRFHW[3]         0x05C
    129  * NRFHW[4]         0x060
    130  * NRFHW[5]         0x064
    131  * NRFHW[6]         0x068
    132  * NRFHW[7]         0x06C
    133  * NRFHW[8]         0x070
    134  * NRFHW[9]         0x074
    135  * NRFHW[10]        0x078
    136  * NRFHW[11]        0x07C
    137  * CUSTOMER[0]      0x080
    138  * CUSTOMER[1]      0x084
    139  * CUSTOMER[2]      0x088
    140  * CUSTOMER[3]      0x08C
    141  * CUSTOMER[4]      0x090
    142  * CUSTOMER[5]      0x094
    143  * CUSTOMER[6]      0x098
    144  * CUSTOMER[7]      0x09C
    145  * CUSTOMER[8]      0x0A0
    146  * CUSTOMER[9]      0x0A4
    147  * CUSTOMER[10]     0x0A8
    148  * CUSTOMER[11]     0x0AC
    149  * CUSTOMER[12]     0x0B0
    150  * CUSTOMER[13]     0x0B4
    151  * CUSTOMER[14]     0x0B8
    152  * CUSTOMER[15]     0x0BC
    153  * CUSTOMER[16]     0x0C0
    154  * CUSTOMER[17]     0x0C4
    155  * CUSTOMER[18]     0x0C8
    156  * CUSTOMER[19]     0x0CC
    157  * CUSTOMER[20]     0x0D0
    158  * CUSTOMER[21]     0x0D4
    159  * CUSTOMER[22]     0x0D8
    160  * CUSTOMER[23]     0x0DC
    161  * CUSTOMER[24]     0x0E0
    162  * CUSTOMER[25]     0x0E4
    163  * CUSTOMER[26]     0x0E8
    164  * CUSTOMER[27]     0x0EC
    165  * CUSTOMER[28]     0x0F0
    166  * CUSTOMER[29]     0x0F4
    167  * CUSTOMER[30]     0x0F8
    168  * CUSTOMER[31]     0x0FC
    169  */
    170 
    171 static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
    172 {
    173     NRF51NVMState *s = NRF51_NVM(opaque);
    174 
    175     assert(offset < sizeof(s->uicr_content));
    176     return s->uicr_content[offset / 4];
    177 }
    178 
    179 static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
    180         unsigned int size)
    181 {
    182     NRF51NVMState *s = NRF51_NVM(opaque);
    183 
    184     assert(offset < sizeof(s->uicr_content));
    185     s->uicr_content[offset / 4] = value;
    186 }
    187 
    188 static const MemoryRegionOps uicr_ops = {
    189     .read = uicr_read,
    190     .write = uicr_write,
    191     .impl.min_access_size = 4,
    192     .impl.max_access_size = 4,
    193     .endianness = DEVICE_LITTLE_ENDIAN
    194 };
    195 
    196 
    197 static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
    198 {
    199     NRF51NVMState *s = NRF51_NVM(opaque);
    200     uint64_t r = 0;
    201 
    202     switch (offset) {
    203     case NRF51_NVMC_READY:
    204         r = NRF51_NVMC_READY_READY;
    205         break;
    206     case NRF51_NVMC_CONFIG:
    207         r = s->config;
    208         break;
    209     default:
    210         qemu_log_mask(LOG_GUEST_ERROR,
    211                 "%s: bad read offset 0x%" HWADDR_PRIx "\n", __func__, offset);
    212         break;
    213     }
    214 
    215     return r;
    216 }
    217 
    218 static void io_write(void *opaque, hwaddr offset, uint64_t value,
    219         unsigned int size)
    220 {
    221     NRF51NVMState *s = NRF51_NVM(opaque);
    222 
    223     switch (offset) {
    224     case NRF51_NVMC_CONFIG:
    225         s->config = value & NRF51_NVMC_CONFIG_MASK;
    226         break;
    227     case NRF51_NVMC_ERASEPCR0:
    228     case NRF51_NVMC_ERASEPCR1:
    229         if (s->config & NRF51_NVMC_CONFIG_EEN) {
    230             /* Mask in-page sub address */
    231             value &= ~(NRF51_PAGE_SIZE - 1);
    232             if (value <= (s->flash_size - NRF51_PAGE_SIZE)) {
    233                 memset(s->storage + value, 0xFF, NRF51_PAGE_SIZE);
    234                 memory_region_flush_rom_device(&s->flash, value,
    235                                                NRF51_PAGE_SIZE);
    236             }
    237         } else {
    238             qemu_log_mask(LOG_GUEST_ERROR,
    239             "%s: Flash erase at 0x%" HWADDR_PRIx" while flash not erasable.\n",
    240             __func__, offset);
    241         }
    242         break;
    243     case NRF51_NVMC_ERASEALL:
    244         if (value == NRF51_NVMC_ERASE) {
    245             if (s->config & NRF51_NVMC_CONFIG_EEN) {
    246                 memset(s->storage, 0xFF, s->flash_size);
    247                 memory_region_flush_rom_device(&s->flash, 0, s->flash_size);
    248                 memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
    249             } else {
    250                 qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash not erasable.\n",
    251                               __func__);
    252             }
    253         }
    254         break;
    255     case NRF51_NVMC_ERASEUICR:
    256         if (value == NRF51_NVMC_ERASE) {
    257             memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
    258         }
    259         break;
    260 
    261     default:
    262         qemu_log_mask(LOG_GUEST_ERROR,
    263                 "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
    264     }
    265 }
    266 
    267 static const MemoryRegionOps io_ops = {
    268         .read = io_read,
    269         .write = io_write,
    270         .impl.min_access_size = 4,
    271         .impl.max_access_size = 4,
    272         .endianness = DEVICE_LITTLE_ENDIAN,
    273 };
    274 
    275 static uint64_t flash_read(void *opaque, hwaddr offset, unsigned size)
    276 {
    277     /*
    278      * This is a rom_device MemoryRegion which is always in
    279      * romd_mode (we never put it in MMIO mode), so reads always
    280      * go directly to RAM and never come here.
    281      */
    282     g_assert_not_reached();
    283 }
    284 
    285 static void flash_write(void *opaque, hwaddr offset, uint64_t value,
    286         unsigned int size)
    287 {
    288     NRF51NVMState *s = NRF51_NVM(opaque);
    289 
    290     if (s->config & NRF51_NVMC_CONFIG_WEN) {
    291         uint32_t oldval;
    292 
    293         assert(offset + size <= s->flash_size);
    294 
    295         /* NOR Flash only allows bits to be flipped from 1's to 0's on write */
    296         oldval = ldl_le_p(s->storage + offset);
    297         oldval &= value;
    298         stl_le_p(s->storage + offset, oldval);
    299 
    300         memory_region_flush_rom_device(&s->flash, offset, size);
    301     } else {
    302         qemu_log_mask(LOG_GUEST_ERROR,
    303                 "%s: Flash write 0x%" HWADDR_PRIx" while flash not writable.\n",
    304                 __func__, offset);
    305     }
    306 }
    307 
    308 
    309 
    310 static const MemoryRegionOps flash_ops = {
    311     .read = flash_read,
    312     .write = flash_write,
    313     .valid.min_access_size = 4,
    314     .valid.max_access_size = 4,
    315     .endianness = DEVICE_LITTLE_ENDIAN,
    316 };
    317 
    318 static void nrf51_nvm_init(Object *obj)
    319 {
    320     NRF51NVMState *s = NRF51_NVM(obj);
    321     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    322 
    323     memory_region_init_io(&s->mmio, obj, &io_ops, s, "nrf51_soc.nvmc",
    324                           NRF51_NVMC_SIZE);
    325     sysbus_init_mmio(sbd, &s->mmio);
    326 
    327     memory_region_init_io(&s->ficr, obj, &ficr_ops, s, "nrf51_soc.ficr",
    328                           sizeof(ficr_content));
    329     sysbus_init_mmio(sbd, &s->ficr);
    330 
    331     memory_region_init_io(&s->uicr, obj, &uicr_ops, s, "nrf51_soc.uicr",
    332                           sizeof(s->uicr_content));
    333     sysbus_init_mmio(sbd, &s->uicr);
    334 }
    335 
    336 static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
    337 {
    338     NRF51NVMState *s = NRF51_NVM(dev);
    339     Error *err = NULL;
    340 
    341     memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
    342         "nrf51_soc.flash", s->flash_size, &err);
    343     if (err) {
    344         error_propagate(errp, err);
    345         return;
    346     }
    347 
    348     s->storage = memory_region_get_ram_ptr(&s->flash);
    349     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
    350 }
    351 
    352 static void nrf51_nvm_reset(DeviceState *dev)
    353 {
    354     NRF51NVMState *s = NRF51_NVM(dev);
    355 
    356     s->config = 0x00;
    357     memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
    358 }
    359 
    360 static Property nrf51_nvm_properties[] = {
    361     DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
    362     DEFINE_PROP_END_OF_LIST(),
    363 };
    364 
    365 static const VMStateDescription vmstate_nvm = {
    366     .name = "nrf51_soc.nvm",
    367     .version_id = 1,
    368     .minimum_version_id = 1,
    369     .fields = (VMStateField[]) {
    370         VMSTATE_UINT32_ARRAY(uicr_content, NRF51NVMState,
    371                 NRF51_UICR_FIXTURE_SIZE),
    372         VMSTATE_UINT32(config, NRF51NVMState),
    373         VMSTATE_END_OF_LIST()
    374     }
    375 };
    376 
    377 static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
    378 {
    379     DeviceClass *dc = DEVICE_CLASS(klass);
    380 
    381     device_class_set_props(dc, nrf51_nvm_properties);
    382     dc->vmsd = &vmstate_nvm;
    383     dc->realize = nrf51_nvm_realize;
    384     dc->reset = nrf51_nvm_reset;
    385 }
    386 
    387 static const TypeInfo nrf51_nvm_info = {
    388     .name = TYPE_NRF51_NVM,
    389     .parent = TYPE_SYS_BUS_DEVICE,
    390     .instance_size = sizeof(NRF51NVMState),
    391     .instance_init = nrf51_nvm_init,
    392     .class_init = nrf51_nvm_class_init
    393 };
    394 
    395 static void nrf51_nvm_register_types(void)
    396 {
    397     type_register_static(&nrf51_nvm_info);
    398 }
    399 
    400 type_init(nrf51_nvm_register_types)