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