qemu

Форк
0
/
xlnx-zynqmp-efuse.c 
863 строки · 27.7 Кб
1
/*
2
 * QEMU model of the ZynqMP eFuse
3
 *
4
 * Copyright (c) 2015 Xilinx Inc.
5
 * Copyright (c) 2023 Advanced Micro Devices, Inc.
6
 *
7
 * Written by Edgar E. Iglesias <edgari@xilinx.com>
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in
17
 * all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
 * THE SOFTWARE.
26
 */
27

28
#include "qemu/osdep.h"
29
#include "hw/nvram/xlnx-zynqmp-efuse.h"
30

31
#include "qemu/log.h"
32
#include "qapi/error.h"
33
#include "migration/vmstate.h"
34
#include "hw/qdev-properties.h"
35

36
#ifndef ZYNQMP_EFUSE_ERR_DEBUG
37
#define ZYNQMP_EFUSE_ERR_DEBUG 0
38
#endif
39

40
REG32(WR_LOCK, 0x0)
41
    FIELD(WR_LOCK, LOCK, 0, 16)
42
REG32(CFG, 0x4)
43
    FIELD(CFG, SLVERR_ENABLE, 5, 1)
44
    FIELD(CFG, MARGIN_RD, 2, 2)
45
    FIELD(CFG, PGM_EN, 1, 1)
46
    FIELD(CFG, EFUSE_CLK_SEL, 0, 1)
47
REG32(STATUS, 0x8)
48
    FIELD(STATUS, AES_CRC_PASS, 7, 1)
49
    FIELD(STATUS, AES_CRC_DONE, 6, 1)
50
    FIELD(STATUS, CACHE_DONE, 5, 1)
51
    FIELD(STATUS, CACHE_LOAD, 4, 1)
52
    FIELD(STATUS, EFUSE_3_TBIT, 2, 1)
53
    FIELD(STATUS, EFUSE_2_TBIT, 1, 1)
54
    FIELD(STATUS, EFUSE_0_TBIT, 0, 1)
55
REG32(EFUSE_PGM_ADDR, 0xc)
56
    FIELD(EFUSE_PGM_ADDR, EFUSE, 11, 2)
57
    FIELD(EFUSE_PGM_ADDR, ROW, 5, 6)
58
    FIELD(EFUSE_PGM_ADDR, COLUMN, 0, 5)
59
REG32(EFUSE_RD_ADDR, 0x10)
60
    FIELD(EFUSE_RD_ADDR, EFUSE, 11, 2)
61
    FIELD(EFUSE_RD_ADDR, ROW, 5, 6)
62
REG32(EFUSE_RD_DATA, 0x14)
63
REG32(TPGM, 0x18)
64
    FIELD(TPGM, VALUE, 0, 16)
65
REG32(TRD, 0x1c)
66
    FIELD(TRD, VALUE, 0, 8)
67
REG32(TSU_H_PS, 0x20)
68
    FIELD(TSU_H_PS, VALUE, 0, 8)
69
REG32(TSU_H_PS_CS, 0x24)
70
    FIELD(TSU_H_PS_CS, VALUE, 0, 8)
71
REG32(TSU_H_CS, 0x2c)
72
    FIELD(TSU_H_CS, VALUE, 0, 4)
73
REG32(EFUSE_ISR, 0x30)
74
    FIELD(EFUSE_ISR, APB_SLVERR, 31, 1)
75
    FIELD(EFUSE_ISR, CACHE_ERROR, 4, 1)
76
    FIELD(EFUSE_ISR, RD_ERROR, 3, 1)
77
    FIELD(EFUSE_ISR, RD_DONE, 2, 1)
78
    FIELD(EFUSE_ISR, PGM_ERROR, 1, 1)
79
    FIELD(EFUSE_ISR, PGM_DONE, 0, 1)
80
REG32(EFUSE_IMR, 0x34)
81
    FIELD(EFUSE_IMR, APB_SLVERR, 31, 1)
82
    FIELD(EFUSE_IMR, CACHE_ERROR, 4, 1)
83
    FIELD(EFUSE_IMR, RD_ERROR, 3, 1)
84
    FIELD(EFUSE_IMR, RD_DONE, 2, 1)
85
    FIELD(EFUSE_IMR, PGM_ERROR, 1, 1)
86
    FIELD(EFUSE_IMR, PGM_DONE, 0, 1)
87
REG32(EFUSE_IER, 0x38)
88
    FIELD(EFUSE_IER, APB_SLVERR, 31, 1)
89
    FIELD(EFUSE_IER, CACHE_ERROR, 4, 1)
90
    FIELD(EFUSE_IER, RD_ERROR, 3, 1)
91
    FIELD(EFUSE_IER, RD_DONE, 2, 1)
92
    FIELD(EFUSE_IER, PGM_ERROR, 1, 1)
93
    FIELD(EFUSE_IER, PGM_DONE, 0, 1)
94
REG32(EFUSE_IDR, 0x3c)
95
    FIELD(EFUSE_IDR, APB_SLVERR, 31, 1)
96
    FIELD(EFUSE_IDR, CACHE_ERROR, 4, 1)
97
    FIELD(EFUSE_IDR, RD_ERROR, 3, 1)
98
    FIELD(EFUSE_IDR, RD_DONE, 2, 1)
99
    FIELD(EFUSE_IDR, PGM_ERROR, 1, 1)
100
    FIELD(EFUSE_IDR, PGM_DONE, 0, 1)
101
REG32(EFUSE_CACHE_LOAD, 0x40)
102
    FIELD(EFUSE_CACHE_LOAD, LOAD, 0, 1)
103
REG32(EFUSE_PGM_LOCK, 0x44)
104
    FIELD(EFUSE_PGM_LOCK, SPK_ID_LOCK, 0, 1)
105
REG32(EFUSE_AES_CRC, 0x48)
106
REG32(EFUSE_TBITS_PRGRMG_EN, 0x100)
107
    FIELD(EFUSE_TBITS_PRGRMG_EN, TBITS_PRGRMG_EN, 3, 1)
108
REG32(DNA_0, 0x100c)
109
REG32(DNA_1, 0x1010)
110
REG32(DNA_2, 0x1014)
111
REG32(IPDISABLE, 0x1018)
112
    FIELD(IPDISABLE, VCU_DIS, 8, 1)
113
    FIELD(IPDISABLE, GPU_DIS, 5, 1)
114
    FIELD(IPDISABLE, APU3_DIS, 3, 1)
115
    FIELD(IPDISABLE, APU2_DIS, 2, 1)
116
    FIELD(IPDISABLE, APU1_DIS, 1, 1)
117
    FIELD(IPDISABLE, APU0_DIS, 0, 1)
118
REG32(SYSOSC_CTRL, 0x101c)
119
    FIELD(SYSOSC_CTRL, SYSOSC_EN, 0, 1)
120
REG32(USER_0, 0x1020)
121
REG32(USER_1, 0x1024)
122
REG32(USER_2, 0x1028)
123
REG32(USER_3, 0x102c)
124
REG32(USER_4, 0x1030)
125
REG32(USER_5, 0x1034)
126
REG32(USER_6, 0x1038)
127
REG32(USER_7, 0x103c)
128
REG32(MISC_USER_CTRL, 0x1040)
129
    FIELD(MISC_USER_CTRL, FPD_SC_EN_0, 14, 1)
130
    FIELD(MISC_USER_CTRL, LPD_SC_EN_0, 11, 1)
131
    FIELD(MISC_USER_CTRL, LBIST_EN, 10, 1)
132
    FIELD(MISC_USER_CTRL, USR_WRLK_7, 7, 1)
133
    FIELD(MISC_USER_CTRL, USR_WRLK_6, 6, 1)
134
    FIELD(MISC_USER_CTRL, USR_WRLK_5, 5, 1)
135
    FIELD(MISC_USER_CTRL, USR_WRLK_4, 4, 1)
136
    FIELD(MISC_USER_CTRL, USR_WRLK_3, 3, 1)
137
    FIELD(MISC_USER_CTRL, USR_WRLK_2, 2, 1)
138
    FIELD(MISC_USER_CTRL, USR_WRLK_1, 1, 1)
139
    FIELD(MISC_USER_CTRL, USR_WRLK_0, 0, 1)
140
REG32(ROM_RSVD, 0x1044)
141
    FIELD(ROM_RSVD, PBR_BOOT_ERROR, 0, 3)
142
REG32(PUF_CHASH, 0x1050)
143
REG32(PUF_MISC, 0x1054)
144
    FIELD(PUF_MISC, REGISTER_DIS, 31, 1)
145
    FIELD(PUF_MISC, SYN_WRLK, 30, 1)
146
    FIELD(PUF_MISC, SYN_INVLD, 29, 1)
147
    FIELD(PUF_MISC, TEST2_DIS, 28, 1)
148
    FIELD(PUF_MISC, UNUSED27, 27, 1)
149
    FIELD(PUF_MISC, UNUSED26, 26, 1)
150
    FIELD(PUF_MISC, UNUSED25, 25, 1)
151
    FIELD(PUF_MISC, UNUSED24, 24, 1)
152
    FIELD(PUF_MISC, AUX, 0, 24)
153
REG32(SEC_CTRL, 0x1058)
154
    FIELD(SEC_CTRL, PPK1_INVLD, 30, 2)
155
    FIELD(SEC_CTRL, PPK1_WRLK, 29, 1)
156
    FIELD(SEC_CTRL, PPK0_INVLD, 27, 2)
157
    FIELD(SEC_CTRL, PPK0_WRLK, 26, 1)
158
    FIELD(SEC_CTRL, RSA_EN, 11, 15)
159
    FIELD(SEC_CTRL, SEC_LOCK, 10, 1)
160
    FIELD(SEC_CTRL, PROG_GATE_2, 9, 1)
161
    FIELD(SEC_CTRL, PROG_GATE_1, 8, 1)
162
    FIELD(SEC_CTRL, PROG_GATE_0, 7, 1)
163
    FIELD(SEC_CTRL, DFT_DIS, 6, 1)
164
    FIELD(SEC_CTRL, JTAG_DIS, 5, 1)
165
    FIELD(SEC_CTRL, ERROR_DIS, 4, 1)
166
    FIELD(SEC_CTRL, BBRAM_DIS, 3, 1)
167
    FIELD(SEC_CTRL, ENC_ONLY, 2, 1)
168
    FIELD(SEC_CTRL, AES_WRLK, 1, 1)
169
    FIELD(SEC_CTRL, AES_RDLK, 0, 1)
