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