Commit 443b88f3332e74361adce52294bb31557ca30fa5
1 parent
5f20cc02b0
Exists in
smarc_8mm-imx_v2019.04_4.19.35_1.1.0
and in
1 other branch
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 */ |