1 /* 2 * Copyright (c) 2016-2020, 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 program region 0 ATTRIBUTES and ACCESS register. 94 */ 95 #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \ 96 static void _tzc##fn_name##_configure_region0(uintptr_t base, \ 97 unsigned int sec_attr, \ 98 unsigned int ns_device_access) \ 99 { \ 100 assert(base != 0U); \ 101 VERBOSE("TrustZone : Configuring region 0 " \ 102 "(TZC Interface Base=0x%lx sec_attr=0x%x," \ 103 " ns_devs=0x%x)\n", 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 static void _tzc##fn_name##_configure_region(uintptr_t base, \ 128 unsigned int filters, \ 129 unsigned int region_no, \ 130 unsigned long long region_base, \ 131 unsigned long long region_top, \ 132 unsigned int sec_attr, \ 133 unsigned int nsaid_permissions) \ 134 { \ 135 assert(base != 0U); \ 136 VERBOSE("TrustZone : Configuring region " \ 137 "(TZC Interface Base: 0x%lx, region_no = %u)" \ 138 "...\n", 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 static inline unsigned int _tzc_read_peripheral_id(uintptr_t base) 173 { 174 unsigned int id; 175 176 id = mmio_read_32(base + PID0_OFF); 177 /* Masks DESC part in PID1 */ 178 id |= ((mmio_read_32(base + PID1_OFF) & 0xFU) << 8U); 179 180 return id; 181 } 182 183 #endif /* TZC_COMMON_PRIVATE_H */ 184