From 443b88f3332e74361adce52294bb31557ca30fa5 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 26 Aug 2019 23:39:57 -0700 Subject: [PATCH] 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 (cherry picked from commit c98b47f1ff60e1f99807e24fd76053ad880f803e) --- arch/arm/mach-imx/imx8m/Kconfig | 10 ++++++ arch/arm/mach-imx/imx8m/soc.c | 54 +++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index a970127fd8..4c0d8cb041 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -21,6 +21,16 @@ config IMX8MN bool select IMX8M +config SECURE_STICKY_BITS_LOCKUP + bool "Enable workaround to fix sticky bits lock up issue" + depends on IMX8MQ && SECURE_BOOT + default y + +config IMX_UNIQUE_ID + hex "Enable workaround to fix sticky bits lock up issue" + depends on IMX8MQ && SECURE_BOOT && !SECURE_STICKY_BITS_LOCKUP + default 0x0 + choice prompt "NXP i.MX8M board select" optional diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 668498a77d..4c2cbee92c 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_IMX_SEC_INIT #include #endif @@ -279,6 +280,56 @@ static void imx_set_wdog_powerdown(bool enable) writew(enable, &wdog3->wmcr); } +#ifdef CONFIG_SECURE_BOOT +static bool is_hdmi_fused(void) { + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[1]; + struct fuse_bank1_regs *fuse = + (struct fuse_bank1_regs *)bank->fuse_regs; + + u32 value = readl(&fuse->tester4); + + if (is_imx8mq()) { + if (value & 0x02000000) + return true; + } + + return false; +} + +bool is_uid_matched(u64 uid) { + struct tag_serialnr nr; + get_board_serial(&nr); + + if (lower_32_bits(uid) == nr.low && + upper_32_bits(uid) == nr.high) + return true; + + return false; +} + +static void secure_lockup(void) +{ + if (is_imx8mq() && is_soc_rev(CHIP_REV_2_1) && + imx_hab_is_enabled() && !is_hdmi_fused()) { +#ifdef CONFIG_SECURE_STICKY_BITS_LOCKUP + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + + clock_enable(CCGR_OCOTP, 1); + setbits_le32(&ocotp->sw_sticky, 0x6); /* Lock up field return and SRK revoke */ + writel(0x80000000, &ocotp->scs_set); /* Lock up SCS */ + + /* Clear mfg prot private key in CAAM */ + setbits_le32((ulong)(CONFIG_SYS_FSL_SEC_ADDR + 0xc), 0x08000000); +#else + /* Check the Unique ID, if it is matched with UID config, then allow to leave sticky bits unlocked */ + if (!is_uid_matched(CONFIG_IMX_UNIQUE_ID)) + hang(); +#endif + } +} +#endif + int arch_cpu_init(void) { struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; @@ -294,6 +345,9 @@ int arch_cpu_init(void) clock_init(); imx_set_wdog_powerdown(false); +#ifdef CONFIG_SECURE_BOOT + secure_lockup(); +#endif if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() || is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() || is_imx8mnsl()) { /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */ -- 2.17.1