170
REG32(SPK_ID, 0x105c)
171
REG32(PPK0_0, 0x10a0)
172
REG32(PPK0_1, 0x10a4)
173
REG32(PPK0_2, 0x10a8)
174
REG32(PPK0_3, 0x10ac)
175
REG32(PPK0_4, 0x10b0)
176
REG32(PPK0_5, 0x10b4)
177
REG32(PPK0_6, 0x10b8)
178
REG32(PPK0_7, 0x10bc)
179
REG32(PPK0_8, 0x10c0)
180
REG32(PPK0_9, 0x10c4)
181
REG32(PPK0_10, 0x10c8)
182
REG32(PPK0_11, 0x10cc)
183
REG32(PPK1_0, 0x10d0)
184
REG32(PPK1_1, 0x10d4)
185
REG32(PPK1_2, 0x10d8)
186
REG32(PPK1_3, 0x10dc)
187
REG32(PPK1_4, 0x10e0)
188
REG32(PPK1_5, 0x10e4)
189
REG32(PPK1_6, 0x10e8)
190
REG32(PPK1_7, 0x10ec)
191
REG32(PPK1_8, 0x10f0)
192
REG32(PPK1_9, 0x10f4)
193
REG32(PPK1_10, 0x10f8)
194
REG32(PPK1_11, 0x10fc)
195

196
#define BIT_POS(ROW, COLUMN)    (ROW * 32 + COLUMN)
197
#define R_MAX (R_PPK1_11 + 1)
198

199
/* #define EFUSE_XOSC            26 */
200

201
/*
202
 * eFUSE layout references:
203
 *   ZynqMP: UG1085 (v2.1) August 21, 2019, p.277, Table 12-13
204
 */
205
#define EFUSE_AES_RDLK        BIT_POS(22, 0)
206
#define EFUSE_AES_WRLK        BIT_POS(22, 1)
207
#define EFUSE_ENC_ONLY        BIT_POS(22, 2)
208
#define EFUSE_BBRAM_DIS       BIT_POS(22, 3)
209
#define EFUSE_ERROR_DIS       BIT_POS(22, 4)
210
#define EFUSE_JTAG_DIS        BIT_POS(22, 5)
211
#define EFUSE_DFT_DIS         BIT_POS(22, 6)
212
#define EFUSE_PROG_GATE_0     BIT_POS(22, 7)
213
#define EFUSE_PROG_GATE_1     BIT_POS(22, 7)
214
#define EFUSE_PROG_GATE_2     BIT_POS(22, 9)
215
#define EFUSE_SEC_LOCK        BIT_POS(22, 10)
216
#define EFUSE_RSA_EN          BIT_POS(22, 11)
217
#define EFUSE_RSA_EN14        BIT_POS(22, 25)
218
#define EFUSE_PPK0_WRLK       BIT_POS(22, 26)
219
#define EFUSE_PPK0_INVLD      BIT_POS(22, 27)
220
#define EFUSE_PPK0_INVLD_1    BIT_POS(22, 28)
221
#define EFUSE_PPK1_WRLK       BIT_POS(22, 29)
222
#define EFUSE_PPK1_INVLD      BIT_POS(22, 30)
223
#define EFUSE_PPK1_INVLD_1    BIT_POS(22, 31)
224

225
/* Areas.  */
226
#define EFUSE_TRIM_START      BIT_POS(1, 0)
227
#define EFUSE_TRIM_END        BIT_POS(1, 30)
228
#define EFUSE_DNA_START       BIT_POS(3, 0)
229
#define EFUSE_DNA_END         BIT_POS(5, 31)
230
#define EFUSE_AES_START       BIT_POS(24, 0)
231
#define EFUSE_AES_END         BIT_POS(31, 31)
232
#define EFUSE_ROM_START       BIT_POS(17, 0)
233
#define EFUSE_ROM_END         BIT_POS(17, 31)
234
#define EFUSE_IPDIS_START     BIT_POS(6, 0)
235
#define EFUSE_IPDIS_END       BIT_POS(6, 31)
236
#define EFUSE_USER_START      BIT_POS(8, 0)
237
#define EFUSE_USER_END        BIT_POS(15, 31)
238
#define EFUSE_BISR_START      BIT_POS(32, 0)
239
#define EFUSE_BISR_END        BIT_POS(39, 31)
240

241
#define EFUSE_USER_CTRL_START BIT_POS(16, 0)
242
#define EFUSE_USER_CTRL_END   BIT_POS(16, 16)
243
#define EFUSE_USER_CTRL_MASK  ((uint32_t)MAKE_64BIT_MASK(0, 17))
244

245
#define EFUSE_PUF_CHASH_START BIT_POS(20, 0)
246
#define EFUSE_PUF_CHASH_END   BIT_POS(20, 31)
247
#define EFUSE_PUF_MISC_START  BIT_POS(21, 0)
248
#define EFUSE_PUF_MISC_END    BIT_POS(21, 31)
249
#define EFUSE_PUF_SYN_WRLK    BIT_POS(21, 30)
250

251
#define EFUSE_SPK_START       BIT_POS(23, 0)
252
#define EFUSE_SPK_END         BIT_POS(23, 31)
253

254
#define EFUSE_PPK0_START      BIT_POS(40, 0)
255
#define EFUSE_PPK0_END        BIT_POS(51, 31)
256
#define EFUSE_PPK1_START      BIT_POS(52, 0)
257
#define EFUSE_PPK1_END        BIT_POS(63, 31)
258

