cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

xlnx-zynqmp-efuse.c (28141B)


      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        ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
    438        qemu_log_mask(LOG_GUEST_ERROR,
    439                      "%s - eFuse write error: %s; addr=0x%x\n",
    440                      object_get_canonical_path(OBJECT(s)),
    441                      errmsg, (unsigned)val64);
    442    }
    443
    444    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
    445    zynqmp_efuse_update_irq(s);
    446}
    447
    448static void zynqmp_efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
    449{
    450    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
    451
    452    /*
    453     * Grant reads only to allowed bits; reference sources:
    454     * 1/ XilSKey - XilSKey_ZynqMp_EfusePs_ReadRow()
    455     * 2/ UG1085, v2.0, table 12-13
    456     * (note: enumerates the masks as <first, last> per described in
    457     *  references to avoid mental translation).
    458     */
    459#define COL_MASK(L_, H_) \
    460    ((uint32_t)MAKE_64BIT_MASK((L_), (1 + (H_) - (L_))))
    461
    462    static const uint32_t ary0_col_mask[] = {
    463        /* XilSKey - XSK_ZYNQMP_EFUSEPS_TBITS_ROW */
    464        [0]  = COL_MASK(28, 31),
    465
    466        /* XilSKey - XSK_ZYNQMP_EFUSEPS_USR{0:7}_FUSE_ROW */
    467        [8]  = COL_MASK(0, 31), [9]  = COL_MASK(0, 31),
    468        [10] = COL_MASK(0, 31), [11] = COL_MASK(0, 31),
    469        [12] = COL_MASK(0, 31), [13] = COL_MASK(0, 31),
    470        [14] = COL_MASK(0, 31), [15] = COL_MASK(0, 31),
    471
    472        /* XilSKey - XSK_ZYNQMP_EFUSEPS_MISC_USR_CTRL_ROW */
    473        [16] = COL_MASK(0, 7) | COL_MASK(10, 16),
    474
    475        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PBR_BOOT_ERR_ROW */
    476        [17] = COL_MASK(0, 2),
    477
    478        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_CHASH_ROW */
    479        [20] = COL_MASK(0, 31),
    480
    481        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_AUX_ROW */
    482        [21] = COL_MASK(0, 23) | COL_MASK(29, 31),
    483
    484        /* XilSKey - XSK_ZYNQMP_EFUSEPS_SEC_CTRL_ROW */
    485        [22] = COL_MASK(0, 31),
    486
    487        /* XilSKey - XSK_ZYNQMP_EFUSEPS_SPK_ID_ROW */
    488        [23] = COL_MASK(0, 31),
    489
    490        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK0_START_ROW */
    491        [40] = COL_MASK(0, 31), [41] = COL_MASK(0, 31),
    492        [42] = COL_MASK(0, 31), [43] = COL_MASK(0, 31),
    493        [44] = COL_MASK(0, 31), [45] = COL_MASK(0, 31),
    494        [46] = COL_MASK(0, 31), [47] = COL_MASK(0, 31),
    495        [48] = COL_MASK(0, 31), [49] = COL_MASK(0, 31),
    496        [50] = COL_MASK(0, 31), [51] = COL_MASK(0, 31),
    497
    498        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK1_START_ROW */
    499        [52] = COL_MASK(0, 31), [53] = COL_MASK(0, 31),
    500        [54] = COL_MASK(0, 31), [55] = COL_MASK(0, 31),
    501        [56] = COL_MASK(0, 31), [57] = COL_MASK(0, 31),
    502        [58] = COL_MASK(0, 31), [59] = COL_MASK(0, 31),
    503        [60] = COL_MASK(0, 31), [61] = COL_MASK(0, 31),
    504        [62] = COL_MASK(0, 31), [63] = COL_MASK(0, 31),
    505    };
    506
    507    uint32_t col_mask = COL_MASK(0, 31);
    508#undef COL_MASK
    509
    510    uint32_t efuse_idx = s->regs[R_EFUSE_RD_ADDR];
    511    uint32_t efuse_ary = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, EFUSE);
    512    uint32_t efuse_row = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, ROW);
    513
    514    switch (efuse_ary) {
    515    case 0:     /* Various */
    516        if (efuse_row >= ARRAY_SIZE(ary0_col_mask)) {
    517            goto denied;
    518        }
    519
    520        col_mask = ary0_col_mask[efuse_row];
    521        if (!col_mask) {
    522            goto denied;
    523        }
    524        break;
    525    case 2:     /* PUF helper data, adjust for skipped array 1 */
    526    case 3:
    527        val64 = FIELD_DP32(efuse_idx, EFUSE_RD_ADDR, EFUSE, efuse_ary - 1);
    528        break;
    529    default:
    530        goto denied;
    531    }
    532
    533    s->regs[R_EFUSE_RD_DATA] = xlnx_efuse_get_row(s->efuse, val64) & col_mask;
    534
    535    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 0);
    536    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
    537    zynqmp_efuse_update_irq(s);
    538    return;
    539
    540 denied:
    541    qemu_log_mask(LOG_GUEST_ERROR,
    542                  "%s: Denied efuse read from array %u, row %u\n",
    543                  object_get_canonical_path(OBJECT(s)),
    544                  efuse_ary, efuse_row);
    545
    546    s->regs[R_EFUSE_RD_DATA] = 0;
    547
    548    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
    549    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 0);
    550    zynqmp_efuse_update_irq(s);
    551}
    552
    553static void zynqmp_efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
    554{
    555    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
    556    bool ok;
    557
    558    ok = xlnx_efuse_k256_check(s->efuse, (uint32_t)val64, EFUSE_AES_START);
    559
    560    ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_PASS, (ok ? 1 : 0));
    561    ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_DONE, 1);
    562
    563    s->regs[R_EFUSE_AES_CRC] = 0;   /* crc value is write-only */
    564}
    565
    566static uint64_t zynqmp_efuse_cache_load_prew(RegisterInfo *reg,
    567                                             uint64_t valu64)
    568{
    569    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
    570
    571    if (valu64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
    572        zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
    573        ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
    574        zynqmp_efuse_update_irq(s);
    575    }
    576
    577    return 0;
    578}
    579
    580static uint64_t zynqmp_efuse_wr_lock_prew(RegisterInfo *reg, uint64_t val)
    581{
    582    return val == 0xDF0D ? 0 : 1;
    583}
    584
    585static RegisterAccessInfo zynqmp_efuse_regs_info[] = {
    586    {   .name = "WR_LOCK",  .addr = A_WR_LOCK,
    587        .reset = 0x1,
    588        .pre_write = zynqmp_efuse_wr_lock_prew,
    589    },{ .name = "CFG",  .addr = A_CFG,
    590    },{ .name = "STATUS",  .addr = A_STATUS,
    591        .rsvd = 0x8,
    592        .ro = 0xff,
    593    },{ .name = "EFUSE_PGM_ADDR",  .addr = A_EFUSE_PGM_ADDR,
    594         .post_write = zynqmp_efuse_pgm_addr_postw
    595    },{ .name = "EFUSE_RD_ADDR",  .addr = A_EFUSE_RD_ADDR,
    596        .rsvd = 0x1f,
    597        .post_write = zynqmp_efuse_rd_addr_postw,
    598    },{ .name = "EFUSE_RD_DATA",  .addr = A_EFUSE_RD_DATA,
    599        .ro = 0xffffffff,
    600    },{ .name = "TPGM",  .addr = A_TPGM,
    601    },{ .name = "TRD",  .addr = A_TRD,
    602        .reset = 0x1b,
    603    },{ .name = "TSU_H_PS",  .addr = A_TSU_H_PS,
    604        .reset = 0xff,
    605    },{ .name = "TSU_H_PS_CS",  .addr = A_TSU_H_PS_CS,
    606        .reset = 0xb,
    607    },{ .name = "TSU_H_CS",  .addr = A_TSU_H_CS,
    608        .reset = 0x7,
    609    },{ .name = "EFUSE_ISR",  .addr = A_EFUSE_ISR,
    610        .rsvd = 0x7fffffe0,
    611        .w1c = 0x8000001f,
    612        .post_write = zynqmp_efuse_isr_postw,
    613    },{ .name = "EFUSE_IMR",  .addr = A_EFUSE_IMR,
    614        .reset = 0x8000001f,
    615        .rsvd = 0x7fffffe0,
    616        .ro = 0xffffffff,
    617    },{ .name = "EFUSE_IER",  .addr = A_EFUSE_IER,
    618        .rsvd = 0x7fffffe0,
    619        .pre_write = zynqmp_efuse_ier_prew,
    620    },{ .name = "EFUSE_IDR",  .addr = A_EFUSE_IDR,
    621        .rsvd = 0x7fffffe0,
    622        .pre_write = zynqmp_efuse_idr_prew,
    623    },{ .name = "EFUSE_CACHE_LOAD",  .addr = A_EFUSE_CACHE_LOAD,
    624        .pre_write = zynqmp_efuse_cache_load_prew,
    625    },{ .name = "EFUSE_PGM_LOCK",  .addr = A_EFUSE_PGM_LOCK,
    626    },{ .name = "EFUSE_AES_CRC",  .addr = A_EFUSE_AES_CRC,
    627        .post_write = zynqmp_efuse_aes_crc_postw,
    628    },{ .name = "EFUSE_TBITS_PRGRMG_EN",  .addr = A_EFUSE_TBITS_PRGRMG_EN,
    629        .reset = R_EFUSE_TBITS_PRGRMG_EN_TBITS_PRGRMG_EN_MASK,
    630    },{ .name = "DNA_0",  .addr = A_DNA_0,
    631        .ro = 0xffffffff,
    632    },{ .name = "DNA_1",  .addr = A_DNA_1,
    633        .ro = 0xffffffff,
    634    },{ .name = "DNA_2",  .addr = A_DNA_2,
    635        .ro = 0xffffffff,
    636    },{ .name = "IPDISABLE",  .addr = A_IPDISABLE,
    637        .ro = 0xffffffff,
    638    },{ .name = "SYSOSC_CTRL",  .addr = A_SYSOSC_CTRL,
    639        .ro = 0xffffffff,
    640    },{ .name = "USER_0",  .addr = A_USER_0,
    641        .ro = 0xffffffff,
    642    },{ .name = "USER_1",  .addr = A_USER_1,
    643        .ro = 0xffffffff,
    644    },{ .name = "USER_2",  .addr = A_USER_2,
    645        .ro = 0xffffffff,
    646    },{ .name = "USER_3",  .addr = A_USER_3,
    647        .ro = 0xffffffff,
    648    },{ .name = "USER_4",  .addr = A_USER_4,
    649        .ro = 0xffffffff,
    650    },{ .name = "USER_5",  .addr = A_USER_5,
    651        .ro = 0xffffffff,
    652    },{ .name = "USER_6",  .addr = A_USER_6,
    653        .ro = 0xffffffff,
    654    },{ .name = "USER_7",  .addr = A_USER_7,
    655        .ro = 0xffffffff,
    656    },{ .name = "MISC_USER_CTRL",  .addr = A_MISC_USER_CTRL,
    657        .ro = 0xffffffff,
    658    },{ .name = "ROM_RSVD",  .addr = A_ROM_RSVD,
    659        .ro = 0xffffffff,
    660    },{ .name = "PUF_CHASH", .addr = A_PUF_CHASH,
    661        .ro = 0xffffffff,
    662    },{ .name = "PUF_MISC",  .addr = A_PUF_MISC,
    663        .ro = 0xffffffff,
    664    },{ .name = "SEC_CTRL",  .addr = A_SEC_CTRL,
    665        .ro = 0xffffffff,
    666    },{ .name = "SPK_ID",  .addr = A_SPK_ID,
    667        .ro = 0xffffffff,
    668    },{ .name = "PPK0_0",  .addr = A_PPK0_0,
    669        .ro = 0xffffffff,
    670    },{ .name = "PPK0_1",  .addr = A_PPK0_1,
    671        .ro = 0xffffffff,
    672    },{ .name = "PPK0_2",  .addr = A_PPK0_2,
    673        .ro = 0xffffffff,
    674    },{ .name = "PPK0_3",  .addr = A_PPK0_3,
    675        .ro = 0xffffffff,
    676    },{ .name = "PPK0_4",  .addr = A_PPK0_4,
    677        .ro = 0xffffffff,
    678    },{ .name = "PPK0_5",  .addr = A_PPK0_5,
    679        .ro = 0xffffffff,
    680    },{ .name = "PPK0_6",  .addr = A_PPK0_6,
    681        .ro = 0xffffffff,
    682    },{ .name = "PPK0_7",  .addr = A_PPK0_7,
    683        .ro = 0xffffffff,
    684    },{ .name = "PPK0_8",  .addr = A_PPK0_8,
    685        .ro = 0xffffffff,
    686    },{ .name = "PPK0_9",  .addr = A_PPK0_9,
    687        .ro = 0xffffffff,
    688    },{ .name = "PPK0_10",  .addr = A_PPK0_10,
    689        .ro = 0xffffffff,
    690    },{ .name = "PPK0_11",  .addr = A_PPK0_11,
    691        .ro = 0xffffffff,
    692    },{ .name = "PPK1_0",  .addr = A_PPK1_0,
    693        .ro = 0xffffffff,
    694    },{ .name = "PPK1_1",  .addr = A_PPK1_1,
    695        .ro = 0xffffffff,
    696    },{ .name = "PPK1_2",  .addr = A_PPK1_2,
    697        .ro = 0xffffffff,
    698    },{ .name = "PPK1_3",  .addr = A_PPK1_3,
    699        .ro = 0xffffffff,
    700    },{ .name = "PPK1_4",  .addr = A_PPK1_4,
    701        .ro = 0xffffffff,
    702    },{ .name = "PPK1_5",  .addr = A_PPK1_5,
    703        .ro = 0xffffffff,
    704    },{ .name = "PPK1_6",  .addr = A_PPK1_6,
    705        .ro = 0xffffffff,
    706    },{ .name = "PPK1_7",  .addr = A_PPK1_7,
    707        .ro = 0xffffffff,
    708    },{ .name = "PPK1_8",  .addr = A_PPK1_8,
    709        .ro = 0xffffffff,
    710    },{ .name = "PPK1_9",  .addr = A_PPK1_9,
    711        .ro = 0xffffffff,
    712    },{ .name = "PPK1_10",  .addr = A_PPK1_10,
    713        .ro = 0xffffffff,
    714    },{ .name = "PPK1_11",  .addr = A_PPK1_11,
    715        .ro = 0xffffffff,
    716    }
    717};
    718
    719static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
    720                                   uint64_t data, unsigned size)
    721{
    722    RegisterInfoArray *reg_array = opaque;
    723    XlnxZynqMPEFuse *s;
    724    Object *dev;
    725
    726    assert(reg_array != NULL);
    727
    728    dev = reg_array->mem.owner;
    729    assert(dev);
    730
    731    s = XLNX_ZYNQMP_EFUSE(dev);
    732
    733    if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
    734        qemu_log_mask(LOG_GUEST_ERROR,
    735                      "%s[reg_0x%02lx]: Attempt to write locked register.\n",
    736                      object_get_canonical_path(OBJECT(s)), (long)addr);
    737    } else {
    738        register_write_memory(opaque, addr, data, size);
    739    }
    740}
    741
    742static const MemoryRegionOps zynqmp_efuse_ops = {
    743    .read = register_read_memory,
    744    .write = zynqmp_efuse_reg_write,
    745    .endianness = DEVICE_LITTLE_ENDIAN,
    746    .valid = {
    747        .min_access_size = 4,
    748        .max_access_size = 4,
    749    },
    750};
    751
    752static void zynqmp_efuse_register_reset(RegisterInfo *reg)
    753{
    754    if (!reg->data || !reg->access) {
    755        return;
    756    }
    757
    758    /* Reset must not trigger some registers' writers */
    759    switch (reg->access->addr) {
    760    case A_EFUSE_AES_CRC:
    761        *(uint32_t *)reg->data = reg->access->reset;
    762        return;
    763    }
    764
    765    register_reset(reg);
    766}
    767
    768static void zynqmp_efuse_reset(DeviceState *dev)
    769{
    770    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
    771    unsigned int i;
    772
    773    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
    774        zynqmp_efuse_register_reset(&s->regs_info[i]);
    775    }
    776
    777    zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
    778    ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
    779    zynqmp_efuse_update_irq(s);
    780}
    781
    782static void zynqmp_efuse_realize(DeviceState *dev, Error **errp)
    783{
    784    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
    785
    786    if (!s->efuse) {
    787        error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
    788                   object_get_canonical_path(OBJECT(dev)));
    789        return;
    790    }
    791
    792    s->efuse->dev = dev;
    793}
    794
    795static void zynqmp_efuse_init(Object *obj)
    796{
    797    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
    798    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    799    RegisterInfoArray *reg_array;
    800
    801    reg_array =
    802        register_init_block32(DEVICE(obj), zynqmp_efuse_regs_info,
    803                              ARRAY_SIZE(zynqmp_efuse_regs_info),
    804                              s->regs_info, s->regs,
    805                              &zynqmp_efuse_ops,
    806                              ZYNQMP_EFUSE_ERR_DEBUG,
    807                              R_MAX * 4);
    808
    809    sysbus_init_mmio(sbd, &reg_array->mem);
    810    sysbus_init_irq(sbd, &s->irq);
    811}
    812
    813static const VMStateDescription vmstate_efuse = {
    814    .name = TYPE_XLNX_ZYNQMP_EFUSE,
    815    .version_id = 1,
    816    .minimum_version_id = 1,
    817    .fields = (VMStateField[]) {
    818        VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPEFuse, R_MAX),
    819        VMSTATE_END_OF_LIST(),
    820    }
    821};
    822
    823static Property zynqmp_efuse_props[] = {
    824    DEFINE_PROP_LINK("efuse",
    825                     XlnxZynqMPEFuse, efuse,
    826                     TYPE_XLNX_EFUSE, XlnxEFuse *),
    827
    828    DEFINE_PROP_END_OF_LIST(),
    829};
    830
    831static void zynqmp_efuse_class_init(ObjectClass *klass, void *data)
    832{
    833    DeviceClass *dc = DEVICE_CLASS(klass);
    834
    835    dc->reset = zynqmp_efuse_reset;
    836    dc->realize = zynqmp_efuse_realize;
    837    dc->vmsd = &vmstate_efuse;
    838    device_class_set_props(dc, zynqmp_efuse_props);
    839}
    840
    841
    842static const TypeInfo efuse_info = {
    843    .name          = TYPE_XLNX_ZYNQMP_EFUSE,
    844    .parent        = TYPE_SYS_BUS_DEVICE,
    845    .instance_size = sizeof(XlnxZynqMPEFuse),
    846    .class_init    = zynqmp_efuse_class_init,
    847    .instance_init = zynqmp_efuse_init,
    848};
    849
    850static void efuse_register_types(void)
    851{
    852    type_register_static(&efuse_info);
    853}
    854
    855type_init(efuse_register_types)