xref: /rk3399_ARM-atf/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c (revision 7c4e1eea61a32291a6640070418e07ab98b42442)
1 /*
2  * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 #include <emi_mpu.h>
9 #include <mtk_sip_svc.h>
10 
11 #define MPU_PHYSICAL_ADDR_SHIFT_BITS	(16)
12 
13 void set_emi_mpu_regions(void)
14 {
15 	struct emi_region_info_t region_info;
16 
17 	/* BL31 address */
18 	region_info.start = TZRAM_BASE;
19 	region_info.end = TZRAM_BASE + TZRAM_SIZE - 1;
20 	region_info.region = BL31_EMI_REGION_ID;
21 	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
22 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
23 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
24 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
25 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
26 	emi_mpu_set_protection(&region_info);
27 
28 	/* BL32 address */
29 	region_info.start = BL32_REGION_BASE;
30 	region_info.end = BL32_REGION_BASE + BL32_REGION_SIZE - 1;
31 	region_info.region = BL32_REGION_ID;
32 	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
33 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
34 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
35 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
36 			      FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
37 	emi_mpu_set_protection(&region_info);
38 
39 	/* SCP core0 DRAM */
40 	region_info.start = SCP_CORE0_REGION_BASE;
41 	region_info.end = SCP_CORE0_REGION_BASE + SCP_CORE0_REGION_SIZE - 1;
42 	region_info.region = SCP_CORE0_REGION_ID;
43 	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
44 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
45 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
46 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
47 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
48 	emi_mpu_set_protection(&region_info);
49 
50 	/* SCP core1 DRAM */
51 	region_info.start = SCP_CORE1_REGION_BASE;
52 	region_info.end = SCP_CORE1_REGION_BASE + SCP_CORE1_REGION_SIZE - 1;
53 	region_info.region = SCP_CORE1_REGION_ID;
54 	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
55 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
56 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
57 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
58 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
59 	emi_mpu_set_protection(&region_info);
60 
61 	/* DSP protect address */
62 	region_info.start = DSP_PROTECT_REGION_BASE;
63 	region_info.end = DSP_PROTECT_REGION_BASE + DSP_PROTECT_REGION_SIZE - 1;
64 	region_info.region = DSP_PROTECT_REGION_ID;
65 	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
66 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
67 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
68 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
69 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
70 	emi_mpu_set_protection(&region_info);
71 
72 	/* All default settings */
73 	region_info.start = DRAM_START_ADDR;
74 	region_info.end = DRAM_START_ADDR + DRAM_MAX_SIZE - 1;
75 	region_info.region = ALL_DEFAULT_REGION_ID;
76 	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
77 			      FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
78 			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
79 			      NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN,
80 			      NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION);
81 	emi_mpu_set_protection(&region_info);
82 }
83 
84 int set_apu_emi_mpu_region(void)
85 {
86 	struct emi_region_info_t region_info;
87 
88 	region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA;
89 	region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1;
90 	region_info.region = APUSYS_SEC_BUF_EMI_REGION_ID;
91 
92 	SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
93 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
94 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
95 			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, FORBIDDEN,
96 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     SEC_RW);
97 
98 	return emi_mpu_set_protection(&region_info);
99 }
100 
101 static inline uint64_t get_decoded_phys_addr(uint64_t addr)
102 {
103 	return (addr << MPU_PHYSICAL_ADDR_SHIFT_BITS);
104 }
105 
106 static inline uint32_t get_decoded_zone_id(uint32_t info)
107 {
108 	return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
109 }
110 
111 static inline uint32_t get_decoded_set_clear_info(uint32_t info)
112 {
113 	return (info & 0x0000FFFF);
114 }
115 
116 int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
117 						  uint64_t zone_info)
118 {
119 	uint64_t phys_addr = get_decoded_phys_addr(encoded_addr);
120 	struct emi_region_info_t region_info;
121 	enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info);
122 	uint32_t is_set = get_decoded_set_clear_info(zone_info);
123 
124 	INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
125 	     encoded_addr, zone_size, zone_info);
126 
127 	if (zone_id != MPU_REQ_ORIGIN_TEE_ZONE_SVP) {
128 		ERROR("Invalid param %s, %d\n", __func__, __LINE__);
129 		return MTK_SIP_E_INVALID_PARAM;
130 	}
131 
132 	if (is_set > 0) {
133 		/* SVP DRAM */
134 		region_info.start = phys_addr;
135 		region_info.end = phys_addr + zone_size - 1;
136 		region_info.region = SVP_DRAM_REGION_ID;
137 		SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
138 					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
139 					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
140 					  FORBIDDEN, SEC_RW, FORBIDDEN, FORBIDDEN,
141 					  FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
142 
143 		emi_mpu_set_protection(&region_info);
144 	} else { /* clear region protection */
145 		emi_mpu_clear_protection(SVP_DRAM_REGION_ID);
146 	}
147 
148 	return 0;
149 }
150