259
#define EFUSE_CACHE_FLD(s, reg, field) \
260
    ARRAY_FIELD_DP32((s)->regs, reg, field, \
261
                     (xlnx_efuse_get_row((s->efuse), EFUSE_ ## field) \
262
                      >> (EFUSE_ ## field % 32)))
263

264
#define EFUSE_CACHE_BIT(s, reg, field) \
265
    ARRAY_FIELD_DP32((s)->regs, reg, field, xlnx_efuse_get_bit((s->efuse), \
266
                EFUSE_ ## field))
267

268
#define FBIT_UNKNOWN (~0)
269

270
QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxZynqMPEFuse *)0)->regs));
271

272
static void update_tbit_status(XlnxZynqMPEFuse *s)
273
{
274
    unsigned int check = xlnx_efuse_tbits_check(s->efuse);
275
    uint32_t val = s->regs[R_STATUS];
276

277
    val = FIELD_DP32(val, STATUS, EFUSE_0_TBIT, !!(check & (1 << 0)));
278
    val = FIELD_DP32(val, STATUS, EFUSE_2_TBIT, !!(check & (1 << 1)));
279
    val = FIELD_DP32(val, STATUS, EFUSE_3_TBIT, !!(check & (1 << 2)));
280

281
    s->regs[R_STATUS] = val;
282
}
283

284
/* Update the u32 array from efuse bits. Slow but simple approach.  */
285
static void cache_sync_u32(XlnxZynqMPEFuse *s, unsigned int r_start,
286
                           unsigned int f_start, unsigned int f_end,
287
                           unsigned int f_written)
288
{
289
    uint32_t *u32 = &s->regs[r_start];
290
    unsigned int fbit, wbits = 0, u32_off = 0;
291

292
    /* Avoid working on bits that are not relevant.  */
293
    if (f_written != FBIT_UNKNOWN
294
        && (f_written < f_start || f_written > f_end)) {
295
        return;
296
    }
297

298
    for (fbit = f_start; fbit <= f_end; fbit++, wbits++) {
299
        if (wbits == 32) {
300
            /* Update the key offset.  */
301
            u32_off += 1;
302
            wbits = 0;
303
        }
304
        u32[u32_off] |= xlnx_efuse_get_bit(s->efuse, fbit) << wbits;
305
    }
306
}
307

308
/*
309
 * Keep the syncs in bit order so we can bail out for the
310
 * slower ones.
311
 */
312
static void zynqmp_efuse_sync_cache(XlnxZynqMPEFuse *s, unsigned int bit)
313
{
314
    EFUSE_CACHE_BIT(s, SEC_CTRL, AES_RDLK);
315
    EFUSE_CACHE_BIT(s, SEC_CTRL, AES_WRLK);
316
    EFUSE_CACHE_BIT(s, SEC_CTRL, ENC_ONLY);
317
    EFUSE_CACHE_BIT(s, SEC_CTRL, BBRAM_DIS);
318
    EFUSE_CACHE_BIT(s, SEC_CTRL, ERROR_DIS);
319
    EFUSE_CACHE_BIT(s, SEC_CTRL, JTAG_DIS);
320
    EFUSE_CACHE_BIT(s, SEC_CTRL, DFT_DIS);
321
    EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_0);
322
    EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_1);
323
    EFUSE_CACHE_BIT(s, SEC_CTRL, PROG_GATE_2);
324
    EFUSE_CACHE_BIT(s, SEC_CTRL, SEC_LOCK);
325
    EFUSE_CACHE_BIT(s, SEC_CTRL, PPK0_WRLK);
326
    EFUSE_CACHE_BIT(s, SEC_CTRL, PPK1_WRLK);
327

328
    EFUSE_CACHE_FLD(s, SEC_CTRL, RSA_EN);
329
    EFUSE_CACHE_FLD(s, SEC_CTRL, PPK0_INVLD);
330
    EFUSE_CACHE_FLD(s, SEC_CTRL, PPK1_INVLD);
331

332
    /* Update the tbits.  */
333
    update_tbit_status(s);
334

335
    /* Sync the various areas.  */
336
    s->regs[R_MISC_USER_CTRL] = xlnx_efuse_get_row(s->efuse,
337
                                                   EFUSE_USER_CTRL_START)
338
                                & EFUSE_USER_CTRL_MASK;
339
    s->regs[R_PUF_CHASH] = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_CHASH_START);
340
    s->regs[R_PUF_MISC]  = xlnx_efuse_get_row(s->efuse, EFUSE_PUF_MISC_START);
341

342
    cache_sync_u32(s, R_DNA_0, EFUSE_DNA_START, EFUSE_DNA_END, bit);
343

344
    if (bit < EFUSE_AES_START) {
345
        return;
346
    }
347

348
    cache_sync_u32(s, R_ROM_RSVD, EFUSE_ROM_START, EFUSE_ROM_END, bit);
349
    cache_sync_u32(s, R_IPDISABLE, EFUSE_IPDIS_START, EFUSE_IPDIS_END, bit);
350
    cache_sync_u32(s, R_USER_0, EFUSE_USER_START, EFUSE_USER_END, bit);
351
    cache_sync_u32(s, R_SPK_ID, EFUSE_SPK_START, EFUSE_SPK_END, bit);
352
    cache_sync_u32(s, R_PPK0_0, EFUSE_PPK0_START, EFUSE_PPK0_END, bit);
353
    cache_sync_u32(s, R_PPK1_0, EFUSE_PPK1_START, EFUSE_PPK1_END, bit);
354
}
355

356
static void zynqmp_efuse_update_irq(XlnxZynqMPEFuse *s)
357
{
358
    bool pending = s->regs[R_EFUSE_ISR] & s->regs[R_EFUSE_IMR];
359
    qemu_set_irq(s->irq, pending);
360
}
361

362
static void zynqmp_efuse_isr_postw(RegisterInfo *reg, uint64_t val64)
363
{
364
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
365
    zynqmp_efuse_update_irq(s);
366
}
367

368
static uint64_t zynqmp_efuse_ier_prew(RegisterInfo *reg, uint64_t val64)
369
{
370
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
371
    uint32_t val = val64;
372

373
    s->regs[R_EFUSE_IMR] |= val;
374
    zynqmp_efuse_update_irq(s);
375
    return 0;
376
}
377

