xref: /rk3399_ARM-atf/drivers/arm/tzc/tzc_common_private.h (revision abd2aba99ef108e0d0bb5d71c0b6e9c47ca26377)
1 /*
2  * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef __TZC_COMMON_PRIVATE_H__
32 #define __TZC_COMMON_PRIVATE_H__
33 
34 #include <arch.h>
35 #include <arch_helpers.h>
36 #include <mmio.h>
37 #include <tzc_common.h>
38 
39 #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name)		\
40 	static inline void _tzc##fn_name##_write_action(		\
41 					uintptr_t base,			\
42 					tzc_action_t action)		\
43 	{								\
44 		mmio_write_32(base + TZC_##macro_name##_ACTION_OFF,	\
45 			action);					\
46 	}
47 
48 #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name)	\
49 	static inline void _tzc##fn_name##_write_region_base(		\
50 					uintptr_t base,			\
51 					int region_no,			\
52 					unsigned long long region_base)	\
53 	{								\
54 		mmio_write_32(base +					\
55 			TZC_REGION_OFFSET(				\
56 				TZC_##macro_name##_REGION_SIZE,		\
57 				region_no) +				\
58 			TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET,	\
59 			(uint32_t)region_base);				\
60 		mmio_write_32(base +					\
61 			TZC_REGION_OFFSET(				\
62 				TZC_##macro_name##_REGION_SIZE,		\
63 				region_no) +				\
64 			TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET,	\
65 			(uint32_t)(region_base >> 32));			\
66 	}
67 
68 #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name)		\
69 	static inline void _tzc##fn_name##_write_region_top(		\
70 					uintptr_t base,			\
71 					int region_no,			\
72 					unsigned long long region_top)	\
73 	{								\
74 		mmio_write_32(base +					\
75 			TZC_REGION_OFFSET				\
76 				(TZC_##macro_name##_REGION_SIZE,	\
77 				region_no) +				\
78 			TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET,	\
79 			(uint32_t)region_top);			\
80 		mmio_write_32(base +					\
81 			TZC_REGION_OFFSET(				\
82 				TZC_##macro_name##_REGION_SIZE,		\
83 				region_no) +				\
84 			TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET,	\
85 			(uint32_t)(region_top >> 32));		\
86 	}
87 
88 #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name)	\
89 	static inline void _tzc##fn_name##_write_region_attributes(	\
90 						uintptr_t base,		\
91 						int region_no,		\
92 						unsigned int attr)	\
93 	{								\
94 		mmio_write_32(base +					\
95 			TZC_REGION_OFFSET(				\
96 				TZC_##macro_name##_REGION_SIZE,		\
97 				region_no) +				\
98 			TZC_##macro_name##_REGION_ATTR_0_OFFSET,	\
99 			attr);						\
100 	}
101 
102 #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name)	\
103 	static inline void _tzc##fn_name##_write_region_id_access(	\
104 						uintptr_t base,		\
105 						int region_no,		\
106 						unsigned int val)	\
107 	{								\
108 		mmio_write_32(base +					\
109 			TZC_REGION_OFFSET(				\
110 				TZC_##macro_name##_REGION_SIZE,		\
111 				region_no) +				\
112 			TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET,	\
113 			val);						\
114 	}
115 
116 /*
117  * It is used to program region 0 ATTRIBUTES and ACCESS register.
118  */
119 #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name)			\
120 	void _tzc##fn_name##_configure_region0(uintptr_t base,		\
121 			   tzc_region_attributes_t sec_attr,		\
122 			   unsigned int ns_device_access)		\
123 	{								\
124 		assert(base);						\
125 		VERBOSE("TrustZone : Configuring region 0 "		\
126 			"(TZC Interface Base=%p sec_attr=0x%x,"		\
127 			" ns_devs=0x%x)\n", (void *)base,		\
128 			sec_attr, ns_device_access);			\
129 									\
130 		/* Set secure attributes on region 0 */			\
131 		_tzc##fn_name##_write_region_attributes(base, 0,	\
132 			sec_attr << TZC_REGION_ATTR_SEC_SHIFT);		\
133 									\
134 		/***************************************************/	\
135 		/* Specify which non-secure devices have permission*/	\
136 		/* to access region 0.				   */	\
137 		/***************************************************/	\
138 		_tzc##fn_name##_write_region_id_access(base,		\
139 						0,			\
140 						ns_device_access);	\
141 	}
142 
143 /*
144  * It is used to program a region from 1 to 8 in the TrustZone controller.
145  * NOTE:
146  * Region 0 is special; it is preferable to use
147  * ##fn_name##_configure_region0 for this region (see comment for
148  * that function).
149  */
150 #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name)			\
151 	void _tzc##fn_name##_configure_region(uintptr_t base,		\
152 				unsigned int filters,			\
153 				int region_no,				\
154 				unsigned long long region_base,		\
155 				unsigned long long region_top,		\
156 				tzc_region_attributes_t sec_attr,	\
157 				unsigned int nsaid_permissions)	\
158 	{								\
159 		assert(base);						\
160 		VERBOSE("TrustZone : Configuring region "		\
161 			"(TZC Interface Base: %p, region_no = %d)"	\
162 			"...\n", (void *)base, region_no);		\
163 		VERBOSE("TrustZone : ... base = %llx, top = %llx,"	\
164 			"\n", region_base, region_top);\
165 		VERBOSE("TrustZone : ... sec_attr = 0x%x,"		\
166 			" ns_devs = 0x%x)\n",				\
167 			sec_attr, nsaid_permissions);			\
168 									\
169 		/***************************************************/	\
170 		/* Inputs look ok, start programming registers.    */	\
171 		/* All the address registers are 32 bits wide and  */	\
172 		/* have a LOW and HIGH				   */	\
173 		/* component used to construct an address up to a  */	\
174 		/* 64bit.					   */	\
175 		/***************************************************/	\
176 		_tzc##fn_name##_write_region_base(base,			\
177 					region_no, region_base);	\
178 		_tzc##fn_name##_write_region_top(base,			\
179 					region_no, region_top);		\
180 									\
181 		/* Enable filter to the region and set secure attributes */\
182 		_tzc##fn_name##_write_region_attributes(base,		\
183 				region_no,				\
184 				(sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\
185 				(filters << TZC_REGION_ATTR_F_EN_SHIFT));\
186 									\
187 		/***************************************************/	\
188 		/* Specify which non-secure devices have permission*/	\
189 		/* to access this region.			   */	\
190 		/***************************************************/	\
191 		_tzc##fn_name##_write_region_id_access(base,		\
192 						region_no,		\
193 						nsaid_permissions);	\
194 	}
195 
196 #if ENABLE_ASSERTIONS
197 
198 static inline unsigned int _tzc_read_peripheral_id(uintptr_t base)
199 {
200 	unsigned int id;
201 
202 	id = mmio_read_32(base + PID0_OFF);
203 	/* Masks DESC part in PID1 */
204 	id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8);
205 
206 	return id;
207 }
208 
209 #ifdef AARCH32
210 static inline unsigned long long _tzc_get_max_top_addr(int addr_width)
211 {
212 	/*
213 	 * Assume at least 32 bit wide address and initialize the max.
214 	 * This function doesn't use 64-bit integer arithmetic to avoid
215 	 * having to implement additional compiler library functions.
216 	 */
217 	unsigned long long addr_mask = 0xFFFFFFFF;
218 	uint32_t *addr_ptr = (uint32_t *)&addr_mask;
219 
220 	assert(addr_width >= 32);
221 
222 	/* This logic works only on little - endian platforms */
223 	assert((read_sctlr() & SCTLR_EE_BIT) == 0);
224 
225 	/*
226 	 * If required address width is greater than 32, populate the higher
227 	 * 32 bits of the 64 bit field with the max address.
228 	 */
229 	if (addr_width > 32)
230 		*(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1);
231 
232 	return addr_mask;
233 }
234 #else
235 #define _tzc_get_max_top_addr(addr_width)\
236 	(UINT64_MAX >> (64 - (addr_width)))
237 #endif /* AARCH32 */
238 
239 #endif /* ENABLE_ASSERTIONS */
240 
241 #endif /* __TZC_COMMON_PRIVATE_H__ */
242