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
update_tbit_status(XlnxZynqMPEFuse * s)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. */
cache_sync_u32(XlnxZynqMPEFuse * s,unsigned int r_start,unsigned int f_start,unsigned int f_end,unsigned int f_written)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 */
zynqmp_efuse_sync_cache(XlnxZynqMPEFuse * s,unsigned int bit)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
zynqmp_efuse_update_irq(XlnxZynqMPEFuse * s)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
zynqmp_efuse_isr_postw(RegisterInfo * reg,uint64_t val64)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
zynqmp_efuse_ier_prew(RegisterInfo * reg,uint64_t val64)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
zynqmp_efuse_idr_prew(RegisterInfo * reg,uint64_t val64)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
zynqmp_efuse_pgm_addr_postw(RegisterInfo * reg,uint64_t val64)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
zynqmp_efuse_rd_addr_postw(RegisterInfo * reg,uint64_t val64)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
zynqmp_efuse_aes_crc_postw(RegisterInfo * reg,uint64_t val64)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
zynqmp_efuse_cache_load_prew(RegisterInfo * reg,uint64_t valu64)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
zynqmp_efuse_wr_lock_prew(RegisterInfo * reg,uint64_t val)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
zynqmp_efuse_reg_write(void * opaque,hwaddr addr,uint64_t data,unsigned size)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
zynqmp_efuse_register_reset(RegisterInfo * reg)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
zynqmp_efuse_reset_hold(Object * obj,ResetType type)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
zynqmp_efuse_realize(DeviceState * dev,Error ** errp)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
zynqmp_efuse_init(Object * obj)802 static void zynqmp_efuse_init(Object *obj)
803 {
804 XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
805 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
806
807 s->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, &s->reg_array->mem);
816 sysbus_init_irq(sbd, &s->irq);
817 }
818
zynqmp_efuse_finalize(Object * obj)819 static void zynqmp_efuse_finalize(Object *obj)
820 {
821 XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
822
823 register_finalize_block(s->reg_array);
824 }
825
826 static const VMStateDescription vmstate_efuse = {
827 .name = TYPE_XLNX_ZYNQMP_EFUSE,
828 .version_id = 1,
829 .minimum_version_id = 1,
830 .fields = (const VMStateField[]) {
831 VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPEFuse, R_MAX),
832 VMSTATE_END_OF_LIST(),
833 }
834 };
835
836 static Property zynqmp_efuse_props[] = {
837 DEFINE_PROP_LINK("efuse",
838 XlnxZynqMPEFuse, efuse,
839 TYPE_XLNX_EFUSE, XlnxEFuse *),
840
841 DEFINE_PROP_END_OF_LIST(),
842 };
843
zynqmp_efuse_class_init(ObjectClass * klass,void * data)844 static void zynqmp_efuse_class_init(ObjectClass *klass, void *data)
845 {
846 DeviceClass *dc = DEVICE_CLASS(klass);
847 ResettableClass *rc = RESETTABLE_CLASS(klass);
848
849 rc->phases.hold = zynqmp_efuse_reset_hold;
850 dc->realize = zynqmp_efuse_realize;
851 dc->vmsd = &vmstate_efuse;
852 device_class_set_props(dc, zynqmp_efuse_props);
853 }
854
855
856 static const TypeInfo efuse_info = {
857 .name = TYPE_XLNX_ZYNQMP_EFUSE,
858 .parent = TYPE_SYS_BUS_DEVICE,
859 .instance_size = sizeof(XlnxZynqMPEFuse),
860 .class_init = zynqmp_efuse_class_init,
861 .instance_init = zynqmp_efuse_init,
862 .instance_finalize = zynqmp_efuse_finalize,
863 };
864
efuse_register_types(void)865 static void efuse_register_types(void)
866 {
867 type_register_static(&efuse_info);
868 }
869
870 type_init(efuse_register_types)
871