378
static uint64_t zynqmp_efuse_idr_prew(RegisterInfo *reg, uint64_t val64)
379
{
380
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
381
    uint32_t val = val64;
382

383
    s->regs[R_EFUSE_IMR] &= ~val;
384
    zynqmp_efuse_update_irq(s);
385
    return 0;
386
}
387

388
static void zynqmp_efuse_pgm_addr_postw(RegisterInfo *reg, uint64_t val64)
389
{
390
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
391
    unsigned bit = val64;
392
    unsigned page = FIELD_EX32(bit, EFUSE_PGM_ADDR, EFUSE);
393
    bool puf_prot = false;
394
    const char *errmsg = NULL;
395

396
    /* Allow only valid array, and adjust for skipped array 1 */
397
    switch (page) {
398
    case 0:
399
        break;
400
    case 2 ... 3:
401
        bit = FIELD_DP32(bit, EFUSE_PGM_ADDR, EFUSE, page - 1);
402
        puf_prot = xlnx_efuse_get_bit(s->efuse, EFUSE_PUF_SYN_WRLK);
403
        break;
404
    default:
405
        errmsg = "Invalid address";
406
        goto pgm_done;
407
    }
408

409
    if (ARRAY_FIELD_EX32(s->regs, WR_LOCK, LOCK)) {
410
        errmsg = "Array write-locked";
411
        goto pgm_done;
412
    }
413

414
    if (!ARRAY_FIELD_EX32(s->regs, CFG, PGM_EN)) {
415
        errmsg = "Array pgm-disabled";
416
        goto pgm_done;
417
    }
418

419
    if (puf_prot) {
420
        errmsg = "PUF_HD-store write-locked";
421
        goto pgm_done;
422
    }
423

424
    if (ARRAY_FIELD_EX32(s->regs, SEC_CTRL, AES_WRLK)
425
        && bit >= EFUSE_AES_START && bit <= EFUSE_AES_END) {
426
        errmsg = "AES key-store Write-locked";
427
        goto pgm_done;
428
    }
429

430
    if (!xlnx_efuse_set_bit(s->efuse, bit)) {
431
        errmsg = "Write failed";
432
    }
433

434
 pgm_done:
435
    if (!errmsg) {
436
        ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 0);
437
    } else {
438
        g_autofree char *path = object_get_canonical_path(OBJECT(s));
439

440
        ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_ERROR, 1);
441
        qemu_log_mask(LOG_GUEST_ERROR,
442
                      "%s - eFuse write error: %s; addr=0x%x\n",
443
                      path, errmsg, (unsigned)val64);
444
    }
445

446
    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, PGM_DONE, 1);
447
    zynqmp_efuse_update_irq(s);
448
}
449

450
static void zynqmp_efuse_rd_addr_postw(RegisterInfo *reg, uint64_t val64)
451
{
452
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
453
    g_autofree char *path = NULL;
454

455
    /*
456
     * Grant reads only to allowed bits; reference sources:
457
     * 1/ XilSKey - XilSKey_ZynqMp_EfusePs_ReadRow()
458
     * 2/ UG1085, v2.0, table 12-13
459
     * (note: enumerates the masks as <first, last> per described in
460
     *  references to avoid mental translation).
461
     */
462
#define COL_MASK(L_, H_) \
463
    ((uint32_t)MAKE_64BIT_MASK((L_), (1 + (H_) - (L_))))
464

465
    static const uint32_t ary0_col_mask[] = {
466
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_TBITS_ROW */
467
        [0]  = COL_MASK(28, 31),
468

469
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_USR{0:7}_FUSE_ROW */
470
        [8]  = COL_MASK(0, 31), [9]  = COL_MASK(0, 31),
471
        [10] = COL_MASK(0, 31), [11] = COL_MASK(0, 31),
472
        [12] = COL_MASK(0, 31), [13] = COL_MASK(0, 31),
473
        [14] = COL_MASK(0, 31), [15] = COL_MASK(0, 31),
474

475
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_MISC_USR_CTRL_ROW */
476
        [16] = COL_MASK(0, 7) | COL_MASK(10, 16),
477

478
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PBR_BOOT_ERR_ROW */
479
        [17] = COL_MASK(0, 2),
480

481
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_CHASH_ROW */
482
        [20] = COL_MASK(0, 31),
483

484
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PUF_AUX_ROW */
485
        [21] = COL_MASK(0, 23) | COL_MASK(29, 31),
486

487
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_SEC_CTRL_ROW */
488
        [22] = COL_MASK(0, 31),
489

490
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_SPK_ID_ROW */
491
        [23] = COL_MASK(0, 31),
492

493
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK0_START_ROW */
494
        [40] = COL_MASK(0, 31), [41] = COL_MASK(0, 31),
495
        [42] = COL_MASK(0, 31), [43] = COL_MASK(0, 31),
496
        [44] = COL_MASK(0, 31), [45] = COL_MASK(0, 31),
497
        [46] = COL_MASK(0, 31), [47] = COL_MASK(0, 31),
498
        [48] = COL_MASK(0, 31), [49] = COL_MASK(0, 31),
499
        [50] = COL_MASK(0, 31), [51] = COL_MASK(0, 31),
500

501
        /* XilSKey - XSK_ZYNQMP_EFUSEPS_PPK1_START_ROW */
502
        [52] = COL_MASK(0, 31), [53] = COL_MASK(0, 31),
503
        [54] = COL_MASK(0, 31), [55] = COL_MASK(0, 31),
504
        [56] = COL_MASK(0, 31), [57] = COL_MASK(0, 31),
505
        [58] = COL_MASK(0, 31), [59] = COL_MASK(0, 31),
506
        [60] = COL_MASK(0, 31), [61] = COL_MASK(0, 31),
507
        [62] = COL_MASK(0, 31), [63] = COL_MASK(0, 31),
508
    };
509

510
    uint32_t col_mask = COL_MASK(0, 31);
511
#undef COL_MASK
512

513
    uint32_t efuse_idx = s->regs[R_EFUSE_RD_ADDR];
514
    uint32_t efuse_ary = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, EFUSE);
