xref: /rk3399_ARM-atf/plat/mediatek/drivers/emi/emi_ctrl.c (revision 52e486f6a6192bd18d36cdcbc35c59092eefc810)
1 /*
2  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 
9 #include <lib/mtk_init/mtk_init.h>
10 #include <mtk_bl31_interface.h>
11 #include <mtk_sip_svc.h>
12 
13 #define NO_PROTECTION	0
14 #define SEC_RW		1
15 #define SEC_RW_NSEC_R	2
16 #define SEC_RW_NSEC_W	3
17 #define SEC_R_NSEC_R	4
18 #define FORBIDDEN	5
19 #define SEC_R_NSEC_RW	6
20 
21 #define EMIMPU_SET	0
22 #define EMIMPU_CLEAR	1
23 #define EMIMPU_READ	2
24 #define EMIMPU_SLVERR	3
25 #define EMIDBG_DUMP	4
26 #define EMIDBG_MSG	5
27 #define AID_TABLE_SET	6
28 #define EMIMPU_CLEAR_MD	7
29 #define KP_SET		8
30 #define KP_CLEAR	9
31 
32 #define EMIMPU_READ_SA			0
33 #define EMIMPU_READ_EA			1
34 #define EMIMPU_READ_APC			2
35 #define EMIMPU_READ_ENABLE		3
36 #define EMIMPU_READ_AID			4
37 #define EMIMPU_CHECK_NS_CPU		5
38 #define EMIMPU_CHECK_REGION_INFO	6
39 #define EMIMPU_PAGE_BASE_REGION		7
40 #define SLBMPU_CLEAR			8
41 #define EMIMPU_CHECK_HP_MOD		9
42 #define EMI_CLE				10
43 #define SLC_PARITY_SELECT		11
44 #define SLC_PARITY_CLEAR		12
45 
46 static uint64_t emi_mpu_read_by_type(unsigned int reg_type, unsigned int region,
47 				     unsigned int aid_shift, struct smccc_res *smccc_ret)
48 {
49 	switch (reg_type) {
50 	case EMIMPU_READ_SA:
51 		return emi_mpu_read_addr(region, 0x0);
52 	case EMIMPU_READ_EA:
53 		return emi_mpu_read_addr(region, 0x8);
54 	case EMIMPU_READ_ENABLE:
55 		return emi_mpu_read_enable(region);
56 	case EMIMPU_READ_AID:
57 		return emi_mpu_read_aid(region, aid_shift);
58 	case EMIMPU_CHECK_REGION_INFO:
59 		return emi_mpu_check_region_info(region, &smccc_ret->a1, &smccc_ret->a2);
60 	case EMIMPU_CHECK_NS_CPU:
61 		return emi_mpu_check_ns_cpu();
62 	case EMIMPU_PAGE_BASE_REGION:
63 		return emi_mpu_page_base_region();
64 	case EMIMPU_CHECK_HP_MOD:
65 		return emi_mpu_smc_hp_mod_check();
66 	default:
67 		return 0;
68 	}
69 }
70 
71 static u_register_t sip_emidbg_control(u_register_t op_id,
72 				       u_register_t x2,
73 				       u_register_t x3,
74 				       u_register_t x4,
75 				       void *handle,
76 				       struct smccc_res *smccc_ret)
77 {
78 	enum mtk_bl31_status ret;
79 
80 	switch (op_id) {
81 	case EMIDBG_DUMP:
82 		return MTK_SIP_E_SUCCESS;
83 	case EMIDBG_MSG:
84 		return MTK_SIP_E_SUCCESS;
85 #ifdef MTK_EMI_MPU_DEBUG
86 	case EMIMPU_READ:
87 		ret = emi_mpu_read_by_type((unsigned int)x2, (unsigned int)x3,
88 					   (unsigned int)x4, smccc_ret);
89 		break;
90 #endif
91 	case EMIMPU_CLEAR_MD:
92 		ret = emi_clear_md_violation();
93 		break;
94 	case KP_CLEAR:
95 		ret = emi_kp_clear_violation((unsigned int)x2);
96 		break;
97 #ifdef CONFIG_MTK_SLB_MPU_CLEAR
98 	case SLBMPU_CLEAR:
99 		ret = slb_clear_violation((unsigned int)x2);
100 		break;
101 #endif
102 #ifdef CONFIG_MTK_EMI_CLEAR
103 	case EMI_CLEAR:
104 		ret = emi_clear_violation((unsigned int)x2, (unsigned int)x3);
105 		break;
106 #endif
107 #ifdef CONFIG_MTK_SLC_PARITY
108 	case SLC_PARITY_SELECT:
109 		ret = slc_parity_select((unsigned int)x2, (unsigned int)x3);
110 		break;
111 	case SLC_PARITY_CLEAR:
112 		ret = slc_parity_clear((unsigned int)x2);
113 		break;
114 #endif
115 	default:
116 		return MTK_SIP_E_NOT_SUPPORTED;
117 	}
118 
119 	return mtk_bl31_map_to_sip_error(ret);
120 }
121 DECLARE_SMC_HANDLER(MTK_SIP_EMIDBG_CONTROL, sip_emidbg_control);
122 
123 static u_register_t sip_emimpu_control(u_register_t op_id,
124 				       u_register_t x2,
125 				       u_register_t x3,
126 				       u_register_t x4,
127 				       void *handle,
128 				       struct smccc_res *smccc_ret)
129 {
130 	enum mtk_bl31_status ret;
131 
132 	switch (op_id) {
133 	case EMIMPU_SET:
134 		ret = emi_mpu_set_protection((uint32_t)x2, (uint32_t)x3, (unsigned int)x4);
135 		break;
136 	case AID_TABLE_SET:
137 		ret = emi_mpu_set_aid((unsigned int)x2, (unsigned int)x3);
138 		break;
139 	case EMIMPU_READ:
140 		ret = emi_mpu_read_by_type((unsigned int)x2, (unsigned int)x3,
141 					   (unsigned int)x4, smccc_ret);
142 		break;
143 	case KP_SET:
144 		ret = emi_kp_set_protection((size_t)x2, (size_t)x3, (unsigned int)x4);
145 		break;
146 	case KP_CLEAR:
147 		ret = emi_kp_clear_violation((unsigned int)x2);
148 		break;
149 	default:
150 		return MTK_SIP_E_NOT_SUPPORTED;
151 	}
152 
153 	return mtk_bl31_map_to_sip_error(ret);
154 }
155 DECLARE_SMC_HANDLER(MTK_SIP_BL_EMIMPU_CONTROL, sip_emimpu_control);
156 
157 static u_register_t sip_tee_emimpu_control(u_register_t op_id,
158 					   u_register_t x2,
159 					   u_register_t x3,
160 					   u_register_t x4,
161 					   void *handle,
162 					   struct smccc_res *smccc_ret)
163 {
164 	enum mtk_bl31_status ret;
165 
166 	switch (op_id) {
167 	case EMIMPU_SET:
168 		ret = emi_mpu_set_protection((uint32_t)x2, (uint32_t)x3, (unsigned int)x4);
169 		break;
170 	case EMIMPU_CLEAR:
171 		ret = emi_clear_protection((unsigned int)x2);
172 		break;
173 	default:
174 		return MTK_SIP_E_NOT_SUPPORTED;
175 	}
176 
177 	return mtk_bl31_map_to_sip_error(ret);
178 }
179 DECLARE_SMC_HANDLER(MTK_SIP_TEE_EMI_MPU_CONTROL, sip_tee_emimpu_control);
180 
181 int emi_mpu_init(void)
182 {
183 	INFO("[%s] emi mpu initialization\n", __func__);
184 
185 	emi_protection_init();
186 
187 	return 0;
188 }
189 MTK_PLAT_SETUP_0_INIT(emi_mpu_init);
190