xref: /arm-trusted-firmware/drivers/arm/tzc/tzc_common_private.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #ifndef TZC_COMMON_PRIVATE_H
8*91f16700Schasinglulu #define TZC_COMMON_PRIVATE_H
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <arch.h>
11*91f16700Schasinglulu #include <arch_helpers.h>
12*91f16700Schasinglulu #include <drivers/arm/tzc_common.h>
13*91f16700Schasinglulu #include <lib/mmio.h>
14*91f16700Schasinglulu 
15*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name)		\
16*91f16700Schasinglulu 	static inline void _tzc##fn_name##_write_action(		\
17*91f16700Schasinglulu 					uintptr_t base,			\
18*91f16700Schasinglulu 					unsigned int action)		\
19*91f16700Schasinglulu 	{								\
20*91f16700Schasinglulu 		mmio_write_32(base + TZC_##macro_name##_ACTION_OFF,	\
21*91f16700Schasinglulu 			action);					\
22*91f16700Schasinglulu 	}
23*91f16700Schasinglulu 
24*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name)	\
25*91f16700Schasinglulu 	static inline void _tzc##fn_name##_write_region_base(		\
26*91f16700Schasinglulu 					uintptr_t base,			\
27*91f16700Schasinglulu 					unsigned int region_no,		\
28*91f16700Schasinglulu 					unsigned long long region_base)	\
29*91f16700Schasinglulu 	{								\
30*91f16700Schasinglulu 		mmio_write_32(base +					\
31*91f16700Schasinglulu 			TZC_REGION_OFFSET(				\
32*91f16700Schasinglulu 				TZC_##macro_name##_REGION_SIZE,		\
33*91f16700Schasinglulu 				(u_register_t)region_no) +		\
34*91f16700Schasinglulu 			TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET,	\
35*91f16700Schasinglulu 			(uint32_t)region_base);				\
36*91f16700Schasinglulu 		mmio_write_32(base +					\
37*91f16700Schasinglulu 			TZC_REGION_OFFSET(				\
38*91f16700Schasinglulu 				TZC_##macro_name##_REGION_SIZE,		\
39*91f16700Schasinglulu 				(u_register_t)region_no) +		\
40*91f16700Schasinglulu 			TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET,	\
41*91f16700Schasinglulu 			(uint32_t)(region_base >> 32));			\
42*91f16700Schasinglulu 	}
43*91f16700Schasinglulu 
44*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name)		\
45*91f16700Schasinglulu 	static inline void _tzc##fn_name##_write_region_top(		\
46*91f16700Schasinglulu 					uintptr_t base,			\
47*91f16700Schasinglulu 					unsigned int region_no,		\
48*91f16700Schasinglulu 					unsigned long long region_top)	\
49*91f16700Schasinglulu 	{								\
50*91f16700Schasinglulu 		mmio_write_32(base +					\
51*91f16700Schasinglulu 			TZC_REGION_OFFSET(				\
52*91f16700Schasinglulu 				TZC_##macro_name##_REGION_SIZE,		\
53*91f16700Schasinglulu 				(u_register_t)region_no) +		\
54*91f16700Schasinglulu 			TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET,	\
55*91f16700Schasinglulu 			(uint32_t)region_top);				\
56*91f16700Schasinglulu 		mmio_write_32(base +					\
57*91f16700Schasinglulu 			TZC_REGION_OFFSET(				\
58*91f16700Schasinglulu 				TZC_##macro_name##_REGION_SIZE,		\
59*91f16700Schasinglulu 				(u_register_t)region_no) +		\
60*91f16700Schasinglulu 			TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET,	\
61*91f16700Schasinglulu 			(uint32_t)(region_top >> 32));			\
62*91f16700Schasinglulu 	}
63*91f16700Schasinglulu 
64*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name)	\
65*91f16700Schasinglulu 	static inline void _tzc##fn_name##_write_region_attributes(	\
66*91f16700Schasinglulu 						uintptr_t base,		\
67*91f16700Schasinglulu 						unsigned int region_no,	\
68*91f16700Schasinglulu 						unsigned int attr)	\
69*91f16700Schasinglulu 	{								\
70*91f16700Schasinglulu 		mmio_write_32(base +					\
71*91f16700Schasinglulu 			TZC_REGION_OFFSET(				\
72*91f16700Schasinglulu 				TZC_##macro_name##_REGION_SIZE,		\
73*91f16700Schasinglulu 				(u_register_t)region_no) +		\
74*91f16700Schasinglulu 			TZC_##macro_name##_REGION_ATTR_0_OFFSET,	\
75*91f16700Schasinglulu 			attr);						\
76*91f16700Schasinglulu 	}
77*91f16700Schasinglulu 
78*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name)	\
79*91f16700Schasinglulu 	static inline void _tzc##fn_name##_write_region_id_access(	\
80*91f16700Schasinglulu 						uintptr_t base,		\
81*91f16700Schasinglulu 						unsigned int region_no,	\
82*91f16700Schasinglulu 						unsigned int val)	\
83*91f16700Schasinglulu 	{								\
84*91f16700Schasinglulu 		mmio_write_32(base +					\
85*91f16700Schasinglulu 			TZC_REGION_OFFSET(				\
86*91f16700Schasinglulu 				TZC_##macro_name##_REGION_SIZE,		\
87*91f16700Schasinglulu 				(u_register_t)region_no) +		\
88*91f16700Schasinglulu 			TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET,	\
89*91f16700Schasinglulu 			val);						\
90*91f16700Schasinglulu 	}
91*91f16700Schasinglulu 
92*91f16700Schasinglulu /*
93*91f16700Schasinglulu  * It is used to modify the filters status for a defined region.
94*91f16700Schasinglulu  */
95*91f16700Schasinglulu #define DEFINE_TZC_COMMON_UPDATE_FILTERS(fn_name, macro_name)		\
96*91f16700Schasinglulu 	static inline void _tzc##fn_name##_update_filters(		\
97*91f16700Schasinglulu 						uintptr_t base,		\
98*91f16700Schasinglulu 						unsigned int region_no,	\
99*91f16700Schasinglulu 						unsigned int nbfilters, \
100*91f16700Schasinglulu 						unsigned int filters)	\
101*91f16700Schasinglulu 	{								\
102*91f16700Schasinglulu 		uint32_t filters_mask = GENMASK(nbfilters - 1U, 0);	\
103*91f16700Schasinglulu 									\
104*91f16700Schasinglulu 		mmio_clrsetbits_32(base +				\
105*91f16700Schasinglulu 			TZC_REGION_OFFSET(				\
106*91f16700Schasinglulu 				TZC_##macro_name##_REGION_SIZE,		\
107*91f16700Schasinglulu 				region_no) +				\
108*91f16700Schasinglulu 			TZC_##macro_name##_REGION_ATTR_0_OFFSET,	\
109*91f16700Schasinglulu 			filters_mask << TZC_REGION_ATTR_F_EN_SHIFT,	\
110*91f16700Schasinglulu 			filters << TZC_REGION_ATTR_F_EN_SHIFT);		\
111*91f16700Schasinglulu 	}
112*91f16700Schasinglulu 
113*91f16700Schasinglulu /*
114*91f16700Schasinglulu  * It is used to program region 0 ATTRIBUTES and ACCESS register.
115*91f16700Schasinglulu  */
116*91f16700Schasinglulu #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name)			\
117*91f16700Schasinglulu 	static void _tzc##fn_name##_configure_region0(uintptr_t base,	\
118*91f16700Schasinglulu 			   unsigned int sec_attr,			\
119*91f16700Schasinglulu 			   unsigned int ns_device_access)		\
120*91f16700Schasinglulu 	{								\
121*91f16700Schasinglulu 		assert(base != 0U);					\
122*91f16700Schasinglulu 		VERBOSE("TrustZone : Configuring region 0 "		\
123*91f16700Schasinglulu 			"(TZC Interface Base=0x%lx sec_attr=0x%x,"	\
124*91f16700Schasinglulu 			" ns_devs=0x%x)\n", base,			\
125*91f16700Schasinglulu 			sec_attr, ns_device_access);			\
126*91f16700Schasinglulu 									\
127*91f16700Schasinglulu 		/* Set secure attributes on region 0 */			\
128*91f16700Schasinglulu 		_tzc##fn_name##_write_region_attributes(base, 0,	\
129*91f16700Schasinglulu 			sec_attr << TZC_REGION_ATTR_SEC_SHIFT);		\
130*91f16700Schasinglulu 									\
131*91f16700Schasinglulu 		/***************************************************/	\
132*91f16700Schasinglulu 		/* Specify which non-secure devices have permission*/	\
133*91f16700Schasinglulu 		/* to access region 0.				   */	\
134*91f16700Schasinglulu 		/***************************************************/	\
135*91f16700Schasinglulu 		_tzc##fn_name##_write_region_id_access(base,		\
136*91f16700Schasinglulu 						0,			\
137*91f16700Schasinglulu 						ns_device_access);	\
138*91f16700Schasinglulu 	}
139*91f16700Schasinglulu 
140*91f16700Schasinglulu /*
141*91f16700Schasinglulu  * It is used to program a region from 1 to 8 in the TrustZone controller.
142*91f16700Schasinglulu  * NOTE:
143*91f16700Schasinglulu  * Region 0 is special; it is preferable to use
144*91f16700Schasinglulu  * ##fn_name##_configure_region0 for this region (see comment for
145*91f16700Schasinglulu  * that function).
146*91f16700Schasinglulu  */
147*91f16700Schasinglulu #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name)			\
148*91f16700Schasinglulu 	static void _tzc##fn_name##_configure_region(uintptr_t base,	\
149*91f16700Schasinglulu 				unsigned int filters,			\
150*91f16700Schasinglulu 				unsigned int region_no,			\
151*91f16700Schasinglulu 				unsigned long long region_base,		\
152*91f16700Schasinglulu 				unsigned long long region_top,		\
153*91f16700Schasinglulu 				unsigned int sec_attr,			\
154*91f16700Schasinglulu 				unsigned int nsaid_permissions)		\
155*91f16700Schasinglulu 	{								\
156*91f16700Schasinglulu 		assert(base != 0U);					\
157*91f16700Schasinglulu 		VERBOSE("TrustZone : Configuring region "		\
158*91f16700Schasinglulu 			"(TZC Interface Base: 0x%lx, region_no = %u)"	\
159*91f16700Schasinglulu 			"...\n", base, region_no);			\
160*91f16700Schasinglulu 		VERBOSE("TrustZone : ... base = %llx, top = %llx,"	\
161*91f16700Schasinglulu 			"\n", region_base, region_top);			\
162*91f16700Schasinglulu 		VERBOSE("TrustZone : ... sec_attr = 0x%x,"		\
163*91f16700Schasinglulu 			" ns_devs = 0x%x)\n",				\
164*91f16700Schasinglulu 			sec_attr, nsaid_permissions);			\
165*91f16700Schasinglulu 									\
166*91f16700Schasinglulu 		/***************************************************/	\
167*91f16700Schasinglulu 		/* Inputs look ok, start programming registers.    */	\
168*91f16700Schasinglulu 		/* All the address registers are 32 bits wide and  */	\
169*91f16700Schasinglulu 		/* have a LOW and HIGH				   */	\
170*91f16700Schasinglulu 		/* component used to construct an address up to a  */	\
171*91f16700Schasinglulu 		/* 64bit.					   */	\
172*91f16700Schasinglulu 		/***************************************************/	\
173*91f16700Schasinglulu 		_tzc##fn_name##_write_region_base(base,			\
174*91f16700Schasinglulu 					region_no, region_base);	\
175*91f16700Schasinglulu 		_tzc##fn_name##_write_region_top(base,			\
176*91f16700Schasinglulu 					region_no, region_top);		\
177*91f16700Schasinglulu 									\
178*91f16700Schasinglulu 		/* Enable filter to the region and set secure attributes */\
179*91f16700Schasinglulu 		_tzc##fn_name##_write_region_attributes(base,		\
180*91f16700Schasinglulu 				region_no,				\
181*91f16700Schasinglulu 				(sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\
182*91f16700Schasinglulu 				(filters << TZC_REGION_ATTR_F_EN_SHIFT));\
183*91f16700Schasinglulu 									\
184*91f16700Schasinglulu 		/***************************************************/	\
185*91f16700Schasinglulu 		/* Specify which non-secure devices have permission*/	\
186*91f16700Schasinglulu 		/* to access this region.			   */	\
187*91f16700Schasinglulu 		/***************************************************/	\
188*91f16700Schasinglulu 		_tzc##fn_name##_write_region_id_access(base,		\
189*91f16700Schasinglulu 						region_no,		\
190*91f16700Schasinglulu 						nsaid_permissions);	\
191*91f16700Schasinglulu 	}
192*91f16700Schasinglulu 
193*91f16700Schasinglulu static inline unsigned int _tzc_read_peripheral_id(uintptr_t base)
194*91f16700Schasinglulu {
195*91f16700Schasinglulu 	unsigned int id;
196*91f16700Schasinglulu 
197*91f16700Schasinglulu 	id = mmio_read_32(base + PID0_OFF);
198*91f16700Schasinglulu 	/* Masks DESC part in PID1 */
199*91f16700Schasinglulu 	id |= ((mmio_read_32(base + PID1_OFF) & 0xFU) << 8U);
200*91f16700Schasinglulu 
201*91f16700Schasinglulu 	return id;
202*91f16700Schasinglulu }
203*91f16700Schasinglulu 
204*91f16700Schasinglulu #endif /* TZC_COMMON_PRIVATE_H */
205