515
    uint32_t efuse_row = FIELD_EX32(efuse_idx, EFUSE_RD_ADDR, ROW);
516

517
    switch (efuse_ary) {
518
    case 0:     /* Various */
519
        if (efuse_row >= ARRAY_SIZE(ary0_col_mask)) {
520
            goto denied;
521
        }
522

523
        col_mask = ary0_col_mask[efuse_row];
524
        if (!col_mask) {
525
            goto denied;
526
        }
527
        break;
528
    case 2:     /* PUF helper data, adjust for skipped array 1 */
529
    case 3:
530
        val64 = FIELD_DP32(efuse_idx, EFUSE_RD_ADDR, EFUSE, efuse_ary - 1);
531
        break;
532
    default:
533
        goto denied;
534
    }
535

536
    s->regs[R_EFUSE_RD_DATA] = xlnx_efuse_get_row(s->efuse, val64) & col_mask;
537

538
    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 0);
539
    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 1);
540
    zynqmp_efuse_update_irq(s);
541
    return;
542

543
 denied:
544
    path = object_get_canonical_path(OBJECT(s));
545
    qemu_log_mask(LOG_GUEST_ERROR,
546
                  "%s: Denied efuse read from array %u, row %u\n",
547
                  path, efuse_ary, efuse_row);
548

549
    s->regs[R_EFUSE_RD_DATA] = 0;
550

551
    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_ERROR, 1);
552
    ARRAY_FIELD_DP32(s->regs, EFUSE_ISR, RD_DONE, 0);
553
    zynqmp_efuse_update_irq(s);
554
}
555

556
static void zynqmp_efuse_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
557
{
558
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
559
    bool ok;
560

561
    ok = xlnx_efuse_k256_check(s->efuse, (uint32_t)val64, EFUSE_AES_START);
562

563
    ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_PASS, (ok ? 1 : 0));
564
    ARRAY_FIELD_DP32(s->regs, STATUS, AES_CRC_DONE, 1);
565

566
    s->regs[R_EFUSE_AES_CRC] = 0;   /* crc value is write-only */
567
}
568

569
static uint64_t zynqmp_efuse_cache_load_prew(RegisterInfo *reg,
570
                                             uint64_t valu64)
571
{
572
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(reg->opaque);
573

574
    if (valu64 & R_EFUSE_CACHE_LOAD_LOAD_MASK) {
575
        zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
576
        ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
577
        zynqmp_efuse_update_irq(s);
578
    }
579

580
    return 0;
581
}
582

583
static uint64_t zynqmp_efuse_wr_lock_prew(RegisterInfo *reg, uint64_t val)
584
{
585
    return val == 0xDF0D ? 0 : 1;
586
}
587

