Commit 443b88f3332e74361adce52294bb31557ca30fa5

Authored by Ye Li
1 parent 5f20cc02b0

MLK-22749 imx8mq: Add workaround to fix sticky bits lock up

On B1 chips with HAB v4.4, the sticky bits are not locked up in
HAB closed mode. We introduce a workaround in SPL to lock up
these bits and clear Manufacturing Protection Private Key for
secure boot.

For field return case, user has to build a SPL with
CONFIG_SECURE_STICKY_BITS_LOCKUP=n and set CONFIG_IMX_UNIQUE_ID to
part's unique id. When the UID check is passed, sticky bits are not
lockup and users can burn field return fuse. Otherwise the boot will
stop.

Signed-off-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit c98b47f1ff60e1f99807e24fd76053ad880f803e)

Showing 2 changed files with 64 additions and 0 deletions Side-by-side Diff

arch/arm/mach-imx/imx8m/Kconfig
... ... @@ -21,6 +21,16 @@
21 21 bool
22 22 select IMX8M
23 23  
  24 +config SECURE_STICKY_BITS_LOCKUP
  25 + bool "Enable workaround to fix sticky bits lock up issue"
  26 + depends on IMX8MQ && SECURE_BOOT
  27 + default y
  28 +
  29 +config IMX_UNIQUE_ID
  30 + hex "Enable workaround to fix sticky bits lock up issue"
  31 + depends on IMX8MQ && SECURE_BOOT && !SECURE_STICKY_BITS_LOCKUP
  32 + default 0x0
  33 +
24 34 choice
25 35 prompt "NXP i.MX8M board select"
26 36 optional
arch/arm/mach-imx/imx8m/soc.c
... ... @@ -21,6 +21,7 @@
21 21 #include <imx_sip.h>
22 22 #include <generated/version_autogenerated.h>
23 23 #include <asm/setup.h>
  24 +#include <asm/bootm.h>
24 25 #ifdef CONFIG_IMX_SEC_INIT
25 26 #include <fsl_caam.h>
26 27 #endif
... ... @@ -279,6 +280,56 @@
279 280 writew(enable, &wdog3->wmcr);
280 281 }
281 282  
  283 +#ifdef CONFIG_SECURE_BOOT
  284 +static bool is_hdmi_fused(void) {
  285 + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  286 + struct fuse_bank *bank = &ocotp->bank[1];
  287 + struct fuse_bank1_regs *fuse =
  288 + (struct fuse_bank1_regs *)bank->fuse_regs;
  289 +
  290 + u32 value = readl(&fuse->tester4);
  291 +
  292 + if (is_imx8mq()) {
  293 + if (value & 0x02000000)
  294 + return true;
  295 + }
  296 +
  297 + return false;
  298 +}
  299 +
  300 +bool is_uid_matched(u64 uid) {
  301 + struct tag_serialnr nr;
  302 + get_board_serial(&nr);
  303 +
  304 + if (lower_32_bits(uid) == nr.low &&
  305 + upper_32_bits(uid) == nr.high)
  306 + return true;
  307 +
  308 + return false;
  309 +}
  310 +
  311 +static void secure_lockup(void)
  312 +{
  313 + if (is_imx8mq() && is_soc_rev(CHIP_REV_2_1) &&
  314 + imx_hab_is_enabled() && !is_hdmi_fused()) {
  315 +#ifdef CONFIG_SECURE_STICKY_BITS_LOCKUP
  316 + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  317 +
  318 + clock_enable(CCGR_OCOTP, 1);
  319 + setbits_le32(&ocotp->sw_sticky, 0x6); /* Lock up field return and SRK revoke */
  320 + writel(0x80000000, &ocotp->scs_set); /* Lock up SCS */
  321 +
  322 + /* Clear mfg prot private key in CAAM */
  323 + setbits_le32((ulong)(CONFIG_SYS_FSL_SEC_ADDR + 0xc), 0x08000000);
  324 +#else
  325 + /* Check the Unique ID, if it is matched with UID config, then allow to leave sticky bits unlocked */
  326 + if (!is_uid_matched(CONFIG_IMX_UNIQUE_ID))
  327 + hang();
  328 +#endif
  329 + }
  330 +}
  331 +#endif
  332 +
282 333 int arch_cpu_init(void)
283 334 {
284 335 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
... ... @@ -294,6 +345,9 @@
294 345 clock_init();
295 346 imx_set_wdog_powerdown(false);
296 347  
  348 +#ifdef CONFIG_SECURE_BOOT
  349 + secure_lockup();
  350 +#endif
297 351 if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() || is_imx8mmsl() ||
298 352 is_imx8mnd() || is_imx8mndl() || is_imx8mns() || is_imx8mnsl()) {
299 353 /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */