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