588
static RegisterAccessInfo zynqmp_efuse_regs_info[] = {
589
    {   .name = "WR_LOCK",  .addr = A_WR_LOCK,
590
        .reset = 0x1,
591
        .pre_write = zynqmp_efuse_wr_lock_prew,
592
    },{ .name = "CFG",  .addr = A_CFG,
593
    },{ .name = "STATUS",  .addr = A_STATUS,
594
        .rsvd = 0x8,
595
        .ro = 0xff,
596
    },{ .name = "EFUSE_PGM_ADDR",  .addr = A_EFUSE_PGM_ADDR,
597
         .post_write = zynqmp_efuse_pgm_addr_postw
598
    },{ .name = "EFUSE_RD_ADDR",  .addr = A_EFUSE_RD_ADDR,
599
        .rsvd = 0x1f,
600
        .post_write = zynqmp_efuse_rd_addr_postw,
601
    },{ .name = "EFUSE_RD_DATA",  .addr = A_EFUSE_RD_DATA,
602
        .ro = 0xffffffff,
603
    },{ .name = "TPGM",  .addr = A_TPGM,
604
    },{ .name = "TRD",  .addr = A_TRD,
605
        .reset = 0x1b,
606
    },{ .name = "TSU_H_PS",  .addr = A_TSU_H_PS,
607
        .reset = 0xff,
608
    },{ .name = "TSU_H_PS_CS",  .addr = A_TSU_H_PS_CS,
609
        .reset = 0xb,
610
    },{ .name = "TSU_H_CS",  .addr = A_TSU_H_CS,
611
        .reset = 0x7,
612
    },{ .name = "EFUSE_ISR",  .addr = A_EFUSE_ISR,
613
        .rsvd = 0x7fffffe0,
614
        .w1c = 0x8000001f,
615
        .post_write = zynqmp_efuse_isr_postw,
616
    },{ .name = "EFUSE_IMR",  .addr = A_EFUSE_IMR,
617
        .reset = 0x8000001f,
618
        .rsvd = 0x7fffffe0,
619
        .ro = 0xffffffff,
620
    },{ .name = "EFUSE_IER",  .addr = A_EFUSE_IER,
621
        .rsvd = 0x7fffffe0,
622
        .pre_write = zynqmp_efuse_ier_prew,
623
    },{ .name = "EFUSE_IDR",  .addr = A_EFUSE_IDR,
624
        .rsvd = 0x7fffffe0,
625
        .pre_write = zynqmp_efuse_idr_prew,
626
    },{ .name = "EFUSE_CACHE_LOAD",  .addr = A_EFUSE_CACHE_LOAD,
627
        .pre_write = zynqmp_efuse_cache_load_prew,
628
    },{ .name = "EFUSE_PGM_LOCK",  .addr = A_EFUSE_PGM_LOCK,
629
    },{ .name = "EFUSE_AES_CRC",  .addr = A_EFUSE_AES_CRC,
630
        .post_write = zynqmp_efuse_aes_crc_postw,
631
    },{ .name = "EFUSE_TBITS_PRGRMG_EN",  .addr = A_EFUSE_TBITS_PRGRMG_EN,
632
        .reset = R_EFUSE_TBITS_PRGRMG_EN_TBITS_PRGRMG_EN_MASK,
633
    },{ .name = "DNA_0",  .addr = A_DNA_0,
634
        .ro = 0xffffffff,
635
    },{ .name = "DNA_1",  .addr = A_DNA_1,
636
        .ro = 0xffffffff,
637
    },{ .name = "DNA_2",  .addr = A_DNA_2,
638
        .ro = 0xffffffff,
639
    },{ .name = "IPDISABLE",  .addr = A_IPDISABLE,
640
        .ro = 0xffffffff,
641
    },{ .name = "SYSOSC_CTRL",  .addr = A_SYSOSC_CTRL,
642
        .ro = 0xffffffff,
643
    },{ .name = "USER_0",  .addr = A_USER_0,
644
        .ro = 0xffffffff,
645
    },{ .name = "USER_1",  .addr = A_USER_1,
646
        .ro = 0xffffffff,
647
    },{ .name = "USER_2",  .addr = A_USER_2,
648
        .ro = 0xffffffff,
649
    },{ .name = "USER_3",  .addr = A_USER_3,
650
        .ro = 0xffffffff,
651
    },{ .name = "USER_4",  .addr = A_USER_4,
652
        .ro = 0xffffffff,
653
    },{ .name = "USER_5",  .addr = A_USER_5,
654
        .ro = 0xffffffff,
655
    },{ .name = "USER_6",  .addr = A_USER_6,
656
        .ro = 0xffffffff,
657
    },{ .name = "USER_7",  .addr = A_USER_7,
658
        .ro = 0xffffffff,
659
    },{ .name = "MISC_USER_CTRL",  .addr = A_MISC_USER_CTRL,
660
        .ro = 0xffffffff,
661
    },{ .name = "ROM_RSVD",  .addr = A_ROM_RSVD,
662
        .ro = 0xffffffff,
663
    },{ .name = "PUF_CHASH", .addr = A_PUF_CHASH,
664
        .ro = 0xffffffff,
665
    },{ .name = "PUF_MISC",  .addr = A_PUF_MISC,
666
        .ro = 0xffffffff,
667
    },{ .name = "SEC_CTRL",  .addr = A_SEC_CTRL,
668
        .ro = 0xffffffff,
669
    },{ .name = "SPK_ID",  .addr = A_SPK_ID,
670
        .ro = 0xffffffff,
671
    },{ .name = "PPK0_0",  .addr = A_PPK0_0,
672
        .ro = 0xffffffff,
673
    },{ .name = "PPK0_1",  .addr = A_PPK0_1,
674
        .ro = 0xffffffff,
675
    },{ .name = "PPK0_2",  .addr = A_PPK0_2,
676
        .ro = 0xffffffff,
677
    },{ .name = "PPK0_3",  .addr = A_PPK0_3,
678
        .ro = 0xffffffff,
679
    },{ .name = "PPK0_4",  .addr = A_PPK0_4,
680
        .ro = 0xffffffff,
681
    },{ .name = "PPK0_5",  .addr = A_PPK0_5,
682
        .ro = 0xffffffff,
683
    },{ .name = "PPK0_6",  .addr = A_PPK0_6,
684
        .ro = 0xffffffff,
685
    },{ .name = "PPK0_7",  .addr = A_PPK0_7,
686
        .ro = 0xffffffff,
687
    },{ .name = "PPK0_8",  .addr = A_PPK0_8,
688
        .ro = 0xffffffff,
689
    },{ .name = "PPK0_9",  .addr = A_PPK0_9,
690
        .ro = 0xffffffff,
691
    },{ .name = "PPK0_10",  .addr = A_PPK0_10,
692
        .ro = 0xffffffff,
693
    },{ .name = "PPK0_11",  .addr = A_PPK0_11,
694
        .ro = 0xffffffff,
695
    },{ .name = "PPK1_0",  .addr = A_PPK1_0,
696
        .ro = 0xffffffff,
697
    },{ .name = "PPK1_1",  .addr = A_PPK1_1,
698
        .ro = 0xffffffff,
699
    },{ .name = "PPK1_2",  .addr = A_PPK1_2,
700
        .ro = 0xffffffff,
701
    },{ .name = "PPK1_3",  .addr = A_PPK1_3,
702
        .ro = 0xffffffff,
703
    },{ .name = "PPK1_4",  .addr = A_PPK1_4,
704
        .ro = 0xffffffff,
705
    },{ .name = "PPK1_5",  .addr = A_PPK1_5,
706
        .ro = 0xffffffff,
707
    },{ .name = "PPK1_6",  .addr = A_PPK1_6,
708
        .ro = 0xffffffff,
709
    },{ .name = "PPK1_7",  .addr = A_PPK1_7,
710
        .ro = 0xffffffff,
711
    },{ .name = "PPK1_8",  .addr = A_PPK1_8,
712
        .ro = 0xffffffff,
713
    },{ .name = "PPK1_9",  .addr = A_PPK1_9,
714
        .ro = 0xffffffff,
715
    },{ .name = "PPK1_10",  .addr = A_PPK1_10,
716
        .ro = 0xffffffff,
717
    },{ .name = "PPK1_11",  .addr = A_PPK1_11,
718
        .ro = 0xffffffff,
719
    }
720
};
721

