RE: [PATCH 04/10] arm: stm32mp: bsec: add permanent lock support in bsec driver
Hi, > From: Patrick DELAUNAY > Sent: mercredi 12 février 2020 19:38 > > Add BSEC lock access (read / write) at 0xC000 offset of misc driver. > The write access only available for Trusted boot mode, based on new SMC > STM32_SMC_WRLOCK_OTP. > > With the fuse command, the permanent lock status is accessed with > 0x1000 offset (0xC000 - 0x800 for OTP sense/program divided by > u32 size), for example: > > Read lock status of fuse 57 (0x39) > > STM32MP> fuse sense 0 0x1039 1 > > Sensing bank 0: > > Word 0x1039: > > Set permanent lock of fuse 57 (0x39) > > STM32MP> fuse prog 0 0x1039 1 > > Sensing bank 0: > > Word 0x1039: > > WARNING: the OTP lock is updated only after reboot > > WARING: Programming lock or fuses is an irreversible operation! > This may brick your system. > > Signed-off-by: Patrick Delaunay > --- Applied to u-boot-stm/next, thanks! Regards Patrick
Re: [PATCH 04/10] arm: stm32mp: bsec: add permanent lock support in bsec driver
On 2/12/20 7:37 PM, Patrick Delaunay wrote: > Add BSEC lock access (read / write) at 0xC000 offset of misc driver. > The write access only available for Trusted boot mode, based on new > SMC STM32_SMC_WRLOCK_OTP. > > With the fuse command, the permanent lock status is accessed with > 0x1000 offset (0xC000 - 0x800 for OTP sense/program > divided by u32 size), for example: > > Read lock status of fuse 57 (0x39) > > STM32MP> fuse sense 0 0x1039 1 > > Sensing bank 0: > > Word 0x1039: > > Set permanent lock of fuse 57 (0x39) > > STM32MP> fuse prog 0 0x1039 1 > > Sensing bank 0: > > Word 0x1039: > > WARNING: the OTP lock is updated only after reboot > > WARING: Programming lock or fuses is an irreversible operation! > This may brick your system. > > Signed-off-by: Patrick Delaunay > --- > > arch/arm/mach-stm32mp/bsec.c | 88 +-- > arch/arm/mach-stm32mp/cpu.c | 6 -- > arch/arm/mach-stm32mp/include/mach/stm32.h| 9 +- > .../mach-stm32mp/include/mach/stm32mp1_smc.h | 1 + > doc/board/st/stm32mp1.rst | 34 --- > 5 files changed, 95 insertions(+), 43 deletions(-) > > diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c > index 1d904caae1..3b923f088e 100644 > --- a/arch/arm/mach-stm32mp/bsec.c > +++ b/arch/arm/mach-stm32mp/bsec.c > @@ -12,8 +12,6 @@ > #include > > #define BSEC_OTP_MAX_VALUE 95 > - > -#ifndef CONFIG_STM32MP1_TRUSTED > #define BSEC_TIMEOUT_US 1 > > /* BSEC REGISTER OFFSET (base relative) */ > @@ -24,9 +22,10 @@ > #define BSEC_OTP_LOCK_OFF0x010 > #define BSEC_DISTURBED_OFF 0x01C > #define BSEC_ERROR_OFF 0x034 > -#define BSEC_SPLOCK_OFF 0x064 /* Program safmem sticky > lock */ > -#define BSEC_SWLOCK_OFF 0x07C /* write in OTP sticky > lock */ > -#define BSEC_SRLOCK_OFF 0x094 /* shadowing sticky lock > */ > +#define BSEC_WRLOCK_OFF 0x04C /* OTP write permananet > lock */ > +#define BSEC_SPLOCK_OFF 0x064 /* OTP write sticky lock > */ > +#define BSEC_SWLOCK_OFF 0x07C /* shadow write sticky > lock */ > +#define BSEC_SRLOCK_OFF 0x094 /* shadow read sticky > lock */ > #define BSEC_OTP_DATA_OFF0x200 > > /* BSEC_CONFIGURATION Register MASK */ > @@ -53,12 +52,12 @@ > #define BSEC_LOCK_PROGRAM0x04 > > /** > - * bsec_check_error() - Check status of one otp > - * @base: base address of bsec IP > + * bsec_lock() - manage lock for each type SR/SP/SW > + * @address: address of bsec IP register > * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) > - * Return: 0 if no error, -EAGAIN or -ENOTSUPP > + * Return: true if locked else false > */ > -static u32 bsec_check_error(u32 base, u32 otp) > +static bool bsec_read_lock(u32 address, u32 otp) > { > u32 bit; > u32 bank; > @@ -66,21 +65,17 @@ static u32 bsec_check_error(u32 base, u32 otp) > bit = 1 << (otp & OTP_LOCK_MASK); > bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32); > > - if (readl(base + BSEC_DISTURBED_OFF + bank) & bit) > - return -EAGAIN; > - else if (readl(base + BSEC_ERROR_OFF + bank) & bit) > - return -ENOTSUPP; > - > - return 0; > + return !!(readl(address + bank) & bit); > } > > +#ifndef CONFIG_STM32MP1_TRUSTED > /** > - * bsec_lock() - manage lock for each type SR/SP/SW > - * @address: address of bsec IP register > + * bsec_check_error() - Check status of one otp > + * @base: base address of bsec IP > * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) > - * Return: true if locked else false > + * Return: 0 if no error, -EAGAIN or -ENOTSUPP > */ > -static bool bsec_read_lock(u32 address, u32 otp) > +static u32 bsec_check_error(u32 base, u32 otp) > { > u32 bit; > u32 bank; > @@ -88,7 +83,12 @@ static bool bsec_read_lock(u32 address, u32 otp) > bit = 1 << (otp & OTP_LOCK_MASK); > bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32); > > - return !!(readl(address + bank) & bit); > + if (readl(base + BSEC_DISTURBED_OFF + bank) & bit) > + return -EAGAIN; > + else if (readl(base + BSEC_ERROR_OFF + bank) & bit) > + return -ENOTSUPP; > + > + return 0; > } > > /** > @@ -324,6 +324,16 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, > u32 *val, u32 otp) > #endif > } > > +static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp) > +{ > + struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); > + > + /* return OTP permanent write lock status */ > + *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp); > + > + return 0; > +} > + > static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp) >
[PATCH 04/10] arm: stm32mp: bsec: add permanent lock support in bsec driver
Add BSEC lock access (read / write) at 0xC000 offset of misc driver. The write access only available for Trusted boot mode, based on new SMC STM32_SMC_WRLOCK_OTP. With the fuse command, the permanent lock status is accessed with 0x1000 offset (0xC000 - 0x800 for OTP sense/program divided by u32 size), for example: Read lock status of fuse 57 (0x39) STM32MP> fuse sense 0 0x1039 1 Sensing bank 0: Word 0x1039: Set permanent lock of fuse 57 (0x39) STM32MP> fuse prog 0 0x1039 1 Sensing bank 0: Word 0x1039: WARNING: the OTP lock is updated only after reboot WARING: Programming lock or fuses is an irreversible operation! This may brick your system. Signed-off-by: Patrick Delaunay --- arch/arm/mach-stm32mp/bsec.c | 88 +-- arch/arm/mach-stm32mp/cpu.c | 6 -- arch/arm/mach-stm32mp/include/mach/stm32.h| 9 +- .../mach-stm32mp/include/mach/stm32mp1_smc.h | 1 + doc/board/st/stm32mp1.rst | 34 --- 5 files changed, 95 insertions(+), 43 deletions(-) diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index 1d904caae1..3b923f088e 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -12,8 +12,6 @@ #include #define BSEC_OTP_MAX_VALUE 95 - -#ifndef CONFIG_STM32MP1_TRUSTED #define BSEC_TIMEOUT_US1 /* BSEC REGISTER OFFSET (base relative) */ @@ -24,9 +22,10 @@ #define BSEC_OTP_LOCK_OFF 0x010 #define BSEC_DISTURBED_OFF 0x01C #define BSEC_ERROR_OFF 0x034 -#define BSEC_SPLOCK_OFF0x064 /* Program safmem sticky lock */ -#define BSEC_SWLOCK_OFF0x07C /* write in OTP sticky lock */ -#define BSEC_SRLOCK_OFF0x094 /* shadowing sticky lock */ +#define BSEC_WRLOCK_OFF0x04C /* OTP write permananet lock */ +#define BSEC_SPLOCK_OFF0x064 /* OTP write sticky lock */ +#define BSEC_SWLOCK_OFF0x07C /* shadow write sticky lock */ +#define BSEC_SRLOCK_OFF0x094 /* shadow read sticky lock */ #define BSEC_OTP_DATA_OFF 0x200 /* BSEC_CONFIGURATION Register MASK */ @@ -53,12 +52,12 @@ #define BSEC_LOCK_PROGRAM 0x04 /** - * bsec_check_error() - Check status of one otp - * @base: base address of bsec IP + * bsec_lock() - manage lock for each type SR/SP/SW + * @address: address of bsec IP register * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) - * Return: 0 if no error, -EAGAIN or -ENOTSUPP + * Return: true if locked else false */ -static u32 bsec_check_error(u32 base, u32 otp) +static bool bsec_read_lock(u32 address, u32 otp) { u32 bit; u32 bank; @@ -66,21 +65,17 @@ static u32 bsec_check_error(u32 base, u32 otp) bit = 1 << (otp & OTP_LOCK_MASK); bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32); - if (readl(base + BSEC_DISTURBED_OFF + bank) & bit) - return -EAGAIN; - else if (readl(base + BSEC_ERROR_OFF + bank) & bit) - return -ENOTSUPP; - - return 0; + return !!(readl(address + bank) & bit); } +#ifndef CONFIG_STM32MP1_TRUSTED /** - * bsec_lock() - manage lock for each type SR/SP/SW - * @address: address of bsec IP register + * bsec_check_error() - Check status of one otp + * @base: base address of bsec IP * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) - * Return: true if locked else false + * Return: 0 if no error, -EAGAIN or -ENOTSUPP */ -static bool bsec_read_lock(u32 address, u32 otp) +static u32 bsec_check_error(u32 base, u32 otp) { u32 bit; u32 bank; @@ -88,7 +83,12 @@ static bool bsec_read_lock(u32 address, u32 otp) bit = 1 << (otp & OTP_LOCK_MASK); bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32); - return !!(readl(address + bank) & bit); + if (readl(base + BSEC_DISTURBED_OFF + bank) & bit) + return -EAGAIN; + else if (readl(base + BSEC_ERROR_OFF + bank) & bit) + return -ENOTSUPP; + + return 0; } /** @@ -324,6 +324,16 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) #endif } +static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp) +{ + struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); + + /* return OTP permanent write lock status */ + *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp); + + return 0; +} + static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp) { #ifdef CONFIG_STM32MP1_TRUSTED @@ -350,17 +360,36 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp) #endif } +static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp) +{ +#ifdef CONFIG_STM32MP1_TRUSTED +