From c7061045072424dc47cc0a12d53bf0fa8a49f1c0 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 14 Dec 2022 13:45:04 +0100 Subject: [PATCH] refactor(st-bsec): improve BSEC driver In order to ease the introduction of a new BSEC3 driver for STM32MP25, the BSEC2 driver is reworked. Unused functions are removed. The bsec_base global variable is removed in favor of the macro BSEC_BASE. A rework is also done around function checking the state of BSEC. Change-Id: I1ad76cb67333ab9a8fa1d65db34d74a712bf1190 Signed-off-by: Patrick Delaunay Signed-off-by: Yann Gautier --- drivers/st/bsec/bsec2.c | 330 +++++++++------------------ include/drivers/st/bsec.h | 102 ++------- include/drivers/st/bsec2_reg.h | 17 +- plat/st/stm32mp1/services/bsec_svc.c | 11 +- 4 files changed, 136 insertions(+), 324 deletions(-) diff --git a/drivers/st/bsec/bsec2.c b/drivers/st/bsec/bsec2.c index 68d3a5b89..463fb300c 100644 --- a/drivers/st/bsec/bsec2.c +++ b/drivers/st/bsec/bsec2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,15 +21,26 @@ #define BSEC_IP_VERSION_2_0 U(0x20) #define BSEC_IP_ID_2 U(0x100032) +/* + * IP configuration + */ +#define BSEC_OTP_MASK GENMASK(4, 0) +#define BSEC_OTP_BANK_SHIFT 5 +#define BSEC_TIMEOUT_VALUE U(0xFFFF) + #define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT) -static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused; +static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __maybe_unused; +static uint32_t bsec_shadow_register(uint32_t otp); static uint32_t bsec_power_safmem(bool power); +static uint32_t bsec_get_version(void); +static uint32_t bsec_get_id(void); +static uint32_t bsec_get_status(void); +static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value); /* BSEC access protection */ static spinlock_t bsec_spinlock; -static uintptr_t bsec_base; static void bsec_lock(void) { @@ -47,7 +58,7 @@ static void bsec_unlock(void) static bool is_otp_invalid_mode(void) { - bool ret = ((bsec_get_status() & BSEC_MODE_INVALID) == BSEC_MODE_INVALID); + bool ret = ((bsec_get_status() & BSEC_OTP_STATUS_INVALID) == BSEC_OTP_STATUS_INVALID); if (ret) { ERROR("OTP mode is OTP-INVALID\n"); @@ -163,7 +174,7 @@ static void bsec_late_init(void) panic(); } - assert(bsec_base == bsec_info.base); + assert(bsec_info.base == BSEC_BASE); bsec_dt_otp_nsec_access(fdt, node); } @@ -177,6 +188,11 @@ static uint32_t otp_bank_offset(uint32_t otp) sizeof(uint32_t); } +static uint32_t otp_bit_mask(uint32_t otp) +{ + return BIT(otp & BSEC_OTP_MASK); +} + /* * bsec_check_error: check BSEC error status. * otp: OTP number. @@ -186,10 +202,10 @@ static uint32_t otp_bank_offset(uint32_t otp) */ static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed) { - uint32_t bit = BIT(otp & BSEC_OTP_MASK); + uint32_t bit = otp_bit_mask(otp); uint32_t bank = otp_bank_offset(otp); - if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) { + if ((mmio_read_32(BSEC_BASE + BSEC_ERROR_OFF + bank) & bit) != 0U) { return BSEC_ERROR; } @@ -197,7 +213,7 @@ static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed) return BSEC_OK; } - if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) { + if ((mmio_read_32(BSEC_BASE + BSEC_DISTURBED_OFF + bank) & bit) != 0U) { return BSEC_DISTURBED; } @@ -210,14 +226,12 @@ static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed) */ uint32_t bsec_probe(void) { - bsec_base = BSEC_BASE; - if (is_otp_invalid_mode()) { return BSEC_ERROR; } - if ((((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_1_1) && - ((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_2_0)) || + if (((bsec_get_version() != BSEC_IP_VERSION_1_1) && + (bsec_get_version() != BSEC_IP_VERSION_2_0)) || (bsec_get_id() != BSEC_IP_ID_2)) { panic(); } @@ -228,103 +242,12 @@ uint32_t bsec_probe(void) return BSEC_OK; } -/* - * bsec_get_base: return BSEC base address. - */ -uint32_t bsec_get_base(void) -{ - return bsec_base; -} - -/* - * bsec_set_config: enable and configure BSEC. - * cfg: pointer to param structure used to set register. - * return value: BSEC_OK if no error. - */ -uint32_t bsec_set_config(struct bsec_config *cfg) -{ - uint32_t value; - uint32_t result; - - if (is_otp_invalid_mode()) { - return BSEC_ERROR; - } - - value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) & - BSEC_CONF_FRQ_MASK) | - (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) & - BSEC_CONF_PRG_WIDTH_MASK) | - (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) & - BSEC_CONF_TREAD_MASK)); - - bsec_lock(); - - mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value); - - bsec_unlock(); - - result = bsec_power_safmem((bool)cfg->power & - BSEC_CONF_POWER_UP_MASK); - if (result != BSEC_OK) { - return result; - } - - value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) & - UPPER_OTP_LOCK_MASK) | - (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) & - DENREG_LOCK_MASK) | - (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) & - GPLOCK_LOCK_MASK)); - - bsec_lock(); - - mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value); - - bsec_unlock(); - - return BSEC_OK; -} - -/* - * bsec_get_config: return config parameters set in BSEC registers. - * cfg: config param return. - * return value: BSEC_OK if no error. - */ -uint32_t bsec_get_config(struct bsec_config *cfg) -{ - uint32_t value; - - if (cfg == NULL) { - return BSEC_INVALID_PARAM; - } - - value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF); - cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >> - BSEC_CONF_POWER_UP_SHIFT); - cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >> - BSEC_CONF_FRQ_SHIFT); - cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >> - BSEC_CONF_PRG_WIDTH_SHIFT); - cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >> - BSEC_CONF_TREAD_SHIFT); - - value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF); - cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >> - UPPER_OTP_LOCK_SHIFT); - cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >> - DENREG_LOCK_SHIFT); - cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >> - GPLOCK_LOCK_SHIFT); - - return BSEC_OK; -} - /* * bsec_shadow_register: copy SAFMEM OTP to BSEC data. * otp: OTP number. * return value: BSEC_OK if no error. */ -uint32_t bsec_shadow_register(uint32_t otp) +static uint32_t bsec_shadow_register(uint32_t otp) { uint32_t result; bool value; @@ -345,7 +268,7 @@ uint32_t bsec_shadow_register(uint32_t otp) otp); } - if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) { + if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) { result = bsec_power_safmem(true); if (result != BSEC_OK) { @@ -357,9 +280,9 @@ uint32_t bsec_shadow_register(uint32_t otp) bsec_lock(); - mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ); + mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_READ); - while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) { + while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) { ; } @@ -392,7 +315,7 @@ uint32_t bsec_read_otp(uint32_t *val, uint32_t otp) return BSEC_INVALID_PARAM; } - *val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF + + *val = mmio_read_32(BSEC_BASE + BSEC_OTP_DATA_OFF + (otp * sizeof(uint32_t))); return BSEC_OK; @@ -427,7 +350,7 @@ uint32_t bsec_write_otp(uint32_t val, uint32_t otp) /* Ensure integrity of each register access sequence */ bsec_lock(); - mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF + + mmio_write_32(BSEC_BASE + BSEC_OTP_DATA_OFF + (otp * sizeof(uint32_t)), val); bsec_unlock(); @@ -470,12 +393,11 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) return BSEC_PROG_FAIL; } - if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) & - BIT(BSEC_LOCK_PROGRAM)) != 0U) { + if ((mmio_read_32(BSEC_BASE + BSEC_OTP_LOCK_OFF) & GPLOCK_LOCK_MASK) != 0U) { WARN("BSEC: GPLOCK activated, prog will be ignored\n"); } - if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) { + if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) { result = bsec_power_safmem(true); if (result != BSEC_OK) { @@ -487,15 +409,15 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) bsec_lock(); - mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val); + mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, val); - mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE); + mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE); - while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) { + while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) { ; } - if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) { + if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) { result = BSEC_PROG_FAIL; } else { result = bsec_check_error(otp, true); @@ -517,6 +439,7 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp) * otp: OTP number. * return value: BSEC_OK if no error. */ +#if defined(IMAGE_BL32) uint32_t bsec_permanent_lock_otp(uint32_t otp) { uint32_t result; @@ -532,7 +455,7 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) return BSEC_INVALID_PARAM; } - if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) { + if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) { result = bsec_power_safmem(true); if (result != BSEC_OK) { @@ -554,16 +477,16 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) bsec_lock(); - mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data); + mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, data); - mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, + mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, addr | BSEC_WRITE | BSEC_LOCK); - while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) { + while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) { ; } - if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) { + if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) { result = BSEC_PROG_FAIL; } else { result = bsec_check_error(otp, false); @@ -579,30 +502,14 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp) return result; } - -/* - * bsec_write_debug_conf: write value in debug feature. - * to enable/disable debug service. - * val: value to write. - * return value: none. - */ -void bsec_write_debug_conf(uint32_t val) -{ - if (is_otp_invalid_mode()) { - return; - } - - bsec_lock(); - mmio_write_32(bsec_base + BSEC_DEN_OFF, val & BSEC_DEN_ALL_MSK); - bsec_unlock(); -} +#endif /* * bsec_read_debug_conf: return debug configuration register value. */ uint32_t bsec_read_debug_conf(void) { - return mmio_read_32(bsec_base + BSEC_DEN_OFF); + return mmio_read_32(BSEC_BASE + BSEC_DEN_OFF); } /* @@ -618,59 +525,35 @@ void bsec_write_scratch(uint32_t val) } bsec_lock(); - mmio_write_32(bsec_base + BSEC_SCRATCH_OFF, val); + mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val); bsec_unlock(); #else mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val); #endif } -/* - * bsec_read_scratch: return scratch register value. - */ -uint32_t bsec_read_scratch(void) -{ - return mmio_read_32(bsec_base + BSEC_SCRATCH_OFF); -} - /* * bsec_get_status: return status register value. */ -uint32_t bsec_get_status(void) +static uint32_t bsec_get_status(void) { - return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF); -} - -/* - * bsec_get_hw_conf: return hardware configuration register value. - */ -uint32_t bsec_get_hw_conf(void) -{ - return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF); + return mmio_read_32(BSEC_BASE + BSEC_OTP_STATUS_OFF); } /* * bsec_get_version: return BSEC version register value. */ -uint32_t bsec_get_version(void) +static uint32_t bsec_get_version(void) { - return mmio_read_32(bsec_base + BSEC_IPVR_OFF); + return mmio_read_32(BSEC_BASE + BSEC_IPVR_OFF) & BSEC_IPVR_MSK; } /* * bsec_get_id: return BSEC ID register value. */ -uint32_t bsec_get_id(void) +static uint32_t bsec_get_id(void) { - return mmio_read_32(bsec_base + BSEC_IP_ID_OFF); -} - -/* - * bsec_get_magic_id: return BSEC magic number register value. - */ -uint32_t bsec_get_magic_id(void) -{ - return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF); + return mmio_read_32(BSEC_BASE + BSEC_IP_ID_OFF); } /* @@ -681,7 +564,7 @@ uint32_t bsec_get_magic_id(void) uint32_t bsec_set_sr_lock(uint32_t otp) { uint32_t bank = otp_bank_offset(otp); - uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); + uint32_t otp_mask = otp_bit_mask(otp); if (is_otp_invalid_mode()) { return BSEC_ERROR; @@ -692,7 +575,7 @@ uint32_t bsec_set_sr_lock(uint32_t otp) } bsec_lock(); - mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, otp_mask); + mmio_write_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank, otp_mask); bsec_unlock(); return BSEC_OK; @@ -707,14 +590,14 @@ uint32_t bsec_set_sr_lock(uint32_t otp) uint32_t bsec_read_sr_lock(uint32_t otp, bool *value) { uint32_t bank = otp_bank_offset(otp); - uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); + uint32_t otp_mask = otp_bit_mask(otp); uint32_t bank_value; if (otp > STM32MP1_OTP_MAX_ID) { return BSEC_INVALID_PARAM; } - bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank); + bank_value = mmio_read_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank); *value = ((bank_value & otp_mask) != 0U); @@ -729,7 +612,7 @@ uint32_t bsec_read_sr_lock(uint32_t otp, bool *value) uint32_t bsec_set_sw_lock(uint32_t otp) { uint32_t bank = otp_bank_offset(otp); - uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); + uint32_t otp_mask = otp_bit_mask(otp); if (is_otp_invalid_mode()) { return BSEC_ERROR; @@ -740,7 +623,7 @@ uint32_t bsec_set_sw_lock(uint32_t otp) } bsec_lock(); - mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, otp_mask); + mmio_write_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank, otp_mask); bsec_unlock(); return BSEC_OK; @@ -762,7 +645,7 @@ uint32_t bsec_read_sw_lock(uint32_t otp, bool *value) return BSEC_INVALID_PARAM; } - bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank); + bank_value = mmio_read_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank); *value = ((bank_value & otp_mask) != 0U); @@ -777,7 +660,7 @@ uint32_t bsec_read_sw_lock(uint32_t otp, bool *value) uint32_t bsec_set_sp_lock(uint32_t otp) { uint32_t bank = otp_bank_offset(otp); - uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); + uint32_t otp_mask = otp_bit_mask(otp); if (is_otp_invalid_mode()) { return BSEC_ERROR; @@ -788,7 +671,7 @@ uint32_t bsec_set_sp_lock(uint32_t otp) } bsec_lock(); - mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, otp_mask); + mmio_write_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank, otp_mask); bsec_unlock(); return BSEC_OK; @@ -810,7 +693,7 @@ uint32_t bsec_read_sp_lock(uint32_t otp, bool *value) return BSEC_INVALID_PARAM; } - bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank); + bank_value = mmio_read_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank); *value = ((bank_value & otp_mask) != 0U); @@ -823,53 +706,23 @@ uint32_t bsec_read_sp_lock(uint32_t otp, bool *value) * value: read value (true or false). * return value: BSEC_OK if no error. */ -uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value) +static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value) { uint32_t bank = otp_bank_offset(otp); - uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); + uint32_t otp_mask = otp_bit_mask(otp); uint32_t bank_value; if (otp > STM32MP1_OTP_MAX_ID) { return BSEC_INVALID_PARAM; } - bank_value = mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank); + bank_value = mmio_read_32(BSEC_BASE + BSEC_WRLOCK_OFF + bank); *value = ((bank_value & otp_mask) != 0U); return BSEC_OK; } -/* - * bsec_otp_lock: Lock Upper OTP or Global Programming or Debug Enable. - * service: Service to lock, see header file. - * return value: BSEC_OK if no error. - */ -uint32_t bsec_otp_lock(uint32_t service) -{ - uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF; - - if (is_otp_invalid_mode()) { - return BSEC_ERROR; - } - - switch (service) { - case BSEC_LOCK_UPPER_OTP: - mmio_write_32(reg, BIT(BSEC_LOCK_UPPER_OTP)); - break; - case BSEC_LOCK_DEBUG: - mmio_write_32(reg, BIT(BSEC_LOCK_DEBUG)); - break; - case BSEC_LOCK_PROGRAM: - mmio_write_32(reg, BIT(BSEC_LOCK_PROGRAM)); - break; - default: - return BSEC_INVALID_PARAM; - } - - return BSEC_OK; -} - /* * bsec_power_safmem: Activate or deactivate SAFMEM power. * power: true to power up, false to power down. @@ -882,7 +735,7 @@ static uint32_t bsec_power_safmem(bool power) bsec_lock(); - register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF); + register_val = mmio_read_32(BSEC_BASE + BSEC_OTP_CONF_OFF); if (power) { register_val |= BSEC_CONF_POWER_UP_MASK; @@ -890,15 +743,15 @@ static uint32_t bsec_power_safmem(bool power) register_val &= ~BSEC_CONF_POWER_UP_MASK; } - mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val); + mmio_write_32(BSEC_BASE + BSEC_OTP_CONF_OFF, register_val); if (power) { - while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) && + while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) && (timeout != 0U)) { timeout--; } } else { - while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) && + while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) != 0U) && (timeout != 0U)) { timeout--; } @@ -915,28 +768,29 @@ static uint32_t bsec_power_safmem(bool power) /* * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value. - * otp_value: read value. - * word: OTP number. + * val: read value. + * otp: OTP number. * return value: BSEC_OK if no error. */ -uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word) +uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp) { uint32_t result; - result = bsec_shadow_register(word); + result = bsec_shadow_register(otp); if (result != BSEC_OK) { - ERROR("BSEC: %u Shadowing Error %u\n", word, result); + ERROR("BSEC: %u Shadowing Error %u\n", otp, result); return result; } - result = bsec_read_otp(otp_value, word); + result = bsec_read_otp(val, otp); if (result != BSEC_OK) { - ERROR("BSEC: %u Read Error %u\n", word, result); + ERROR("BSEC: %u Read Error %u\n", otp, result); } return result; } +#if defined(IMAGE_BL32) /* * bsec_check_nsec_access_rights: check non-secure access rights to target OTP. * otp: OTP number. @@ -944,7 +798,6 @@ uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word) */ uint32_t bsec_check_nsec_access_rights(uint32_t otp) { -#if defined(IMAGE_BL32) if (otp > STM32MP1_OTP_MAX_ID) { return BSEC_INVALID_PARAM; } @@ -954,8 +807,33 @@ uint32_t bsec_check_nsec_access_rights(uint32_t otp) return BSEC_ERROR; } } -#endif return BSEC_OK; } +#endif +uint32_t bsec_get_secure_state(void) +{ + uint32_t status = bsec_get_status(); + uint32_t result = BSEC_STATE_INVALID; + uint32_t otp_enc_id __maybe_unused; + uint32_t otp_bit_len __maybe_unused; + int res __maybe_unused; + + if ((status & BSEC_OTP_STATUS_INVALID) != 0U) { + result = BSEC_STATE_INVALID; + } else { + if ((status & BSEC_OTP_STATUS_SECURE) != 0U) { + if (stm32mp_is_closed_device()) { + result = BSEC_STATE_SEC_CLOSED; + } else { + result = BSEC_STATE_SEC_OPEN; + } + } else { + /* OTP modes OPEN1 and OPEN2 are not supported */ + result = BSEC_STATE_INVALID; + } + } + + return result; +} diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h index 60dcf3c12..4a1517af3 100644 --- a/include/drivers/st/bsec.h +++ b/include/drivers/st/bsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,13 +12,6 @@ #include -/* - * IP configuration - */ -#define BSEC_OTP_MASK GENMASK(4, 0) -#define BSEC_OTP_BANK_SHIFT 5 -#define BSEC_TIMEOUT_VALUE 0xFFFF - /* * Return status */ @@ -32,98 +25,49 @@ #define BSEC_RETRY 0xFFFFFFF8U #define BSEC_NOT_SUPPORTED 0xFFFFFFF7U #define BSEC_WRITE_LOCKED 0xFFFFFFF6U -#define BSEC_ERROR_INVALID_FVR 0xFFFFFFF5U /* - * OTP MODE + * get BSEC global state: result for bsec_get_secure_state() + * @state: global state + * [1:0] BSEC state + * 00b: Sec Open + * 01b: Sec Closed + * 11b: Invalid + * [8]: Hardware Key set = 1b */ -#define BSEC_MODE_OPEN1 0x00U -#define BSEC_MODE_SECURED 0x01U -#define BSEC_MODE_OPEN2 0x02U -#define BSEC_MODE_INVALID 0x04U - -/* - * OTP Lock services definition. - * Value must corresponding to the bit number in the register. - * Special case: (bit number << 1) for BSEC3. - */ -#define BSEC_LOCK_UPPER_OTP 0x00 -#define BSEC_LOCK_GWLOCK 0x01 -#define BSEC_LOCK_DEBUG 0x02 -#define BSEC_LOCK_PROGRAM 0x03 -#define BSEC_LOCK_KVLOCK 0x04 - -/* - * Values for struct bsec_config::freq - */ -#define FREQ_10_20_MHZ 0x0 -#define FREQ_20_30_MHZ 0x1 -#define FREQ_30_45_MHZ 0x2 -#define FREQ_45_67_MHZ 0x3 - -/* - * Device info structure, providing device-specific functions and a means of - * adding driver-specific state. - */ -struct bsec_config { - uint8_t den_lock; /* - * Debug enable sticky lock - * 1 debug enable is locked until next reset - */ - - /* BSEC2 only */ - uint8_t tread; /* SAFMEM Reading current level default 0 */ - uint8_t pulse_width; /* SAFMEM Programming pulse width default 1 */ - uint8_t freq; /* - * SAFMEM CLOCK see freq value define - * default FREQ_45_67_MHZ - */ - uint8_t power; /* Power up SAFMEM. 1 power up, 0 power off */ - uint8_t prog_lock; /* - * Programming Sticky lock - * 1 programming is locked until next reset - */ - uint8_t upper_otp_lock; /* - * Shadowing of upper OTP sticky lock - * 1 shadowing of upper OTP is locked - * until next reset - */ -}; +#define BSEC_STATE_SEC_OPEN U(0x0) +#define BSEC_STATE_SEC_CLOSED U(0x1) +#define BSEC_STATE_INVALID U(0x3) +#define BSEC_STATE_MASK GENMASK_32(1, 0) uint32_t bsec_probe(void); -uint32_t bsec_get_base(void); -uint32_t bsec_set_config(struct bsec_config *cfg); -uint32_t bsec_get_config(struct bsec_config *cfg); - -uint32_t bsec_shadow_register(uint32_t otp); uint32_t bsec_read_otp(uint32_t *val, uint32_t otp); +uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp); uint32_t bsec_write_otp(uint32_t val, uint32_t otp); uint32_t bsec_program_otp(uint32_t val, uint32_t otp); -uint32_t bsec_permanent_lock_otp(uint32_t otp); -void bsec_write_debug_conf(uint32_t val); uint32_t bsec_read_debug_conf(void); void bsec_write_scratch(uint32_t val); -uint32_t bsec_read_scratch(void); - -uint32_t bsec_get_status(void); -uint32_t bsec_get_hw_conf(void); -uint32_t bsec_get_version(void); -uint32_t bsec_get_id(void); -uint32_t bsec_get_magic_id(void); +/* Sticky lock support */ uint32_t bsec_set_sr_lock(uint32_t otp); uint32_t bsec_read_sr_lock(uint32_t otp, bool *value); uint32_t bsec_set_sw_lock(uint32_t otp); uint32_t bsec_read_sw_lock(uint32_t otp, bool *value); uint32_t bsec_set_sp_lock(uint32_t otp); uint32_t bsec_read_sp_lock(uint32_t otp, bool *value); -uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value); -uint32_t bsec_otp_lock(uint32_t service); -uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word); +uint32_t bsec_get_secure_state(void); +static inline bool bsec_mode_is_closed_device(void) +{ + return (bsec_get_secure_state() & BSEC_STATE_MASK) == BSEC_STATE_SEC_CLOSED; +} + +#if defined(IMAGE_BL32) +uint32_t bsec_permanent_lock_otp(uint32_t otp); uint32_t bsec_check_nsec_access_rights(uint32_t otp); +#endif #endif /* BSEC_H */ diff --git a/include/drivers/st/bsec2_reg.h b/include/drivers/st/bsec2_reg.h index f8950205d..fa44cf153 100644 --- a/include/drivers/st/bsec2_reg.h +++ b/include/drivers/st/bsec2_reg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, STMicroelectronics - All Rights Reserved + * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -80,22 +80,17 @@ #define GPLOCK_LOCK_SHIFT 4 /* BSEC_OTP_STATUS Register */ -#define BSEC_MODE_STATUS_MASK GENMASK(2, 0) -#define BSEC_MODE_SECURE_MASK BIT(0) -#define BSEC_MODE_FULLDBG_MASK BIT(1) -#define BSEC_MODE_INVALID_MASK BIT(2) -#define BSEC_MODE_BUSY_MASK BIT(3) -#define BSEC_MODE_PROGFAIL_MASK BIT(4) -#define BSEC_MODE_PWR_MASK BIT(5) -#define BSEC_MODE_BIST1_LOCK_MASK BIT(6) -#define BSEC_MODE_BIST2_LOCK_MASK BIT(7) +#define BSEC_OTP_STATUS_SECURE BIT(0) +#define BSEC_OTP_STATUS_INVALID BIT(2) +#define BSEC_OTP_STATUS_BUSY BIT(3) +#define BSEC_OTP_STATUS_PROGFAIL BIT(4) +#define BSEC_OTP_STATUS_PWRON BIT(5) /* BSEC_DENABLE Register */ #define BSEC_HDPEN BIT(4) #define BSEC_SPIDEN BIT(5) #define BSEC_SPINDEN BIT(6) #define BSEC_DBGSWGEN BIT(10) -#define BSEC_DEN_ALL_MSK GENMASK(10, 0) /* BSEC_FENABLE Register */ #define BSEC_FEN_ALL_MSK GENMASK(14, 0) diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c index 1fb44b487..7cc001382 100644 --- a/plat/st/stm32mp1/services/bsec_svc.c +++ b/plat/st/stm32mp1/services/bsec_svc.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved + * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ -#include #include #include #include +#include #include #include "bsec_svc.h" @@ -39,12 +39,7 @@ uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3, break; } - result = bsec_shadow_register(x2); - if (result != BSEC_OK) { - break; - } - - result = bsec_read_otp(ret_otp_value, x2); + result = bsec_shadow_read_otp(ret_otp_value, x2); if (result != BSEC_OK) { break; }