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