1 /* 2 * Copyright (c) 2016-2021, 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 <drivers/arm/tzc_common.h> 13 #include <lib/mmio.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 unsigned int 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 unsigned 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 (u_register_t)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 (u_register_t)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 unsigned 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 (u_register_t)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 (u_register_t)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 unsigned int region_no, \ 68 unsigned int attr) \ 69 { \ 70 mmio_write_32(base + \ 71 TZC_REGION_OFFSET( \ 72 TZC_##macro_name##_REGION_SIZE, \ 73 (u_register_t)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 unsigned int region_no, \ 82 unsigned int val) \ 83 { \ 84 mmio_write_32(base + \ 85 TZC_REGION_OFFSET( \ 86 TZC_##macro_name##_REGION_SIZE, \ 87 (u_register_t)region_no) + \ 88 TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \ 89 val); \ 90 } 91 92 /* 93 * It is used to modify the filters status for a defined region. 94 */ 95 #define DEFINE_TZC_COMMON_UPDATE_FILTERS(fn_name, macro_name) \ 96 static inline void _tzc##fn_name##_update_filters( \ 97 uintptr_t base, \ 98 unsigned int region_no, \ 99 unsigned int nbfilters, \ 100 unsigned int filters) \ 101 { \ 102 uint32_t filters_mask = GENMASK(nbfilters - 1U, 0); \ 103 \ 104 mmio_clrsetbits_32(base + \ 105 TZC_REGION_OFFSET( \ 106 TZC_##macro_name##_REGION_SIZE, \ 107 region_no) + \ 108 TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ 109 filters_mask << TZC_REGION_ATTR_F_EN_SHIFT, \ 110 filters << TZC_REGION_ATTR_F_EN_SHIFT); \ 111 } 112 113 /* 114 * It is used to program region 0 ATTRIBUTES and ACCESS register. 115 */ 116 #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \ 117 static void _tzc##fn_name##_configure_region0(uintptr_t base, \ 118 unsigned int sec_attr, \ 119 unsigned int ns_device_access) \ 120 { \ 121 assert(base != 0U); \ 122 VERBOSE("TrustZone : Configuring region 0 " \ 123 "(TZC Interface Base=0x%lx sec_attr=0x%x," \ 124 " ns_devs=0x%x)\n", base, \ 125 sec_attr, ns_device_access); \ 126 \ 127 /* Set secure attributes on region 0 */ \ 128 _tzc##fn_name##_write_region_attributes(base, 0, \ 129 sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \ 130 \ 131 /***************************************************/ \ 132 /* Specify which non-secure devices have permission*/ \ 133 /* to access region 0. */ \ 134 /***************************************************/ \ 135 _tzc##fn_name##_write_region_id_access(base, \ 136 0, \ 137 ns_device_access); \ 138 } 139 140 /* 141 * It is used to program a region from 1 to 8 in the TrustZone controller. 142 * NOTE: 143 * Region 0 is special; it is preferable to use 144 * ##fn_name##_configure_region0 for this region (see comment for 145 * that function). 146 */ 147 #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \ 148 static void _tzc##fn_name##_configure_region(uintptr_t base, \ 149 unsigned int filters, \ 150 unsigned int region_no, \ 151 unsigned long long region_base, \ 152 unsigned long long region_top, \ 153 unsigned int sec_attr, \ 154 unsigned int nsaid_permissions) \ 155 { \ 156 assert(base != 0U); \ 157 VERBOSE("TrustZone : Configuring region " \ 158 "(TZC Interface Base: 0x%lx, region_no = %u)" \ 159 "...\n", base, region_no); \ 160 VERBOSE("TrustZone : ... base = %llx, top = %llx," \ 161 "\n", region_base, region_top); \ 162 VERBOSE("TrustZone : ... sec_attr = 0x%x," \ 163 " ns_devs = 0x%x)\n", \ 164 sec_attr, nsaid_permissions); \ 165 \ 166 /***************************************************/ \ 167 /* Inputs look ok, start programming registers. */ \ 168 /* All the address registers are 32 bits wide and */ \ 169 /* have a LOW and HIGH */ \ 170 /* component used to construct an address up to a */ \ 171 /* 64bit. */ \ 172 /***************************************************/ \ 173 _tzc##fn_name##_write_region_base(base, \ 174 region_no, region_base); \ 175 _tzc##fn_name##_write_region_top(base, \ 176 region_no, region_top); \ 177 \ 178 /* Enable filter to the region and set secure attributes */\ 179 _tzc##fn_name##_write_region_attributes(base, \ 180 region_no, \ 181 (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\ 182 (filters << TZC_REGION_ATTR_F_EN_SHIFT));\ 183 \ 184 /***************************************************/ \ 185 /* Specify which non-secure devices have permission*/ \ 186 /* to access this region. */ \ 187 /***************************************************/ \ 188 _tzc##fn_name##_write_region_id_access(base, \ 189 region_no, \ 190 nsaid_permissions); \ 191 } 192 193 static inline unsigned int _tzc_read_peripheral_id(uintptr_t base) 194 { 195 unsigned int id; 196 197 id = mmio_read_32(base + PID0_OFF); 198 /* Masks DESC part in PID1 */ 199 id |= ((mmio_read_32(base + PID1_OFF) & 0xFU) << 8U); 200 201 return id; 202 } 203 204 #endif /* TZC_COMMON_PRIVATE_H */ 205