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