Home | History | Annotate | Download | only in tzc
      1 /*
      2  * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #ifndef __TZC_COMMON_PRIVATE_H__
      8 #define __TZC_COMMON_PRIVATE_H__
      9 
     10 #include <arch.h>
     11 #include <arch_helpers.h>
     12 #include <mmio.h>
     13 #include <tzc_common.h>
     14 
     15 #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name)		\
     16 	static inline void _tzc##fn_name##_write_action(		\
     17 					uintptr_t base,			\
     18 					tzc_action_t action)		\
     19 	{								\
     20 		mmio_write_32(base + TZC_##macro_name##_ACTION_OFF,	\
     21 			action);					\
     22 	}
     23 
     24 #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name)	\
     25 	static inline void _tzc##fn_name##_write_region_base(		\
     26 					uintptr_t base,			\
     27 					int region_no,			\
     28 					unsigned long long region_base)	\
     29 	{								\
     30 		mmio_write_32(base +					\
     31 			TZC_REGION_OFFSET(				\
     32 				TZC_##macro_name##_REGION_SIZE,		\
     33 				region_no) +				\
     34 			TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET,	\
     35 			(uint32_t)region_base);				\
     36 		mmio_write_32(base +					\
     37 			TZC_REGION_OFFSET(				\
     38 				TZC_##macro_name##_REGION_SIZE,		\
     39 				region_no) +				\
     40 			TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET,	\
     41 			(uint32_t)(region_base >> 32));			\
     42 	}
     43 
     44 #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name)		\
     45 	static inline void _tzc##fn_name##_write_region_top(		\
     46 					uintptr_t base,			\
     47 					int region_no,			\
     48 					unsigned long long region_top)	\
     49 	{								\
     50 		mmio_write_32(base +					\
     51 			TZC_REGION_OFFSET				\
     52 				(TZC_##macro_name##_REGION_SIZE,	\
     53 				region_no) +				\
     54 			TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET,	\
     55 			(uint32_t)region_top);			\
     56 		mmio_write_32(base +					\
     57 			TZC_REGION_OFFSET(				\
     58 				TZC_##macro_name##_REGION_SIZE,		\
     59 				region_no) +				\
     60 			TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET,	\
     61 			(uint32_t)(region_top >> 32));		\
     62 	}
     63 
     64 #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name)	\
     65 	static inline void _tzc##fn_name##_write_region_attributes(	\
     66 						uintptr_t base,		\
     67 						int region_no,		\
     68 						unsigned int attr)	\
     69 	{								\
     70 		mmio_write_32(base +					\
     71 			TZC_REGION_OFFSET(				\
     72 				TZC_##macro_name##_REGION_SIZE,		\
     73 				region_no) +				\
     74 			TZC_##macro_name##_REGION_ATTR_0_OFFSET,	\
     75 			attr);						\
     76 	}
     77 
     78 #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name)	\
     79 	static inline void _tzc##fn_name##_write_region_id_access(	\
     80 						uintptr_t base,		\
     81 						int region_no,		\
     82 						unsigned int val)	\
     83 	{								\
     84 		mmio_write_32(base +					\
     85 			TZC_REGION_OFFSET(				\
     86 				TZC_##macro_name##_REGION_SIZE,		\
     87 				region_no) +				\
     88 			TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET,	\
     89 			val);						\
     90 	}
     91 
     92 /*
     93  * It is used to program region 0 ATTRIBUTES and ACCESS register.
     94  */
     95 #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name)			\
     96 	void _tzc##fn_name##_configure_region0(uintptr_t base,		\
     97 			   tzc_region_attributes_t sec_attr,		\
     98 			   unsigned int ns_device_access)		\
     99 	{								\
    100 		assert(base);						\
    101 		VERBOSE("TrustZone : Configuring region 0 "		\
    102 			"(TZC Interface Base=%p sec_attr=0x%x,"		\
    103 			" ns_devs=0x%x)\n", (void *)base,		\
    104 			sec_attr, ns_device_access);			\
    105 									\
    106 		/* Set secure attributes on region 0 */			\
    107 		_tzc##fn_name##_write_region_attributes(base, 0,	\
    108 			sec_attr << TZC_REGION_ATTR_SEC_SHIFT);		\
    109 									\
    110 		/***************************************************/	\
    111 		/* Specify which non-secure devices have permission*/	\
    112 		/* to access region 0.				   */	\
    113 		/***************************************************/	\
    114 		_tzc##fn_name##_write_region_id_access(base,		\
    115 						0,			\
    116 						ns_device_access);	\
    117 	}
    118 
    119 /*
    120  * It is used to program a region from 1 to 8 in the TrustZone controller.
    121  * NOTE:
    122  * Region 0 is special; it is preferable to use
    123  * ##fn_name##_configure_region0 for this region (see comment for
    124  * that function).
    125  */
    126 #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name)			\
    127 	void _tzc##fn_name##_configure_region(uintptr_t base,		\
    128 				unsigned int filters,			\
    129 				int region_no,				\
    130 				unsigned long long region_base,		\
    131 				unsigned long long region_top,		\
    132 				tzc_region_attributes_t sec_attr,	\
    133 				unsigned int nsaid_permissions)	\
    134 	{								\
    135 		assert(base);						\
    136 		VERBOSE("TrustZone : Configuring region "		\
    137 			"(TZC Interface Base: %p, region_no = %d)"	\
    138 			"...\n", (void *)base, region_no);		\
    139 		VERBOSE("TrustZone : ... base = %llx, top = %llx,"	\
    140 			"\n", region_base, region_top);\
    141 		VERBOSE("TrustZone : ... sec_attr = 0x%x,"		\
    142 			" ns_devs = 0x%x)\n",				\
    143 			sec_attr, nsaid_permissions);			\
    144 									\
    145 		/***************************************************/	\
    146 		/* Inputs look ok, start programming registers.    */	\
    147 		/* All the address registers are 32 bits wide and  */	\
    148 		/* have a LOW and HIGH				   */	\
    149 		/* component used to construct an address up to a  */	\
    150 		/* 64bit.					   */	\
    151 		/***************************************************/	\
    152 		_tzc##fn_name##_write_region_base(base,			\
    153 					region_no, region_base);	\
    154 		_tzc##fn_name##_write_region_top(base,			\
    155 					region_no, region_top);		\
    156 									\
    157 		/* Enable filter to the region and set secure attributes */\
    158 		_tzc##fn_name##_write_region_attributes(base,		\
    159 				region_no,				\
    160 				(sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\
    161 				(filters << TZC_REGION_ATTR_F_EN_SHIFT));\
    162 									\
    163 		/***************************************************/	\
    164 		/* Specify which non-secure devices have permission*/	\
    165 		/* to access this region.			   */	\
    166 		/***************************************************/	\
    167 		_tzc##fn_name##_write_region_id_access(base,		\
    168 						region_no,		\
    169 						nsaid_permissions);	\
    170 	}
    171 
    172 #if ENABLE_ASSERTIONS
    173 
    174 static inline unsigned int _tzc_read_peripheral_id(uintptr_t base)
    175 {
    176 	unsigned int id;
    177 
    178 	id = mmio_read_32(base + PID0_OFF);
    179 	/* Masks DESC part in PID1 */
    180 	id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8);
    181 
    182 	return id;
    183 }
    184 
    185 #ifdef AARCH32
    186 static inline unsigned long long _tzc_get_max_top_addr(int addr_width)
    187 {
    188 	/*
    189 	 * Assume at least 32 bit wide address and initialize the max.
    190 	 * This function doesn't use 64-bit integer arithmetic to avoid
    191 	 * having to implement additional compiler library functions.
    192 	 */
    193 	unsigned long long addr_mask = 0xFFFFFFFF;
    194 	uint32_t *addr_ptr = (uint32_t *)&addr_mask;
    195 
    196 	assert(addr_width >= 32);
    197 
    198 	/* This logic works only on little - endian platforms */
    199 	assert((read_sctlr() & SCTLR_EE_BIT) == 0);
    200 
    201 	/*
    202 	 * If required address width is greater than 32, populate the higher
    203 	 * 32 bits of the 64 bit field with the max address.
    204 	 */
    205 	if (addr_width > 32)
    206 		*(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1);
    207 
    208 	return addr_mask;
    209 }
    210 #else
    211 #define _tzc_get_max_top_addr(addr_width)\
    212 	(UINT64_MAX >> (64 - (addr_width)))
    213 #endif /* AARCH32 */
    214 
    215 #endif /* ENABLE_ASSERTIONS */
    216 
    217 #endif /* __TZC_COMMON_PRIVATE_H__ */
    218