qemu/hw/nvram/xlnx-zynqmp-efuse.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the ZynqMP eFuse
   3 *
   4 * Copyright (c) 2015 Xilinx Inc.
   5 *
   6 * Written by Edgar E. Iglesias <edgari@xilinx.com>
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  25 */
  26
  27#include "qemu/osdep.h"
  28#include "hw/nvram/xlnx-zynqmp-efuse.h"
  29
  30#include "qemu/log.h"
  31#include "qapi/error.h"
  32#include "migration/vmstate.h"
  33#include "hw/qdev-properties.h"
  34
  35#ifndef ZYNQMP_EFUSE_ERR_DEBUG
  36#define ZYNQMP_EFUSE_ERR_DEBUG 0
  37#endif
  38
  39REG32(WR_LOCK, 0x0)
  40    FIELD(WR_LOCK, LOCK, 0, 16)
  41REG32(CFG, 0x4)
  42    FIELD(CFG, SLVERR_ENABLE, 5, 1)
  43    FIELD(CFG, MARGIN_RD, 2, 2)
  44    FIELD(CFG, PGM_EN, 1, 1)
  45    FIELD(CFG, EFUSE_CLK_SEL, 0, 1)
  46REG32(STATUS, 0x8)
  47    FIELD(STATUS, AES_CRC_PASS, 7, 1)
  48    FIELD(STATUS, AES_CRC_DONE, 6, 1)
  49    FIELD(STATUS, CACHE_DONE, 5, 1)
  50    FIELD(STATUS, CACHE_LOAD, 4, 1)
  51    FIELD(STATUS, EFUSE_3_TBIT, 2, 1)
  52    FIELD(STATUS, EFUSE_2_TBIT, 1, 1)
  53    FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
  54REG32(EFUSE_PGM_ADDR, 0xc)
  55    FIELD(EFUSE_PGM_ADDR, EFUSE, 11, 2)
  56    FIELD(EFUSE_PGM_ADDR, ROW, 5, 6)
  57    FIELD(EFUSE_PGM_ADDR, COLUMN, 0, 5)
  58REG32(EFUSE_RD_ADDR, 0x10)
  59    FIELD(EFUSE_RD_ADDR, EFUSE, 11, 2)
  60    FIELD(EFUSE_RD_ADDR, ROW, 5, 6)
  61REG32(EFUSE_RD_DATA, 0x14)
  62REG32(TPGM, 0x18)
  63    FIELD(TPGM, VALUE, 0, 16)
  64REG32(TRD, 0x1c)
  65    FIELD(TRD, VALUE, 0, 8)
  66REG32(TSU_H_PS, 0x20)
  67    FIELD(TSU_H_PS, VALUE, 0, 8)
  68REG32(TSU_H_PS_CS, 0x24)
  69    FIELD(TSU_H_PS_CS, VALUE, 0, 8)
  70REG32(TSU_H_CS, 0x2c)
  71    FIELD(TSU_H_CS, VALUE, 0, 4)
  72REG32(EFUSE_ISR, 0x30)
  73    FIELD(EFUSE_ISR, APB_SLVERR, 31, 1)
  74    FIELD(EFUSE_ISR, CACHE_ERROR, 4, 1)
  75    FIELD(EFUSE_ISR, RD_ERROR, 3, 1)
  76    FIELD(EFUSE_ISR, RD_DONE, 2, 1)
  77    FIELD(EFUSE_ISR, PGM_ERROR, 1, 1)
  78    FIELD(EFUSE_ISR, PGM_DONE, 0, 1)
  79REG32(EFUSE_IMR, 0x34)
  80    FIELD(EFUSE_IMR, APB_SLVERR, 31, 1)
  81    FIELD(EFUSE_IMR, CACHE_ERROR, 4, 1)
  82    FIELD(EFUSE_IMR, RD_ERROR, 3, 1)
  83    FIELD(EFUSE_IMR, RD_DONE, 2, 1)
  84    FIELD(EFUSE_IMR, PGM_ERROR, 1, 1)
  85    FIELD(EFUSE_IMR, PGM_DONE, 0, 1)
  86REG32(EFUSE_IER, 0x38)
  87    FIELD(EFUSE_IER, APB_SLVERR, 31, 1)
  88    FIELD(EFUSE_IER, CACHE_ERROR, 4, 1)
  89    FIELD(EFUSE_IER, RD_ERROR, 3, 1)
  90    FIELD(EFUSE_IER, RD_DONE, 2, 1)
  91    FIELD(EFUSE_IER, PGM_ERROR, 1, 1)
  92    FIELD(EFUSE_IER, PGM_DONE, 0, 1)
  93REG32(EFUSE_IDR, 0x3c)
  94    FIELD(EFUSE_IDR, APB_SLVERR, 31, 1)
  95    FIELD(EFUSE_IDR, CACHE_ERROR, 4, 1)
  96    FIELD(EFUSE_IDR, RD_ERROR, 3, 1)
  97    FIELD(EFUSE_IDR, RD_DONE, 2, 1)
  98    FIELD(EFUSE_IDR, PGM_ERROR, 1, 1)
  99    FIELD(EFUSE_IDR, PGM_DONE, 0, 1)
 100REG32(EFUSE_CACHE_LOAD, 0x40)
 101    FIELD(EFUSE_CACHE_LOAD, LOAD, 0, 1)
 102REG32(EFUSE_PGM_LOCK, 0x44)
 103    FIELD(EFUSE_PGM_LOCK, SPK_ID_LOCK, 0, 1)
 104REG32(EFUSE_AES_CRC, 0x48)
 105REG32(EFUSE_TBITS_PRGRMG_EN, 0x100)
 106    FIELD(EFUSE_TBITS_PRGRMG_EN, TBITS_PRGRMG_EN, 3, 1)
 107REG32(DNA_0, 0x100c)
 108REG32(DNA_1, 0x1010)
 109REG32(DNA_2, 0x1014)
 110REG32(IPDISABLE, 0x1018)
 111    FIELD(IPDISABLE, VCU_DIS, 8, 1)
 112    FIELD(IPDISABLE, GPU_DIS, 5, 1)
 113    FIELD(IPDISABLE, APU3_DIS, 3, 1)
 114    FIELD(IPDISABLE, APU2_DIS, 2, 1)
 115    FIELD(IPDISABLE, APU1_DIS, 1, 1)
 116    FIELD(IPDISABLE, APU0_DIS, 0, 1)
 117REG32(SYSOSC_CTRL, 0x101c)
 118    FIELD(SYSOSC_CTRL, SYSOSC_EN, 0, 1)
 119REG32(USER_0, 0x1020)
 120REG32(USER_1, 0x1024)
 121REG32(USER_2, 0x1028)
 122REG32(USER_3, 0x102c)
 123REG32(USER_4, 0x1030)
 124REG32(USER_5, 0x1034)
 125REG32(USER_6, 0x1038)
 126REG32(USER_7, 0x103c)
 127REG32(MISC_USER_CTRL, 0x1040)
 128    FIELD(MISC_USER_CTRL, FPD_SC_EN_0, 14, 1)
 129    FIELD(MISC_USER_CTRL, LPD_SC_EN_0, 11, 1)
 130    FIELD(MISC_USER_CTRL, LBIST_EN, 10, 1)
 131    FIELD(MISC_USER_CTRL, USR_WRLK_7, 7, 1)
 132    FIELD(MISC_USER_CTRL, USR_WRLK_6, 6, 1)
 133    FIELD(MISC_USER_CTRL, USR_WRLK_5, 5, 1)
 134    FIELD(MISC_USER_CTRL, USR_WRLK_4, 4, 1)
 135    FIELD(MISC_USER_CTRL, USR_WRLK_3, 3, 1)
 136    FIELD(MISC_USER_CTRL, USR_WRLK_2, 2, 1)
 137    FIELD(MISC_USER_CTRL, USR_WRLK_1, 1, 1)
 138    FIELD(MISC_USER_CTRL, USR_WRLK_0, 0, 1)
 139REG32(ROM_RSVD, 0x1044)
 140    FIELD(ROM_RSVD, PBR_BOOT_ERROR, 0, 3)
 141REG32(PUF_CHASH, 0x1050)
 142REG32(PUF_MISC, 0x1054)
 143    FIELD(PUF_MISC, REGISTER_DIS, 31, 1)
 144    FIELD(PUF_MISC, SYN_WRLK, 30, 1)
 145    FIELD(PUF_MISC, SYN_INVLD, 29, 1)
 146    FIELD(PUF_MISC, TEST2_DIS, 28, 1)
 147    FIELD(PUF_MISC, UNUSED27, 27, 1)
 148    FIELD(PUF_MISC, UNUSED26, 26, 1)
 149    FIELD(PUF_MISC, UNUSED25, 25, 1)
 150    FIELD(PUF_MISC, UNUSED24, 24, 1)
 151    FIELD(PUF_MISC, AUX, 0, 24)
 152REG32(SEC_CTRL, 0x1058)
 153    FIELD(SEC_CTRL, PPK1_INVLD, 30, 2)
 154    FIELD(SEC_CTRL, PPK1_WRLK, 29, 1)
 155    FIELD(SEC_CTRL, PPK0_INVLD, 27, 2)
 156    FIELD(SEC_CTRL, PPK0_WRLK, 26, 1)
 157    FIELD(SEC_CTRL, RSA_EN, 11, 15)
 158    FIELD(SEC_CTRL, SEC_LOCK, 10, 1)
 159    FIELD(SEC_CTRL, PROG_GATE_2, 9, 1)
 160    FIELD(SEC_CTRL, PROG_GATE_1, 8, 1)
 161    FIELD(SEC_CTRL, PROG_GATE_0, 7, 1)
 162    FIELD(SEC_CTRL, DFT_DIS, 6, 1)
 163    FIELD(SEC_CTRL, JTAG_DIS, 5, 1)
 164    FIELD(SEC_CTRL, ERROR_DIS, 4, 1)
 165    FIELD(SEC_CTRL, BBRAM_DIS, 3, 1)
 166    FIELD(SEC_CTRL, ENC_ONLY, 2, 1)
 167    FIELD(SEC_CTRL, AES_WRLK, 1, 1)
 168    FIELD(SEC_CTRL, AES_RDLK, 0, 1)
 169REG32(SPK_ID, 0x105c)
 170REG32(PPK0_0, 0x10a0)
 171REG32(PPK0_1, 0x10a4)
 172REG32(PPK0_2, 0x10a8)
 173REG32(PPK0_3, 0x10ac)
 174REG32(PPK0_4, 0x10b0)
 175REG32(PPK0_5, 0x10b4)
 176REG32(PPK0_6, 0x10b8)
 177REG32(PPK0_7, 0x10bc)
 178REG32(PPK0_8, 0x10c0)
 179REG32(PPK0_9, 0x10c4)
 180REG32(PPK0_10, 0x10c8)
 181REG32(PPK0_11, 0x10cc)
 182REG32(PPK1_0, 0x10d0)
 183REG32(PPK1_1, 0x10d4)
 184REG32(PPK1_2, 0x10d8)
 185REG32(PPK1_3, 0x10dc)
 186REG32(PPK1_4, 0x10e0)
 187REG32(PPK1_5, 0x10e4)
 188REG32(PPK1_6, 0x10e8)
 189REG32(PPK1_7, 0x10ec)
 190REG32(PPK1_8, 0x10f0)
 191REG32(PPK1_9, 0x10f4)
 192REG32(PPK1_10, 0x10f8)
 193REG32(PPK1_11, 0x10fc)
 194
 195#define BIT_POS(ROW, COLUMN)    (ROW * 32 + COLUMN)
 196#define R_MAX (R_PPK1_11 + 1)
 197
 198/* #define EFUSE_XOSC            26 */
 199
 200/*
 201 * eFUSE layout references:
 202 *   ZynqMP: UG1085 (v2.1) August 21, 2019, p.277, Table 12-13
 203 */
 204#define EFUSE_AES_RDLK        BIT_POS(22, 0)
 205#define EFUSE_AES_WRLK        BIT_POS(22, 1)
 206#define EFUSE_ENC_ONLY        BIT_POS(22, 2)
 207#define EFUSE_BBRAM_DIS       BIT_POS(22, 3)
 208#define EFUSE_ERROR_DIS       BIT_POS(22, 4)
 209#define EFUSE_JTAG_DIS        BIT_POS(22, 5)
 210#define EFUSE_DFT_DIS         BIT_POS(22, 6)
 211#define EFUSE_PROG_GATE_0     BIT_POS(22, 7)
 212#define EFUSE_PROG_GATE_1     BIT_POS(22, 7)
 213#define EFUSE_PROG_GATE_2     BIT_POS(22, 9)
 214#define EFUSE_SEC_LOCK        BIT_POS(22, 10)
 215#define EFUSE_RSA_EN          BIT_POS(22, 11)
 216#define EFUSE_RSA_EN14        BIT_POS(22, 25)
 217#define EFUSE_PPK0_WRLK       BIT_POS(22, 26)
 218#define EFUSE_PPK0_INVLD      BIT_POS(22, 27)
 219#define EFUSE_PPK0_INVLD_1    BIT_POS(22, 28)
 220#define EFUSE_PPK1_WRLK       BIT_POS(22, 29)
 221#define EFUSE_PPK1_INVLD      BIT_POS(22, 30)
 222#define EFUSE_PPK1_INVLD_1    BIT_POS(22, 31)
 223
 224/* Areas.  */
 225#define EFUSE_TRIM_START      BIT_POS(1, 0)
 226#define EFUSE_TRIM_END        BIT_POS(1, 30)
 227#define EFUSE_DNA_START       BIT_POS(3, 0)
 228#define EFUSE_DNA_END         BIT_POS(5, 31)
 229#define EFUSE_AES_START       BIT_POS(24, 0)
 230#define EFUSE_AES_END         BIT_POS(31, 31)
 231#define EFUSE_ROM_START       BIT_POS(17, 0)
 232#define EFUSE_ROM_END         BIT_POS(17, 31)
 233#define EFUSE_IPDIS_START     BIT_POS(6, 0)
 234#define EFUSE_IPDIS_END       BIT_POS(6, 31)
 235#define EFUSE_USER_START      BIT_POS(8, 0)
 236#define EFUSE_USER_END        BIT_POS(15, 31)
 237#define EFUSE_BISR_START      BIT_POS(32, 0)
 238#define EFUSE_BISR_END        BIT_POS(39, 31)
 239
 240#define EFUSE_USER_CTRL_START BIT_POS(16, 0)
 241#define EFUSE_USER_CTRL_END   BIT_POS(16, 16)
 242#define EFUSE_USER_CTRL_MASK  ((uint32_t)MAKE_64BIT_MASK(0, 17))
 243
 244#define EFUSE_PUF_CHASH_START BIT_POS(20, 0)
 245#define EFUSE_PUF_CHASH_END   BIT_POS(20, 31)
 246#define EFUSE_PUF_MISC_START  BIT_POS(21, 0)
 247#define EFUSE_PUF_MISC_END    BIT_POS(21, 31)
 248#define EFUSE_PUF_SYN_WRLK    BIT_POS(21, 30)
 249
 250#define EFUSE_SPK_START       BIT_POS(23, 0)
 251#define EFUSE_SPK_END         BIT_POS(23, 31)
 252
 253#define EFUSE_PPK0_START      BIT_POS(40, 0)
 254#define EFUSE_PPK0_END        BIT_POS(51, 31)
 255#define EFUSE_PPK1_START      BIT_POS(52, 0)
 256#define EFUSE_PPK1_END        BIT_POS(63, 31)
 257
 258#define EFUSE_CACHE_FLD(s, reg, field) \
 259    ARRAY_FIELD_DP32((s)->regs, reg, field, \
 260                     (xlnx_efuse_get_row((s->efuse), EFUSE_ ## field) \
 261                      >> (EFUSE_ ## field % 32)))
 262
 263#define EFUSE_CACHE_BIT(s, reg, field) \
 264    ARRAY_FIELD_DP32((s)->regs, reg, field, xlnx_efuse_get_bit((s->efuse), \
 265                EFUSE_ ## field))
 266
 267#define FBIT_UNKNOWN (~0)
 268
 269QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxZynqMPEFuse *)0)->regs));
 270
 271static void update_tbit_status(XlnxZynqMPEFuse *s)
 272{
 273    unsigned int check = xlnx_efuse_tbits_check(s->efuse);
 274    uint32_t val = s->regs[R_STATUS];
 275
 276    val = FIELD_DP32(val, STATUS, EFUSE_0_TBIT, !!(check & (1 << 0)));
 277    val = FIELD_DP32(val, STATUS, EFUSE_2_TBIT, !!(check & (1 << 1)));
 278    val = FIELD_DP32(val, STATUS, EFUSE_3_TBIT, !!(check & (1 << 2)));
 279
 280    s->regs[R_STATUS] = val;
 281}
 282
 283/* Update the u32 array from efuse bits. Slow but simple approach.  */
 284static void cache_sync_u32(XlnxZynqMPEFuse *s, unsigned int r_start,
 285                           unsigned int f_start, unsigned int f_end,
 286                           unsigned int f_written)
 287{
 288    uint32_t *u32 = &s->regs[r_start];
 289    unsigned int fbit, wbits = 0, u32_off = 0;
 290
 291    /* Avoid working on bits that are not relevant.  */
 292    if (f_written != FBIT_UNKNOWN
 293        && (f_written < f_start || f_written > f_end)) {
 294        return;
 295    }
 296
 297    for (fbit = f_start; fbit <= f_end; fbit++, wbits++) {
 298        if (wbits == 32) {
 299            /* Update the key offset.  */
 300            u32_off += 1;
 301            wbits = 0;
 302        }
 303        u32[u32_off] |= xlnx_efuse_get_bit(s->efuse, fbit) << wbits;
 304    }
 305}
 306
 307/*
 308 * Keep the syncs in bit order so we can bail out for the
 309 * slower ones.
 310 */
 311static void zynqmp_efuse_sync_cache(XlnxZynqMPEFuse *s, unsigned int bit)
 312{
 313    EFUSE_CACHE_BIT(s, SEC_CTRL, AES_RDLK);
 314    EFUSE_CACHE_BIT(s, SEC_CTRL, AES_WRLK);
 315    EFUSE_CACHE_BIT(s, SEC_CTRL, ENC_ONLY);
 316    EFUSE_CACHE_BIT(s, SEC_CTRL, BBRAM_DIS);
 317    EFUSE_CACHE_BIT(s, SEC_CTRL, ERROR_DIS);
 318    EFUSE_CACHE_BIT(s, SEC_CTRL, JTAG_DIS);
 319    EFUSE_CACHE_BIT(s, SEC_CTRL, DFT_DIS);
 320    EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_0);
 321    EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_1);
 322    EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_2);
 323    EFUSE_CACHE_BIT(s, SEC_CTRL, SEC_LOCK);
 324    EFUSE_CACHE_BIT(s, SEC_CTRL, PPK0_WRLK);
 325    EFUSE_CACHE_BIT(s, SEC_CTRL, PPK1_WRLK);
 326
 327    EFUSE_CACHE_FLD(s, SEC_CTRL, RSA_EN);
 328    EFUSE_CACHE_FLD(s, SEC_CTRL, PPK0_INVLD);
 329    EFUSE_CACHE_FLD(s, SEC_CTRL, PPK1_INVLD);
 330
 331    /* Update the tbits.  */
 332    update_tbit_status(s);
 333
 334    /* Sync the various areas.  */
 335    s->regs[R_MISC_USER_CTRL] = xlnx_efuse_get_row(s->efuse,
 336                                                   EFUSE_USER_CTRL_START)
 337                                & EFUSE_USER_CTRL_MASK;
 338    s->regs[R_PUF_CHASH] = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_CHASH_START);
 339    s->regs[R_PUF_MISC]  = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_MISC_START);
 340
 341    cache_sync_u32(s, R_DNA_0, EFUSE_DNA_START, EFUSE_DNA_END, bit);
 342
 343    if (bit < EFUSE_AES_START) {
 344        return;
 345    }
 346
 347    cache_sync_u32(s, R_ROM_RSVD, EFUSE_ROM_START, EFUSE_ROM_END, bit);
 348    cache_sync_u32(s, R_IPDISABLE, EFUSE_IPDIS_START, EFUSE_IPDIS_END, bit);
 349    cache_sync_u32(s, R_USER_0, EFUSE_USER_START, EFUSE_USER_END, bit);
 350    cache_sync_u32(s, R_SPK_ID, EFUSE_SPK_START, EFUSE_SPK_END, bit);
 351    cache_sync_u32(s, R_PPK0_0, EFUSE_PPK0_START, EFUSE_PPK0_END, bit);
 352    cache_sync_u32(s, R_PPK1_0, EFUSE_PPK1_START, EFUSE_PPK1_END, bit);
 353}
 354
 355static void zynqmp_efuse_update_irq(XlnxZynqMPEFuse *s)
 356{
 357    bool pending = s->regs[R_EFUSE_ISR] & s->regs[R_EFUSE_IMR];
 358    qemu_set_irq(s->irq, pending);
 359}
 360
 361static void zynqmp_efuse_isr_postw(RegisterInfo *reg, uint64_t val64)
 362{
 363    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
 364    zynqmp_efuse_update_irq(s);
 365}
 366
 367static uint64_t zynqmp_efuse_ier_prew(RegisterInfo *reg, uint64_t val64)
 368{
 369    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
 370    uint32_t val = val64;
 371
 372    s->regs[R_EFUSE_IMR] |= val;
 373    zynqmp_efuse_update_irq(s);
 374    return 0;
 375}
 376
 377static uint64_t zynqmp_efuse_idr_prew(RegisterInfo *reg, uint64_t val64)
 378{
 379    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
 380    uint32_t val = val64;
 381
 382    s->regs[R_EFUSE_IMR] &= ~val;
 383    zynqmp_efuse_update_irq(s);
 384    return 0;
 385}
 386
 387static void zynqmp_efuse_pgm_addr_postw(RegisterInfo *reg, uint64_t val64)
 388{
 389    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
 390    unsigned bit = val64;
 391    unsigned page = FIELD_EX32(bit, EFUSE_PGM_ADDR, EFUSE);
 392    bool puf_prot = false;
 393    const char *errmsg = NULL;
 394
 395    /* Allow only valid array, and adjust for skipped array 1 */
 396    switch (page) {
 397    case 0:
 398        break;
 399    case 2 ... 3:
 400        bit = FIELD_DP32(bit, EFUSE_PGM_ADDR, EFUSE, page - 1);
 401        puf_prot = xlnx_efuse_get_bit(s->efuse, EFUSE_PUF_SYN_WRLK);
 402        break;
 403    default:
 404        errmsg = "Invalid address";
 405        goto pgm_done;
 406    }
 407
 408    if (ARRAY_FIELD_EX32(s->regs, WR_LOCK, LOCK)) {
 409        errmsg = "Array write-locked";
 410        goto pgm_done;
 411    }
 412
 413    if (!ARRAY_FIELD_EX32(s->regs, CFG, PGM_EN)) {
 414        errmsg = "Array pgm-disabled";
 415        goto pgm_done;
 416    }
 417
 418    if (puf_prot) {
 419        errmsg = "PUF_HD-store write-locked";
 420        goto pgm_done;
 421    }
 422
 423    if (ARRAY_FIELD_EX32(s->regs, SEC_CTRL, AES_WRLK)
 424        && bit >= EFUSE_AES_START && bit <= EFUSE_AES_END) {
 425        errmsg = "AES key-store Write-locked";
 426        goto pgm_done;
 427    }
 428
 429    if (!xlnx_efuse_set_bit(s->efuse, bit)) {
 430        errmsg = "Write failed";
 431    }
 432
 433 pgm_done:
 434    if (!errmsg) {
 435        ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 0);
 436    } else {
 437        g_autofree char *path = object_get_canonical_path(OBJECT(s));
 438
 439        ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
 440        qemu_log_mask(LOG_GUEST_ERROR,
 441                      "%s - eFuse write error: %s; addr=0x%x\n",
 442                      path, errmsg, (unsigned)val64);
 443    }
 444
 445    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
 446    zynqmp_efuse_update_irq(s);
 447}
 448
 449static void zynqmp_efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
 450{
 451    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
 452    g_autofree char *path = NULL;
 453
 454    /*
 455     * Grant reads only to allowed bits; reference sources:
 456     * 1/ XilSKey - XilSKey_ZynqMp_EfusePs_ReadRow()
 457     * 2/ UG1085, v2.0, table 12-13
 458     * (note: enumerates the masks as <first, last> per described in
 459     *  references to avoid mental translation).
 460     */
 461#define COL_MASK(L_, H_) \
 462    ((uint32_t)MAKE_64BIT_MASK((L_), (1 + (H_) - (L_))))
 463
 464    static const uint32_t ary0_col_mask[] = {
 465        /* XilSKey - XSK_ZYNQMP_EFUSEPS_TBITS_ROW */
 466        [0]  = COL_MASK(28, 31),
 467
 468        /* XilSKey - XSK_ZYNQMP_EFUSEPS_USR{0:7}_FUSE_ROW */
 469        [8]  = COL_MASK(0, 31), [9]  = COL_MASK(0, 31),
 470        [10] = COL_MASK(0, 31), [11] = COL_MASK(0, 31),
 471        [12] = COL_MASK(0, 31), [13] = COL_MASK(0, 31),
 472        [14] = COL_MASK(0, 31), [15] = COL_MASK(0, 31),
 473
 474        /* XilSKey - XSK_ZYNQMP_EFUSEPS_MISC_USR_CTRL_ROW */
 475        [16] = COL_MASK(0, 7) | COL_MASK(10, 16),
 476
 477        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PBR_BOOT_ERR_ROW */
 478        [17] = COL_MASK(0, 2),
 479
 480        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_CHASH_ROW */
 481        [20] = COL_MASK(0, 31),
 482
 483        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_AUX_ROW */
 484        [21] = COL_MASK(0, 23) | COL_MASK(29, 31),
 485
 486        /* XilSKey - XSK_ZYNQMP_EFUSEPS_SEC_CTRL_ROW */
 487        [22] = COL_MASK(0, 31),
 488
 489        /* XilSKey - XSK_ZYNQMP_EFUSEPS_SPK_ID_ROW */
 490        [23] = COL_MASK(0, 31),
 491
 492        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK0_START_ROW */
 493        [40] = COL_MASK(0, 31), [41] = COL_MASK(0, 31),
 494        [42] = COL_MASK(0, 31), [43] = COL_MASK(0, 31),
 495        [44] = COL_MASK(0, 31), [45] = COL_MASK(0, 31),
 496        [46] = COL_MASK(0, 31), [47] = COL_MASK(0, 31),
 497        [48] = COL_MASK(0, 31), [49] = COL_MASK(0, 31),
 498        [50] = COL_MASK(0, 31), [51] = COL_MASK(0, 31),
 499
 500        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK1_START_ROW */
 501        [52] = COL_MASK(0, 31), [53] = COL_MASK(0, 31),
 502        [54] = COL_MASK(0, 31), [55] = COL_MASK(0, 31),
 503        [56] = COL_MASK(0, 31), [57] = COL_MASK(0, 31),
 504        [58] = COL_MASK(0, 31), [59] = COL_MASK(0, 31),
 505        [60] = COL_MASK(0, 31), [61] = COL_MASK(0, 31),
 506        [62] = COL_MASK(0, 31), [63] = COL_MASK(0, 31),
 507    };
 508
 509    uint32_t col_mask = COL_MASK(0, 31);
 510#undef COL_MASK
 511
 512    uint32_t efuse_idx = s->regs[R_EFUSE_RD_ADDR];
 513    uint32_t efuse_ary = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, EFUSE);
 514    uint32_t efuse_row = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, ROW);
 515
 516    switch (efuse_ary) {
 517    case 0:     /* Various */
 518        if (efuse_row >= ARRAY_SIZE(ary0_col_mask)) {
 519            goto denied;
 520        }
 521
 522        col_mask = ary0_col_mask[efuse_row];
 523        if (!col_mask) {
 524            goto denied;
 525        }
 526        break;
 527    case 2:     /* PUF helper data, adjust for skipped array 1 */
 528    case 3:
 529        val64 = FIELD_DP32(efuse_idx, EFUSE_RD_ADDR, EFUSE, efuse_ary - 1);
 530        break;
 531    default:
 532        goto denied;
 533    }
 534
 535    s->regs[R_EFUSE_RD_DATA] = xlnx_efuse_get_row(s->efuse, val64) & col_mask;
 536
 537    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 0);
 538    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
 539    zynqmp_efuse_update_irq(s);
 540    return;
 541
 542 denied:
 543    path = object_get_canonical_path(OBJECT(s));
 544    qemu_log_mask(LOG_GUEST_ERROR,
 545                  "%s: Denied efuse read from array %u, row %u\n",
 546                  path, efuse_ary, efuse_row);
 547
 548    s->regs[R_EFUSE_RD_DATA] = 0;
 549
 550    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
 551    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 0);
 552    zynqmp_efuse_update_irq(s);
 553}
 554
 555static void zynqmp_efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
 556{
 557    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
 558    bool ok;
 559
 560    ok = xlnx_efuse_k256_check(s->efuse, (uint32_t)val64, EFUSE_AES_START);
 561
 562    ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_PASS, (ok ? 1 : 0));
 563    ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_DONE, 1);
 564
 565    s->regs[R_EFUSE_AES_CRC] = 0;   /* crc value is write-only */
 566}
 567
 568static uint64_t zynqmp_efuse_cache_load_prew(RegisterInfo *reg,
 569                                             uint64_t valu64)
 570{
 571    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
 572
 573    if (valu64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
 574        zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
 575        ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
 576        zynqmp_efuse_update_irq(s);
 577    }
 578
 579    return 0;
 580}
 581
 582static uint64_t zynqmp_efuse_wr_lock_prew(RegisterInfo *reg, uint64_t val)
 583{
 584    return val == 0xDF0D ? 0 : 1;
 585}
 586
 587static RegisterAccessInfo zynqmp_efuse_regs_info[] = {
 588    {   .name = "WR_LOCK",  .addr = A_WR_LOCK,
 589        .reset = 0x1,
 590        .pre_write = zynqmp_efuse_wr_lock_prew,
 591    },{ .name = "CFG",  .addr = A_CFG,
 592    },{ .name = "STATUS",  .addr = A_STATUS,
 593        .rsvd = 0x8,
 594        .ro = 0xff,
 595    },{ .name = "EFUSE_PGM_ADDR",  .addr = A_EFUSE_PGM_ADDR,
 596         .post_write = zynqmp_efuse_pgm_addr_postw
 597    },{ .name = "EFUSE_RD_ADDR",  .addr = A_EFUSE_RD_ADDR,
 598        .rsvd = 0x1f,
 599        .post_write = zynqmp_efuse_rd_addr_postw,
 600    },{ .name = "EFUSE_RD_DATA",  .addr = A_EFUSE_RD_DATA,
 601        .ro = 0xffffffff,
 602    },{ .name = "TPGM",  .addr = A_TPGM,
 603    },{ .name = "TRD",  .addr = A_TRD,
 604        .reset = 0x1b,
 605    },{ .name = "TSU_H_PS",  .addr = A_TSU_H_PS,
 606        .reset = 0xff,
 607    },{ .name = "TSU_H_PS_CS",  .addr = A_TSU_H_PS_CS,
 608        .reset = 0xb,
 609    },{ .name = "TSU_H_CS",  .addr = A_TSU_H_CS,
 610        .reset = 0x7,
 611    },{ .name = "EFUSE_ISR",  .addr = A_EFUSE_ISR,
 612        .rsvd = 0x7fffffe0,
 613        .w1c = 0x8000001f,
 614        .post_write = zynqmp_efuse_isr_postw,
 615    },{ .name = "EFUSE_IMR",  .addr = A_EFUSE_IMR,
 616        .reset = 0x8000001f,
 617        .rsvd = 0x7fffffe0,
 618        .ro = 0xffffffff,
 619    },{ .name = "EFUSE_IER",  .addr = A_EFUSE_IER,
 620        .rsvd = 0x7fffffe0,
 621        .pre_write = zynqmp_efuse_ier_prew,
 622    },{ .name = "EFUSE_IDR",  .addr = A_EFUSE_IDR,
 623        .rsvd = 0x7fffffe0,
 624        .pre_write = zynqmp_efuse_idr_prew,
 625    },{ .name = "EFUSE_CACHE_LOAD",  .addr = A_EFUSE_CACHE_LOAD,
 626        .pre_write = zynqmp_efuse_cache_load_prew,
 627    },{ .name = "EFUSE_PGM_LOCK",  .addr = A_EFUSE_PGM_LOCK,
 628    },{ .name = "EFUSE_AES_CRC",  .addr = A_EFUSE_AES_CRC,
 629        .post_write = zynqmp_efuse_aes_crc_postw,
 630    },{ .name = "EFUSE_TBITS_PRGRMG_EN",  .addr = A_EFUSE_TBITS_PRGRMG_EN,
 631        .reset = R_EFUSE_TBITS_PRGRMG_EN_TBITS_PRGRMG_EN_MASK,
 632    },{ .name = "DNA_0",  .addr = A_DNA_0,
 633        .ro = 0xffffffff,
 634    },{ .name = "DNA_1",  .addr = A_DNA_1,
 635        .ro = 0xffffffff,
 636    },{ .name = "DNA_2",  .addr = A_DNA_2,
 637        .ro = 0xffffffff,
 638    },{ .name = "IPDISABLE",  .addr = A_IPDISABLE,
 639        .ro = 0xffffffff,
 640    },{ .name = "SYSOSC_CTRL",  .addr = A_SYSOSC_CTRL,
 641        .ro = 0xffffffff,
 642    },{ .name = "USER_0",  .addr = A_USER_0,
 643        .ro = 0xffffffff,
 644    },{ .name = "USER_1",  .addr = A_USER_1,
 645        .ro = 0xffffffff,
 646    },{ .name = "USER_2",  .addr = A_USER_2,
 647        .ro = 0xffffffff,
 648    },{ .name = "USER_3",  .addr = A_USER_3,
 649        .ro = 0xffffffff,
 650    },{ .name = "USER_4",  .addr = A_USER_4,
 651        .ro = 0xffffffff,
 652    },{ .name = "USER_5",  .addr = A_USER_5,
 653        .ro = 0xffffffff,
 654    },{ .name = "USER_6",  .addr = A_USER_6,
 655        .ro = 0xffffffff,
 656    },{ .name = "USER_7",  .addr = A_USER_7,
 657        .ro = 0xffffffff,
 658    },{ .name = "MISC_USER_CTRL",  .addr = A_MISC_USER_CTRL,
 659        .ro = 0xffffffff,
 660    },{ .name = "ROM_RSVD",  .addr = A_ROM_RSVD,
 661        .ro = 0xffffffff,
 662    },{ .name = "PUF_CHASH", .addr = A_PUF_CHASH,
 663        .ro = 0xffffffff,
 664    },{ .name = "PUF_MISC",  .addr = A_PUF_MISC,
 665        .ro = 0xffffffff,
 666    },{ .name = "SEC_CTRL",  .addr = A_SEC_CTRL,
 667        .ro = 0xffffffff,
 668    },{ .name = "SPK_ID",  .addr = A_SPK_ID,
 669        .ro = 0xffffffff,
 670    },{ .name = "PPK0_0",  .addr = A_PPK0_0,
 671        .ro = 0xffffffff,
 672    },{ .name = "PPK0_1",  .addr = A_PPK0_1,
 673        .ro = 0xffffffff,
 674    },{ .name = "PPK0_2",  .addr = A_PPK0_2,
 675        .ro = 0xffffffff,
 676    },{ .name = "PPK0_3",  .addr = A_PPK0_3,
 677        .ro = 0xffffffff,
 678    },{ .name = "PPK0_4",  .addr = A_PPK0_4,
 679        .ro = 0xffffffff,
 680    },{ .name = "PPK0_5",  .addr = A_PPK0_5,
 681        .ro = 0xffffffff,
 682    },{ .name = "PPK0_6",  .addr = A_PPK0_6,
 683        .ro = 0xffffffff,
 684    },{ .name = "PPK0_7",  .addr = A_PPK0_7,
 685        .ro = 0xffffffff,
 686    },{ .name = "PPK0_8",  .addr = A_PPK0_8,
 687        .ro = 0xffffffff,
 688    },{ .name = "PPK0_9",  .addr = A_PPK0_9,
 689        .ro = 0xffffffff,
 690    },{ .name = "PPK0_10",  .addr = A_PPK0_10,
 691        .ro = 0xffffffff,
 692    },{ .name = "PPK0_11",  .addr = A_PPK0_11,
 693        .ro = 0xffffffff,
 694    },{ .name = "PPK1_0",  .addr = A_PPK1_0,
 695        .ro = 0xffffffff,
 696    },{ .name = "PPK1_1",  .addr = A_PPK1_1,
 697        .ro = 0xffffffff,
 698    },{ .name = "PPK1_2",  .addr = A_PPK1_2,
 699        .ro = 0xffffffff,
 700    },{ .name = "PPK1_3",  .addr = A_PPK1_3,
 701        .ro = 0xffffffff,
 702    },{ .name = "PPK1_4",  .addr = A_PPK1_4,
 703        .ro = 0xffffffff,
 704    },{ .name = "PPK1_5",  .addr = A_PPK1_5,
 705        .ro = 0xffffffff,
 706    },{ .name = "PPK1_6",  .addr = A_PPK1_6,
 707        .ro = 0xffffffff,
 708    },{ .name = "PPK1_7",  .addr = A_PPK1_7,
 709        .ro = 0xffffffff,
 710    },{ .name = "PPK1_8",  .addr = A_PPK1_8,
 711        .ro = 0xffffffff,
 712    },{ .name = "PPK1_9",  .addr = A_PPK1_9,
 713        .ro = 0xffffffff,
 714    },{ .name = "PPK1_10",  .addr = A_PPK1_10,
 715        .ro = 0xffffffff,
 716    },{ .name = "PPK1_11",  .addr = A_PPK1_11,
 717        .ro = 0xffffffff,
 718    }
 719};
 720
 721static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
 722                                   uint64_t data, unsigned size)
 723{
 724    RegisterInfoArray *reg_array = opaque;
 725    XlnxZynqMPEFuse *s;
 726    Object *dev;
 727
 728    assert(reg_array != NULL);
 729
 730    dev = reg_array->mem.owner;
 731    assert(dev);
 732
 733    s = XLNX_ZYNQMP_EFUSE(dev);
 734
 735    if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
 736        g_autofree char *path = object_get_canonical_path(OBJECT(s));
 737
 738        qemu_log_mask(LOG_GUEST_ERROR,
 739                      "%s[reg_0x%02lx]: Attempt to write locked register.\n",
 740                      path, (long)addr);
 741    } else {
 742        register_write_memory(opaque, addr, data, size);
 743    }
 744}
 745
 746static const MemoryRegionOps zynqmp_efuse_ops = {
 747    .read = register_read_memory,
 748    .write = zynqmp_efuse_reg_write,
 749    .endianness = DEVICE_LITTLE_ENDIAN,
 750    .valid = {
 751        .min_access_size = 4,
 752        .max_access_size = 4,
 753    },
 754};
 755
 756static void zynqmp_efuse_register_reset(RegisterInfo *reg)
 757{
 758    if (!reg->data || !reg->access) {
 759        return;
 760    }
 761
 762    /* Reset must not trigger some registers' writers */
 763    switch (reg->access->addr) {
 764    case A_EFUSE_AES_CRC:
 765        *(uint32_t *)reg->data = reg->access->reset;
 766        return;
 767    }
 768
 769    register_reset(reg);
 770}
 771
 772static void zynqmp_efuse_reset(DeviceState *dev)
 773{
 774    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
 775    unsigned int i;
 776
 777    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 778        zynqmp_efuse_register_reset(&s->regs_info[i]);
 779    }
 780
 781    zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
 782    ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
 783    zynqmp_efuse_update_irq(s);
 784}
 785
 786static void zynqmp_efuse_realize(DeviceState *dev, Error **errp)
 787{
 788    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
 789
 790    if (!s->efuse) {
 791        g_autofree char *path = object_get_canonical_path(OBJECT(s));
 792
 793        error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
 794                   path);
 795        return;
 796    }
 797
 798    s->efuse->dev = dev;
 799}
 800
 801static void zynqmp_efuse_init(Object *obj)
 802{
 803    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
 804    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 805    RegisterInfoArray *reg_array;
 806
 807    reg_array =
 808        register_init_block32(DEVICE(obj), zynqmp_efuse_regs_info,
 809                              ARRAY_SIZE(zynqmp_efuse_regs_info),
 810                              s->regs_info, s->regs,
 811                              &zynqmp_efuse_ops,
 812                              ZYNQMP_EFUSE_ERR_DEBUG,
 813                              R_MAX * 4);
 814
 815    sysbus_init_mmio(sbd, &reg_array->mem);
 816    sysbus_init_irq(sbd, &s->irq);
 817}
 818
 819static const VMStateDescription vmstate_efuse = {
 820    .name = TYPE_XLNX_ZYNQMP_EFUSE,
 821    .version_id = 1,
 822    .minimum_version_id = 1,
 823    .fields = (VMStateField[]) {
 824        VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPEFuse, R_MAX),
 825        VMSTATE_END_OF_LIST(),
 826    }
 827};
 828
 829static Property zynqmp_efuse_props[] = {
 830    DEFINE_PROP_LINK("efuse",
 831                     XlnxZynqMPEFuse, efuse,
 832                     TYPE_XLNX_EFUSE, XlnxEFuse *),
 833
 834    DEFINE_PROP_END_OF_LIST(),
 835};
 836
 837static void zynqmp_efuse_class_init(ObjectClass *klass, void *data)
 838{
 839    DeviceClass *dc = DEVICE_CLASS(klass);
 840
 841    dc->reset = zynqmp_efuse_reset;
 842    dc->realize = zynqmp_efuse_realize;
 843    dc->vmsd = &vmstate_efuse;
 844    device_class_set_props(dc, zynqmp_efuse_props);
 845}
 846
 847
 848static const TypeInfo efuse_info = {
 849    .name          = TYPE_XLNX_ZYNQMP_EFUSE,
 850    .parent        = TYPE_SYS_BUS_DEVICE,
 851    .instance_size = sizeof(XlnxZynqMPEFuse),
 852    .class_init    = zynqmp_efuse_class_init,
 853    .instance_init = zynqmp_efuse_init,
 854};
 855
 856static void efuse_register_types(void)
 857{
 858    type_register_static(&efuse_info);
 859}
 860
 861type_init(efuse_register_types)
 862