Browse Source

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 <patrick.delaunay@foss.st.com>
Signed-off-by: Yann Gautier <yann.gautier@st.com>
pull/1999/merge
Patrick Delaunay 2 years ago
committed by Yann Gautier
parent
commit
c706104507
  1. 330
      drivers/st/bsec/bsec2.c
  2. 102
      include/drivers/st/bsec.h
  3. 17
      include/drivers/st/bsec2_reg.h
  4. 11
      plat/st/stm32mp1/services/bsec_svc.c

330
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)
{
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)
static uint32_t bsec_get_status(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;
}

102
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 <lib/utils_def.h>
/*
* 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
*/
#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
* 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 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 */

17
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)

11
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 <platform_def.h>
#include <common/debug.h>
#include <drivers/st/bsec.h>
#include <drivers/st/bsec2_reg.h>
#include <platform_def.h>
#include <stm32mp1_smc.h>
#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;
}

Loading…
Cancel
Save