xref: /optee_os/core/drivers/imx_snvs.c (revision 916e56edb0be783873e4c3974d1e3e5cd6b15fe5)
11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2c6ac89bcSPeng Fan /*
3599784c7SRouven Czerwinski  * Copyright (C) 2020 Pengutronix
4599784c7SRouven Czerwinski  * Rouven Czerwinski <entwicklung@pengutronix.de>
5*916e56edSClement Faure  * Copyright 2022 NXP
6c6ac89bcSPeng Fan  */
7c6ac89bcSPeng Fan 
8c6ac89bcSPeng Fan #include <io.h>
9c6ac89bcSPeng Fan #include <mm/core_memprot.h>
10c6ac89bcSPeng Fan #include <mm/core_mmu.h>
11c6ac89bcSPeng Fan #include <stdint.h>
12*916e56edSClement Faure #include <tee/tee_fs.h>
13c6ac89bcSPeng Fan #include <types_ext.h>
14c6ac89bcSPeng Fan #include <trace.h>
15c6ac89bcSPeng Fan 
16*916e56edSClement Faure #define SNVS_HPSR 0x14
17*916e56edSClement Faure 
18*916e56edSClement Faure #define HPSR_SSM_ST_MASK  GENMASK_32(11, 8)
19*916e56edSClement Faure #define HPSR_SSM_ST_SHIFT 8
20*916e56edSClement Faure 
21*916e56edSClement Faure #define SNVS_HPSR_SYS_SECURITY_BAD    BIT(14)
22*916e56edSClement Faure #define SNVS_HPSR_SYS_SECURITY_CLOSED BIT(13)
23*916e56edSClement Faure #define SNVS_HPSR_SYS_SECURITY_OPEN   BIT(12)
24*916e56edSClement Faure 
25*916e56edSClement Faure enum snvs_ssm_mode {
26*916e56edSClement Faure 	SNVS_SSM_MODE_INIT,
27*916e56edSClement Faure 	SNVS_SSM_MODE_HARD_FAIL,
28*916e56edSClement Faure 	SNVS_SSM_MODE_SOFT_FAIL = 3,
29*916e56edSClement Faure 	SNVS_SSM_MODE_INIT_INTERMEDIATE = 8,
30*916e56edSClement Faure 	SNVS_SSM_MODE_CHECK,
31*916e56edSClement Faure 	SNVS_SSM_MODE_NON_SECURE = 11,
32*916e56edSClement Faure 	SNVS_SSM_MODE_TRUSTED = 13,
33*916e56edSClement Faure 	SNVS_SSM_MODE_SECURE,
34*916e56edSClement Faure };
35*916e56edSClement Faure 
36*916e56edSClement Faure enum snvs_security_cfg {
37*916e56edSClement Faure 	SNVS_SECURITY_CFG_FAB,
38*916e56edSClement Faure 	SNVS_SECURITY_CFG_OPEN,
39*916e56edSClement Faure 	SNVS_SECURITY_CFG_CLOSED,
40*916e56edSClement Faure 	SNVS_SECURITY_CFG_FIELD_RETURN,
41*916e56edSClement Faure };
42*916e56edSClement Faure 
43*916e56edSClement Faure #ifdef CFG_RPMB_FS
44*916e56edSClement Faure static enum snvs_security_cfg snvs_get_security_cfg(void)
45c6ac89bcSPeng Fan {
46c2e4eb43SAnton Rybakov 	vaddr_t snvs = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC,
47c2e4eb43SAnton Rybakov 				       SNVS_HPSR + sizeof(uint32_t));
48599784c7SRouven Czerwinski 	uint32_t val = 0;
49c6ac89bcSPeng Fan 
50599784c7SRouven Czerwinski 	val = io_read32(snvs + SNVS_HPSR);
51599784c7SRouven Czerwinski 	DMSG("HPSR: 0x%"PRIx32, val);
52599784c7SRouven Czerwinski 	if (val & SNVS_HPSR_SYS_SECURITY_BAD)
53599784c7SRouven Czerwinski 		return SNVS_SECURITY_CFG_FIELD_RETURN;
54599784c7SRouven Czerwinski 	else if (val & SNVS_HPSR_SYS_SECURITY_CLOSED)
55599784c7SRouven Czerwinski 		return SNVS_SECURITY_CFG_CLOSED;
56599784c7SRouven Czerwinski 	else if (val & SNVS_HPSR_SYS_SECURITY_OPEN)
57599784c7SRouven Czerwinski 		return SNVS_SECURITY_CFG_OPEN;
58599784c7SRouven Czerwinski 	else if (val > 4 && val < 8)
59599784c7SRouven Czerwinski 		return SNVS_SECURITY_CFG_OPEN;
60c6ac89bcSPeng Fan 
61599784c7SRouven Czerwinski 	return SNVS_SECURITY_CFG_FAB;
62c6ac89bcSPeng Fan }
63c6ac89bcSPeng Fan 
64*916e56edSClement Faure static enum snvs_ssm_mode snvs_get_ssm_mode(void)
65c6ac89bcSPeng Fan {
66c2e4eb43SAnton Rybakov 	vaddr_t snvs = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC,
67c2e4eb43SAnton Rybakov 				       SNVS_HPSR + sizeof(uint32_t));
68599784c7SRouven Czerwinski 	uint32_t val = 0;
69c6ac89bcSPeng Fan 
70599784c7SRouven Czerwinski 	val = io_read32(snvs + SNVS_HPSR);
71599784c7SRouven Czerwinski 	val &= HPSR_SSM_ST_MASK;
72599784c7SRouven Czerwinski 	val = val >> HPSR_SSM_ST_SHIFT;
73599784c7SRouven Czerwinski 	DMSG("HPSR: SSM ST Mode: 0x%01"PRIx32, val);
74599784c7SRouven Czerwinski 	return val;
75c6ac89bcSPeng Fan }
76*916e56edSClement Faure 
77*916e56edSClement Faure bool plat_rpmb_key_is_ready(void)
78*916e56edSClement Faure {
79*916e56edSClement Faure 	enum snvs_ssm_mode mode = SNVS_SSM_MODE_INIT;
80*916e56edSClement Faure 	enum snvs_security_cfg security = SNVS_SECURITY_CFG_OPEN;
81*916e56edSClement Faure 	bool ssm_secure = false;
82*916e56edSClement Faure 
83*916e56edSClement Faure 	mode = snvs_get_ssm_mode();
84*916e56edSClement Faure 	security = snvs_get_security_cfg();
85*916e56edSClement Faure 	ssm_secure = (mode == SNVS_SSM_MODE_TRUSTED ||
86*916e56edSClement Faure 		      mode == SNVS_SSM_MODE_SECURE);
87*916e56edSClement Faure 
88*916e56edSClement Faure 	/*
89*916e56edSClement Faure 	 * On i.MX6SDL and i.MX6DQ, the security cfg always returns
90*916e56edSClement Faure 	 * SNVS_SECURITY_CFG_FAB (000), therefore we ignore the security
91*916e56edSClement Faure 	 * configuration for this SoC.
92*916e56edSClement Faure 	 */
93*916e56edSClement Faure 	if (soc_is_imx6sdl() || soc_is_imx6dq())
94*916e56edSClement Faure 		return ssm_secure;
95*916e56edSClement Faure 
96*916e56edSClement Faure 	return ssm_secure && (security == SNVS_SECURITY_CFG_CLOSED);
97*916e56edSClement Faure }
98*916e56edSClement Faure #endif /* CFG_RPMB_FS */
99