1239b085cSAntonio Nino Diaz /* 21af540efSRoberto Vargas * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. 3239b085cSAntonio Nino Diaz * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5239b085cSAntonio Nino Diaz */ 6239b085cSAntonio Nino Diaz 7*af6491f8SAntonio Nino Diaz #ifndef TZC_COMMON_PRIVATE_H 8*af6491f8SAntonio Nino Diaz #define TZC_COMMON_PRIVATE_H 9239b085cSAntonio Nino Diaz 10239b085cSAntonio Nino Diaz #include <arch.h> 11239b085cSAntonio Nino Diaz #include <arch_helpers.h> 12239b085cSAntonio Nino Diaz #include <mmio.h> 13239b085cSAntonio Nino Diaz #include <tzc_common.h> 14239b085cSAntonio Nino Diaz 15239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \ 16239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_action( \ 17239b085cSAntonio Nino Diaz uintptr_t base, \ 18*af6491f8SAntonio Nino Diaz unsigned int action) \ 19239b085cSAntonio Nino Diaz { \ 20239b085cSAntonio Nino Diaz mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \ 21239b085cSAntonio Nino Diaz action); \ 22239b085cSAntonio Nino Diaz } 23239b085cSAntonio Nino Diaz 24239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \ 25239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_base( \ 26239b085cSAntonio Nino Diaz uintptr_t base, \ 27*af6491f8SAntonio Nino Diaz unsigned int region_no, \ 28239b085cSAntonio Nino Diaz unsigned long long region_base) \ 29239b085cSAntonio Nino Diaz { \ 30239b085cSAntonio Nino Diaz mmio_write_32(base + \ 31239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 32239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 33239b085cSAntonio Nino Diaz region_no) + \ 34239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \ 35239b085cSAntonio Nino Diaz (uint32_t)region_base); \ 36239b085cSAntonio Nino Diaz mmio_write_32(base + \ 37239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 38239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 39239b085cSAntonio Nino Diaz region_no) + \ 40239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \ 41239b085cSAntonio Nino Diaz (uint32_t)(region_base >> 32)); \ 42239b085cSAntonio Nino Diaz } 43239b085cSAntonio Nino Diaz 44239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \ 45239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_top( \ 46239b085cSAntonio Nino Diaz uintptr_t base, \ 47*af6491f8SAntonio Nino Diaz unsigned int region_no, \ 48239b085cSAntonio Nino Diaz unsigned long long region_top) \ 49239b085cSAntonio Nino Diaz { \ 50239b085cSAntonio Nino Diaz mmio_write_32(base + \ 51239b085cSAntonio Nino Diaz TZC_REGION_OFFSET \ 52239b085cSAntonio Nino Diaz (TZC_##macro_name##_REGION_SIZE, \ 53239b085cSAntonio Nino Diaz region_no) + \ 54239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \ 55239b085cSAntonio Nino Diaz (uint32_t)region_top); \ 56239b085cSAntonio Nino Diaz mmio_write_32(base + \ 57239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 58239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 59239b085cSAntonio Nino Diaz region_no) + \ 60239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \ 61239b085cSAntonio Nino Diaz (uint32_t)(region_top >> 32)); \ 62239b085cSAntonio Nino Diaz } 63239b085cSAntonio Nino Diaz 64239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \ 65239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_attributes( \ 66239b085cSAntonio Nino Diaz uintptr_t base, \ 67*af6491f8SAntonio Nino Diaz unsigned int region_no, \ 68239b085cSAntonio Nino Diaz unsigned int attr) \ 69239b085cSAntonio Nino Diaz { \ 70239b085cSAntonio Nino Diaz mmio_write_32(base + \ 71239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 72239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 73239b085cSAntonio Nino Diaz region_no) + \ 74239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ 75239b085cSAntonio Nino Diaz attr); \ 76239b085cSAntonio Nino Diaz } 77239b085cSAntonio Nino Diaz 78239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \ 79239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_id_access( \ 80239b085cSAntonio Nino Diaz uintptr_t base, \ 81*af6491f8SAntonio Nino Diaz unsigned int region_no, \ 82239b085cSAntonio Nino Diaz unsigned int val) \ 83239b085cSAntonio Nino Diaz { \ 84239b085cSAntonio Nino Diaz mmio_write_32(base + \ 85239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 86239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 87239b085cSAntonio Nino Diaz region_no) + \ 88239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \ 89239b085cSAntonio Nino Diaz val); \ 90239b085cSAntonio Nino Diaz } 91239b085cSAntonio Nino Diaz 92239b085cSAntonio Nino Diaz /* 93239b085cSAntonio Nino Diaz * It is used to program region 0 ATTRIBUTES and ACCESS register. 94239b085cSAntonio Nino Diaz */ 95239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \ 961af540efSRoberto Vargas static void _tzc##fn_name##_configure_region0(uintptr_t base, \ 97*af6491f8SAntonio Nino Diaz unsigned int sec_attr, \ 98239b085cSAntonio Nino Diaz unsigned int ns_device_access) \ 99239b085cSAntonio Nino Diaz { \ 100*af6491f8SAntonio Nino Diaz assert(base != 0U); \ 101239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region 0 " \ 102*af6491f8SAntonio Nino Diaz "(TZC Interface Base=0x%lx sec_attr=0x%x," \ 103*af6491f8SAntonio Nino Diaz " ns_devs=0x%x)\n", base, \ 104239b085cSAntonio Nino Diaz sec_attr, ns_device_access); \ 105239b085cSAntonio Nino Diaz \ 106239b085cSAntonio Nino Diaz /* Set secure attributes on region 0 */ \ 107239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_attributes(base, 0, \ 108239b085cSAntonio Nino Diaz sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \ 109239b085cSAntonio Nino Diaz \ 110239b085cSAntonio Nino Diaz /***************************************************/ \ 111239b085cSAntonio Nino Diaz /* Specify which non-secure devices have permission*/ \ 112239b085cSAntonio Nino Diaz /* to access region 0. */ \ 113239b085cSAntonio Nino Diaz /***************************************************/ \ 114239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_id_access(base, \ 115239b085cSAntonio Nino Diaz 0, \ 116239b085cSAntonio Nino Diaz ns_device_access); \ 117239b085cSAntonio Nino Diaz } 118239b085cSAntonio Nino Diaz 119239b085cSAntonio Nino Diaz /* 120239b085cSAntonio Nino Diaz * It is used to program a region from 1 to 8 in the TrustZone controller. 121239b085cSAntonio Nino Diaz * NOTE: 122239b085cSAntonio Nino Diaz * Region 0 is special; it is preferable to use 123239b085cSAntonio Nino Diaz * ##fn_name##_configure_region0 for this region (see comment for 124239b085cSAntonio Nino Diaz * that function). 125239b085cSAntonio Nino Diaz */ 126239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \ 1271af540efSRoberto Vargas static void _tzc##fn_name##_configure_region(uintptr_t base, \ 128239b085cSAntonio Nino Diaz unsigned int filters, \ 129*af6491f8SAntonio Nino Diaz unsigned int region_no, \ 130239b085cSAntonio Nino Diaz unsigned long long region_base, \ 131239b085cSAntonio Nino Diaz unsigned long long region_top, \ 132*af6491f8SAntonio Nino Diaz unsigned int sec_attr, \ 133239b085cSAntonio Nino Diaz unsigned int nsaid_permissions) \ 134239b085cSAntonio Nino Diaz { \ 135*af6491f8SAntonio Nino Diaz assert(base != 0U); \ 136239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region " \ 137*af6491f8SAntonio Nino Diaz "(TZC Interface Base: 0x%lx, region_no = %u)" \ 138*af6491f8SAntonio Nino Diaz "...\n", base, region_no); \ 139239b085cSAntonio Nino Diaz VERBOSE("TrustZone : ... base = %llx, top = %llx," \ 140239b085cSAntonio Nino Diaz "\n", region_base, region_top); \ 141239b085cSAntonio Nino Diaz VERBOSE("TrustZone : ... sec_attr = 0x%x," \ 142239b085cSAntonio Nino Diaz " ns_devs = 0x%x)\n", \ 143239b085cSAntonio Nino Diaz sec_attr, nsaid_permissions); \ 144239b085cSAntonio Nino Diaz \ 145239b085cSAntonio Nino Diaz /***************************************************/ \ 146239b085cSAntonio Nino Diaz /* Inputs look ok, start programming registers. */ \ 147239b085cSAntonio Nino Diaz /* All the address registers are 32 bits wide and */ \ 148239b085cSAntonio Nino Diaz /* have a LOW and HIGH */ \ 149239b085cSAntonio Nino Diaz /* component used to construct an address up to a */ \ 150239b085cSAntonio Nino Diaz /* 64bit. */ \ 151239b085cSAntonio Nino Diaz /***************************************************/ \ 152239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_base(base, \ 153239b085cSAntonio Nino Diaz region_no, region_base); \ 154239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_top(base, \ 155239b085cSAntonio Nino Diaz region_no, region_top); \ 156239b085cSAntonio Nino Diaz \ 157239b085cSAntonio Nino Diaz /* Enable filter to the region and set secure attributes */\ 158239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_attributes(base, \ 159239b085cSAntonio Nino Diaz region_no, \ 160239b085cSAntonio Nino Diaz (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\ 161239b085cSAntonio Nino Diaz (filters << TZC_REGION_ATTR_F_EN_SHIFT));\ 162239b085cSAntonio Nino Diaz \ 163239b085cSAntonio Nino Diaz /***************************************************/ \ 164239b085cSAntonio Nino Diaz /* Specify which non-secure devices have permission*/ \ 165239b085cSAntonio Nino Diaz /* to access this region. */ \ 166239b085cSAntonio Nino Diaz /***************************************************/ \ 167239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_id_access(base, \ 168239b085cSAntonio Nino Diaz region_no, \ 169239b085cSAntonio Nino Diaz nsaid_permissions); \ 170239b085cSAntonio Nino Diaz } 171239b085cSAntonio Nino Diaz 172239b085cSAntonio Nino Diaz static inline unsigned int _tzc_read_peripheral_id(uintptr_t base) 173239b085cSAntonio Nino Diaz { 174239b085cSAntonio Nino Diaz unsigned int id; 175239b085cSAntonio Nino Diaz 176239b085cSAntonio Nino Diaz id = mmio_read_32(base + PID0_OFF); 177239b085cSAntonio Nino Diaz /* Masks DESC part in PID1 */ 178*af6491f8SAntonio Nino Diaz id |= ((mmio_read_32(base + PID1_OFF) & 0xFU) << 8U); 179239b085cSAntonio Nino Diaz 180239b085cSAntonio Nino Diaz return id; 181239b085cSAntonio Nino Diaz } 182239b085cSAntonio Nino Diaz 183806d9ad1SSoby Mathew #if ENABLE_ASSERTIONS 184239b085cSAntonio Nino Diaz #ifdef AARCH32 185*af6491f8SAntonio Nino Diaz static inline unsigned long long _tzc_get_max_top_addr(unsigned int addr_width) 186239b085cSAntonio Nino Diaz { 187239b085cSAntonio Nino Diaz /* 188239b085cSAntonio Nino Diaz * Assume at least 32 bit wide address and initialize the max. 189239b085cSAntonio Nino Diaz * This function doesn't use 64-bit integer arithmetic to avoid 190239b085cSAntonio Nino Diaz * having to implement additional compiler library functions. 191239b085cSAntonio Nino Diaz */ 192*af6491f8SAntonio Nino Diaz unsigned long long addr_mask = 0xFFFFFFFFU; 193239b085cSAntonio Nino Diaz uint32_t *addr_ptr = (uint32_t *)&addr_mask; 194239b085cSAntonio Nino Diaz 195*af6491f8SAntonio Nino Diaz assert(addr_width >= 32U); 196239b085cSAntonio Nino Diaz 197239b085cSAntonio Nino Diaz /* This logic works only on little - endian platforms */ 198*af6491f8SAntonio Nino Diaz assert((read_sctlr() & SCTLR_EE_BIT) == 0U); 199239b085cSAntonio Nino Diaz 200239b085cSAntonio Nino Diaz /* 201239b085cSAntonio Nino Diaz * If required address width is greater than 32, populate the higher 202239b085cSAntonio Nino Diaz * 32 bits of the 64 bit field with the max address. 203239b085cSAntonio Nino Diaz */ 204*af6491f8SAntonio Nino Diaz if (addr_width > 32U) 205*af6491f8SAntonio Nino Diaz *(addr_ptr + 1U) = ((1U << (addr_width - 32U)) - 1U); 206239b085cSAntonio Nino Diaz 207239b085cSAntonio Nino Diaz return addr_mask; 208239b085cSAntonio Nino Diaz } 209239b085cSAntonio Nino Diaz #else 210*af6491f8SAntonio Nino Diaz static inline unsigned long long _tzc_get_max_top_addr(unsigned int addr_width) 211*af6491f8SAntonio Nino Diaz { 212*af6491f8SAntonio Nino Diaz return UINT64_MAX >> (64U - addr_width); 213*af6491f8SAntonio Nino Diaz } 214239b085cSAntonio Nino Diaz #endif /* AARCH32 */ 215239b085cSAntonio Nino Diaz 216aa61368eSAntonio Nino Diaz #endif /* ENABLE_ASSERTIONS */ 217239b085cSAntonio Nino Diaz 218*af6491f8SAntonio Nino Diaz #endif /* TZC_COMMON_PRIVATE_H */ 219