blob: a803a3a9c1143ea0bac4a035016ae40a3c3ff88e [file] [log] [blame]
Nicolas Le Bayoncc3f1082019-05-22 19:20:53 +02001/*
2 * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <limits.h>
9
10#include <arch_helpers.h>
11#include <common/debug.h>
12#include <drivers/st/bsec.h>
13#include <drivers/st/bsec3_reg.h>
14#include <drivers/st/stm32mp_reset.h>
15#include <lib/mmio.h>
16#include <lib/spinlock.h>
17#include <libfdt.h>
18
19#include <platform_def.h>
20
21#define BSEC_IP_VERSION_1_0 U(0x10)
22#define BSEC_IP_ID_3 U(0x100033)
23
24#define MAX_NB_TRIES U(3)
25
26/*
27 * IP configuration
28 */
29#define BSEC_OTP_MASK GENMASK_32(4, 0)
30#define BSEC_OTP_BANK_SHIFT U(5)
31#define BSEC_TIMEOUT_VALUE U(0x800000) /* ~7sec @1.2GHz */
32
33/* Magic use to indicated valid SHADOW = 'B' 'S' 'E' 'C' */
34#define BSEC_MAGIC U(0x42534543)
35
36#define OTP_MAX_SIZE (STM32MP2_OTP_MAX_ID + U(1))
37
38struct bsec_shadow {
39 uint32_t magic;
40 uint32_t state;
41 uint32_t value[OTP_MAX_SIZE];
42 uint32_t status[OTP_MAX_SIZE];
43};
44
45static uint32_t otp_bank(uint32_t otp)
46{
47 if (otp > STM32MP2_OTP_MAX_ID) {
48 panic();
49 }
50
51 return (otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT;
52}
53
54static uint32_t otp_bit_mask(uint32_t otp)
55{
56 return BIT(otp & BSEC_OTP_MASK);
57}
58
59/*
60 * bsec_get_status: return status register value.
61 */
62static uint32_t bsec_get_status(void)
63{
64 return mmio_read_32(BSEC_BASE + BSEC_OTPSR);
65}
66
67/*
68 * bsec_get_version: return BSEC version.
69 */
70static uint32_t bsec_get_version(void)
71{
72 return mmio_read_32(BSEC_BASE + BSEC_VERR) & BSEC_VERR_MASK;
73}
74
75/*
76 * bsec_get_id: return BSEC ID.
77 */
78static uint32_t bsec_get_id(void)
79{
80 return mmio_read_32(BSEC_BASE + BSEC_IPIDR);
81}
82
83static bool is_fuse_shadowed(uint32_t otp)
84{
85 uint32_t bank = otp_bank(otp);
86 uint32_t otp_mask = otp_bit_mask(otp);
87 uint32_t bank_value;
88
89 bank_value = mmio_read_32(BSEC_BASE + BSEC_SFSR(bank));
90
91 if ((bank_value & otp_mask) != 0U) {
92 return true;
93 }
94
95 return false;
96}
97
98static void poll_otp_status_busy(void)
99{
100 uint32_t timeout = BSEC_TIMEOUT_VALUE;
101
102 while (((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) && (timeout != 0U)) {
103 timeout--;
104 }
105
106 if ((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) {
107 ERROR("BSEC timeout\n");
108 panic();
109 }
110}
111
112static uint32_t check_read_error(uint32_t otp)
113{
114 uint32_t status = bsec_get_status();
115
116 if ((status & BSEC_OTPSR_SECF) != 0U) {
117 VERBOSE("BSEC read %u single error correction detected\n", otp);
118 }
119
120 if ((status & BSEC_OTPSR_PPLF) != 0U) {
121 VERBOSE("BSEC read %u permanent programming lock detected.\n", otp);
122 }
123
124 if ((status & BSEC_OTPSR_PPLMF) != 0U) {
125 ERROR("BSEC read %u error 0x%x\n", otp, status);
126 return BSEC_ERROR;
127 }
128
129 if ((status & (BSEC_OTPSR_DISTURBF | BSEC_OTPSR_DEDF | BSEC_OTPSR_AMEF)) != 0U) {
130 ERROR("BSEC read %u error 0x%x with invalid FVR\n", otp, status);
131 return BSEC_RETRY;
132 }
133
134 return BSEC_OK;
135}
136
137static uint32_t check_program_error(uint32_t otp)
138{
139 uint32_t status = bsec_get_status();
140
141 if ((status & BSEC_OTPSR_PROGFAIL) != 0U) {
142 ERROR("BSEC program %u error 0x%x\n", otp, status);
143 return BSEC_RETRY;
144 }
145
146 return BSEC_OK;
147}
148
149static void check_reset_error(void)
150{
151 uint32_t status = bsec_get_status();
152
153 /* check initial status reporting */
154 if ((status & BSEC_OTPSR_BUSY) != 0U) {
155 VERBOSE("BSEC reset and busy when OTPSR read\n");
156 }
157 if ((status & BSEC_OTPSR_HIDEUP) != 0U) {
158 VERBOSE("BSEC upper fuse are not accessible (HIDEUP)\n");
159 }
160 if ((status & BSEC_OTPSR_OTPSEC) != 0U) {
161 VERBOSE("BSEC reset single error correction detected\n");
162 }
163 if ((status & BSEC_OTPSR_OTPNVIR) == 0U) {
164 VERBOSE("BSEC reset first fuse word 0 is detected zero\n");
165 }
166 if ((status & BSEC_OTPSR_OTPERR) != 0U) {
167 ERROR("BSEC reset critical error 0x%x\n", status);
168 panic();
169 }
170 if ((status & BSEC_OTPSR_FUSEOK) != BSEC_OTPSR_FUSEOK) {
171 ERROR("BSEC reset critical error 0x%x\n", status);
172 panic();
173 }
174}
175
176static bool is_bsec_write_locked(void)
177{
178 return (mmio_read_32(BSEC_BASE + BSEC_LOCKR) & BSEC_LOCKR_GWLOCK_MASK) != 0U;
179}
180
181/*
182 * bsec_probe: initialize BSEC driver.
183 * return value: BSEC_OK if no error.
184 */
185uint32_t bsec_probe(void)
186{
187 uint32_t version = bsec_get_version();
188 uint32_t id = bsec_get_id();
189
190 if ((version != BSEC_IP_VERSION_1_0) || (id != BSEC_IP_ID_3)) {
191 ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
192 panic();
193 }
194
195 check_reset_error();
196
197 return BSEC_OK;
198}
199
200/*
201 * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
202 * otp: OTP number.
203 * return value: BSEC_OK if no error.
204 */
205static uint32_t bsec_shadow_register(uint32_t otp)
206{
207 uint32_t result;
208 uint32_t i;
209 bool value;
210
211 result = bsec_read_sr_lock(otp, &value);
212 if (result != BSEC_OK) {
213 WARN("BSEC: %u Sticky-read bit read Error %u\n", otp, result);
214 } else if (value) {
215 VERBOSE("BSEC: OTP %u is locked and will not be refreshed\n", otp);
216 }
217
218 for (i = 0U; i < MAX_NB_TRIES; i++) {
219 mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp);
220
221 poll_otp_status_busy();
222
223 result = check_read_error(otp);
224 if (result != BSEC_RETRY) {
225 break;
226 }
227 }
228
229 return result;
230}
231
232/*
233 * bsec_write_otp: write a value in shadow OTP.
234 * val: value to program.
235 * otp: OTP number.
236 * return value: BSEC_OK if no error.
237 */
238uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
239{
240 bool state;
241 uint32_t result;
242
243 if (otp > STM32MP2_OTP_MAX_ID) {
244 panic();
245 }
246
247 if (!is_fuse_shadowed(otp)) {
248 return BSEC_ERROR;
249 }
250
251 if (is_bsec_write_locked()) {
252 return BSEC_WRITE_LOCKED;
253 }
254
255 result = bsec_read_sw_lock(otp, &state);
256 if (result != BSEC_OK) {
257 WARN("Shadow register is SW locked\n");
258 return result;
259 }
260
261 mmio_write_32(BSEC_BASE + BSEC_FVR(otp), val);
262
263 return BSEC_OK;
264}
265
266/*
267 * bsec_program_otp: program a bit in SAFMEM after the prog.
268 * The OTP data is not refreshed.
269 * val: value to program.
270 * otp: OTP number.
271 * return value: BSEC_OK if no error.
272 */
273uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
274{
275 uint32_t result;
276 uint32_t i;
277 bool value;
278
279 if (otp > STM32MP2_OTP_MAX_ID) {
280 panic();
281 }
282
283 if (is_bsec_write_locked() == true) {
284 return BSEC_WRITE_LOCKED;
285 }
286
287 result = bsec_read_sp_lock(otp, &value);
288 if (result != BSEC_OK) {
289 WARN("BSEC: %u Sticky-prog bit read Error %u\n", otp, result);
290 } else if (value) {
291 WARN("BSEC: OTP locked, prog will be ignored\n");
292 return BSEC_WRITE_LOCKED;
293 }
294
295 mmio_write_32(BSEC_BASE + BSEC_WDR, val);
296
297 for (i = 0U; i < MAX_NB_TRIES; i++) {
298 mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp | BSEC_OTPCR_PROG);
299
300 poll_otp_status_busy();
301
302 result = check_program_error(otp);
303 if (result != BSEC_RETRY) {
304 break;
305 }
306 }
307
308 return result;
309}
310
311/*
312 * bsec_read_debug_conf: read debug configuration.
313 */
314uint32_t bsec_read_debug_conf(void)
315{
316 return mmio_read_32(BSEC_BASE + BSEC_DENR);
317}
318
319static uint32_t bsec_lock_register_set(uint32_t offset, uint32_t mask)
320{
321 uint32_t value = mmio_read_32(BSEC_BASE + offset);
322
323 /* The lock is already set */
324 if ((value & mask) != 0U) {
325 return BSEC_OK;
326 }
327
328 if (is_bsec_write_locked()) {
329 return BSEC_WRITE_LOCKED;
330 }
331
332 value |= mask;
333
334 mmio_write_32(BSEC_BASE + offset, value);
335
336 return BSEC_OK;
337}
338
339static bool bsec_lock_register_get(uint32_t offset, uint32_t mask)
340{
341 uint32_t value = mmio_read_32(BSEC_BASE + offset);
342
343 return (value & mask) != 0U;
344}
345
346/*
347 * bsec_set_sr_lock: set shadow-read lock.
348 * otp: OTP number.
349 * return value: BSEC_OK if no error.
350 */
351uint32_t bsec_set_sr_lock(uint32_t otp)
352{
353 uint32_t bank = otp_bank(otp);
354 uint32_t otp_mask = otp_bit_mask(otp);
355
356 if (otp > STM32MP2_OTP_MAX_ID) {
357 panic();
358 }
359
360 return bsec_lock_register_set(BSEC_SRLOCK(bank), otp_mask);
361}
362
363/*
364 * bsec_read_sr_lock: read shadow-read lock.
365 * otp: OTP number.
366 * value: read value (true or false).
367 * return value: BSEC_OK if no error.
368 */
369uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
370{
371 uint32_t bank = otp_bank(otp);
372 uint32_t otp_mask = otp_bit_mask(otp);
373
374 assert(value != NULL);
375 if (otp > STM32MP2_OTP_MAX_ID) {
376 panic();
377 }
378
379 *value = bsec_lock_register_get(BSEC_SRLOCK(bank), otp_mask);
380
381 return BSEC_OK;
382}
383
384/*
385 * bsec_set_sw_lock: set shadow-write lock.
386 * otp: OTP number.
387 * return value: BSEC_OK if no error.
388 */
389uint32_t bsec_set_sw_lock(uint32_t otp)
390{
391 uint32_t bank = otp_bank(otp);
392 uint32_t otp_mask = otp_bit_mask(otp);
393
394 if (otp > STM32MP2_OTP_MAX_ID) {
395 panic();
396 }
397
398 return bsec_lock_register_set(BSEC_SWLOCK(bank), otp_mask);
399}
400
401/*
402 * bsec_read_sw_lock: read shadow-write lock.
403 * otp: OTP number.
404 * value: read value (true or false).
405 * return value: BSEC_OK if no error.
406 */
407uint32_t bsec_read_sw_lock(uint32_t otp, bool *value)
408{
409 uint32_t bank = otp_bank(otp);
410 uint32_t otp_mask = otp_bit_mask(otp);
411
412 assert(value != NULL);
413 if (otp > STM32MP2_OTP_MAX_ID) {
414 panic();
415 }
416
417 *value = bsec_lock_register_get(BSEC_SWLOCK(bank), otp_mask);
418
419 return BSEC_OK;
420}
421
422/*
423 * bsec_set_sp_lock: set shadow-program lock.
424 * otp: OTP number.
425 * return value: BSEC_OK if no error.
426 */
427uint32_t bsec_set_sp_lock(uint32_t otp)
428{
429 uint32_t bank = otp_bank(otp);
430 uint32_t otp_mask = otp_bit_mask(otp);
431
432 if (otp > STM32MP2_OTP_MAX_ID) {
433 panic();
434 }
435
436 return bsec_lock_register_set(BSEC_SPLOCK(bank), otp_mask);
437}
438
439/*
440 * bsec_read_sp_lock: read shadow-program lock.
441 * otp: OTP number.
442 * value: read value (true or false).
443 * return value: BSEC_OK if no error.
444 */
445uint32_t bsec_read_sp_lock(uint32_t otp, bool *value)
446{
447 uint32_t bank = otp_bank(otp);
448 uint32_t otp_mask = otp_bit_mask(otp);
449
450 assert(value != NULL);
451 if (otp > STM32MP2_OTP_MAX_ID) {
452 panic();
453 }
454
455 *value = bsec_lock_register_get(BSEC_SPLOCK(bank), otp_mask);
456
457 return BSEC_OK;
458}
459
460/*
461 * bsec_get_secure_state: read state in BSEC status register.
462 * return: secure state
463 */
464uint32_t bsec_get_secure_state(void)
465{
466 uint32_t state = BSEC_STATE_INVALID;
467 uint32_t status = bsec_get_status();
468 uint32_t bsec_sr = mmio_read_32(BSEC_BASE + BSEC_SR);
469
470 if ((status & BSEC_OTPSR_FUSEOK) == BSEC_OTPSR_FUSEOK) {
471 /* NVSTATE is only valid if FUSEOK */
472 uint32_t nvstates = (bsec_sr & BSEC_SR_NVSTATE_MASK) >> BSEC_SR_NVSTATE_SHIFT;
473
474 if (nvstates == BSEC_SR_NVSTATE_OPEN) {
475 state = BSEC_STATE_SEC_OPEN;
476 } else if (nvstates == BSEC_SR_NVSTATE_CLOSED) {
477 state = BSEC_STATE_SEC_CLOSED;
478 } else {
479 VERBOSE("%s nvstates = %u\n", __func__, nvstates);
480 }
481 }
482
483 return state;
484}
485
486/*
487 * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
488 * val: read value.
489 * otp: OTP number.
490 * return value: BSEC_OK if no error.
491 */
492uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
493{
494 assert(val != NULL);
495 if (otp > STM32MP2_OTP_MAX_ID) {
496 panic();
497 }
498
499 *val = 0U;
500
501 if (is_bsec_write_locked()) {
502 return BSEC_WRITE_LOCKED;
503 }
504
505 if (!is_fuse_shadowed(otp)) {
506 uint32_t result = bsec_shadow_register(otp);
507
508 if (result != BSEC_OK) {
509 ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
510 return result;
511 }
512 }
513
514 *val = mmio_read_32(BSEC_BASE + BSEC_FVR(otp));
515
516 return BSEC_OK;
517}
518
519/*
520 * bsec_read_otp: read an OTP data value.
521 * val: read value.
522 * otp: OTP number.
523 * return value: BSEC_OK if no error.
524 */
525uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
526{
527 assert(val != NULL);
528 if (otp > STM32MP2_OTP_MAX_ID) {
529 panic();
530 }
531
532 return bsec_shadow_read_otp(val, otp);
533}