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