722
static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
723
                                   uint64_t data, unsigned size)
724
{
725
    RegisterInfoArray *reg_array = opaque;
726
    XlnxZynqMPEFuse *s;
727
    Object *dev;
728

729
    assert(reg_array != NULL);
730

731
    dev = reg_array->mem.owner;
732
    assert(dev);
733

734
    s = XLNX_ZYNQMP_EFUSE(dev);
735

736
    if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
737
        g_autofree char *path = object_get_canonical_path(OBJECT(s));
738

739
        qemu_log_mask(LOG_GUEST_ERROR,
740
                      "%s[reg_0x%02lx]: Attempt to write locked register.\n",
741
                      path, (long)addr);
742
    } else {
743
        register_write_memory(opaque, addr, data, size);
744
    }
745
}
746

747
static const MemoryRegionOps zynqmp_efuse_ops = {
748
    .read = register_read_memory,
749
    .write = zynqmp_efuse_reg_write,
750
    .endianness = DEVICE_LITTLE_ENDIAN,
751
    .valid = {
752
        .min_access_size = 4,
753
        .max_access_size = 4,
754
    },
755
};
756

757
static void zynqmp_efuse_register_reset(RegisterInfo *reg)
758
{
759
    if (!reg->data || !reg->access) {
760
        return;
761
    }
762

763
    /* Reset must not trigger some registers' writers */
764
    switch (reg->access->addr) {
765
    case A_EFUSE_AES_CRC:
766
        *(uint32_t *)reg->data = reg->access->reset;
767
        return;
768
    }
769

770
    register_reset(reg);
771
}
772

773
static void zynqmp_efuse_reset_hold(Object *obj, ResetType type)
774
{
775
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
776
    unsigned int i;
777

778
    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
779
        zynqmp_efuse_register_reset(&s->regs_info[i]);
780
    }
781

782
    zynqmp_efuse_sync_cache(s, FBIT_UNKNOWN);
783
    ARRAY_FIELD_DP32(s->regs, STATUS, CACHE_DONE, 1);
784
    zynqmp_efuse_update_irq(s);
785
}
786

787
static void zynqmp_efuse_realize(DeviceState *dev, Error **errp)
788
{
789
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
790

791
    if (!s->efuse) {
792
        g_autofree char *path = object_get_canonical_path(OBJECT(s));
793

794
        error_setg(errp, "%s.efuse: link property not connected to XLNX-EFUSE",
795
                   path);
796
        return;
797
    }
798

799
    s->efuse->dev = dev;
800
}
801

802
static void zynqmp_efuse_init(Object *obj)
803
{
804
    XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
805
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
806
    RegisterInfoArray *reg_array;
807

808
    reg_array =
809
        register_init_block32(DEVICE(obj), zynqmp_efuse_regs_info,
810
                              ARRAY_SIZE(zynqmp_efuse_regs_info),
811
                              s->regs_info, s->regs,
812
                              &zynqmp_efuse_ops,
813
                              ZYNQMP_EFUSE_ERR_DEBUG,
814
                              R_MAX * 4);
815

816
    sysbus_init_mmio(sbd, &reg_array->mem);
817
    sysbus_init_irq(sbd, &s->irq);
818
}
819

820
static const VMStateDescription vmstate_efuse = {
821
    .name = TYPE_XLNX_ZYNQMP_EFUSE,
822
    .version_id = 1,
823
    .minimum_version_id = 1,
824
    .fields = (const VMStateField[]) {
825
        VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPEFuse, R_MAX),
826
        VMSTATE_END_OF_LIST(),
827
    }
828
};
829

830
static Property zynqmp_efuse_props[] = {
831
    DEFINE_PROP_LINK("efuse",
832
                     XlnxZynqMPEFuse, efuse,
833
                     TYPE_XLNX_EFUSE, XlnxEFuse *),
834

835
    DEFINE_PROP_END_OF_LIST(),
836
};
837

838
static void zynqmp_efuse_class_init(ObjectClass *klass, void *data)
839
{
840
    DeviceClass *dc = DEVICE_CLASS(klass);
841
    ResettableClass *rc = RESETTABLE_CLASS(klass);
842

843
    rc->phases.hold = zynqmp_efuse_reset_hold;
844
    dc->realize = zynqmp_efuse_realize;
845
    dc->vmsd = &vmstate_efuse;
846
    device_class_set_props(dc, zynqmp_efuse_props);
847
}
848

849

850
static const TypeInfo efuse_info = {
851
    .name          = TYPE_XLNX_ZYNQMP_EFUSE,
852
    .parent        = TYPE_SYS_BUS_DEVICE,
853
    .instance_size = sizeof(XlnxZynqMPEFuse),
854
    .class_init    = zynqmp_efuse_class_init,
855
    .instance_init = zynqmp_efuse_init,
856
};
857

858
static void efuse_register_types(void)
859
{
860
    type_register_static(&efuse_info);
861
}
862

863
type_init(efuse_register_types)
864

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.