1239b085cSAntonio Nino Diaz /* 2239b085cSAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 3239b085cSAntonio Nino Diaz * 4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5239b085cSAntonio Nino Diaz */ 6239b085cSAntonio Nino Diaz 7239b085cSAntonio Nino Diaz #ifndef __TZC_COMMON_PRIVATE_H__ 8239b085cSAntonio 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, \ 18239b085cSAntonio Nino Diaz tzc_action_t 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, \ 27239b085cSAntonio Nino Diaz 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, \ 47239b085cSAntonio Nino Diaz 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, \ 67239b085cSAntonio Nino Diaz 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, \ 81239b085cSAntonio Nino Diaz 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) \ 96239b085cSAntonio Nino Diaz void _tzc##fn_name##_configure_region0(uintptr_t base, \ 97239b085cSAntonio Nino Diaz tzc_region_attributes_t sec_attr, \ 98239b085cSAntonio Nino Diaz unsigned int ns_device_access) \ 99239b085cSAntonio Nino Diaz { \ 100239b085cSAntonio Nino Diaz assert(base); \ 101239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region 0 " \ 102239b085cSAntonio Nino Diaz "(TZC Interface Base=%p sec_attr=0x%x," \ 103239b085cSAntonio Nino Diaz " ns_devs=0x%x)\n", (void *)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) \ 127239b085cSAntonio Nino Diaz void _tzc##fn_name##_configure_region(uintptr_t base, \ 128239b085cSAntonio Nino Diaz unsigned int filters, \ 129239b085cSAntonio Nino Diaz int region_no, \ 130239b085cSAntonio Nino Diaz unsigned long long region_base, \ 131239b085cSAntonio Nino Diaz unsigned long long region_top, \ 132239b085cSAntonio Nino Diaz tzc_region_attributes_t sec_attr, \ 133239b085cSAntonio Nino Diaz unsigned int nsaid_permissions) \ 134239b085cSAntonio Nino Diaz { \ 135239b085cSAntonio Nino Diaz assert(base); \ 136239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region " \ 137239b085cSAntonio Nino Diaz "(TZC Interface Base: %p, region_no = %d)" \ 138239b085cSAntonio Nino Diaz "...\n", (void *)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 172aa61368eSAntonio Nino Diaz #if ENABLE_ASSERTIONS 173aa61368eSAntonio Nino Diaz 174239b085cSAntonio Nino Diaz static inline unsigned int _tzc_read_peripheral_id(uintptr_t base) 175239b085cSAntonio Nino Diaz { 176239b085cSAntonio Nino Diaz unsigned int id; 177239b085cSAntonio Nino Diaz 178239b085cSAntonio Nino Diaz id = mmio_read_32(base + PID0_OFF); 179239b085cSAntonio Nino Diaz /* Masks DESC part in PID1 */ 180239b085cSAntonio Nino Diaz id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8); 181239b085cSAntonio Nino Diaz 182239b085cSAntonio Nino Diaz return id; 183239b085cSAntonio Nino Diaz } 184239b085cSAntonio Nino Diaz 185239b085cSAntonio Nino Diaz #ifdef AARCH32 186239b085cSAntonio Nino Diaz static inline unsigned long long _tzc_get_max_top_addr(int addr_width) 187239b085cSAntonio Nino Diaz { 188239b085cSAntonio Nino Diaz /* 189239b085cSAntonio Nino Diaz * Assume at least 32 bit wide address and initialize the max. 190239b085cSAntonio Nino Diaz * This function doesn't use 64-bit integer arithmetic to avoid 191239b085cSAntonio Nino Diaz * having to implement additional compiler library functions. 192239b085cSAntonio Nino Diaz */ 193239b085cSAntonio Nino Diaz unsigned long long addr_mask = 0xFFFFFFFF; 194239b085cSAntonio Nino Diaz uint32_t *addr_ptr = (uint32_t *)&addr_mask; 195239b085cSAntonio Nino Diaz 196239b085cSAntonio Nino Diaz assert(addr_width >= 32); 197239b085cSAntonio Nino Diaz 198239b085cSAntonio Nino Diaz /* This logic works only on little - endian platforms */ 199239b085cSAntonio Nino Diaz assert((read_sctlr() & SCTLR_EE_BIT) == 0); 200239b085cSAntonio Nino Diaz 201239b085cSAntonio Nino Diaz /* 202239b085cSAntonio Nino Diaz * If required address width is greater than 32, populate the higher 203239b085cSAntonio Nino Diaz * 32 bits of the 64 bit field with the max address. 204239b085cSAntonio Nino Diaz */ 205239b085cSAntonio Nino Diaz if (addr_width > 32) 206239b085cSAntonio Nino Diaz *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1); 207239b085cSAntonio Nino Diaz 208239b085cSAntonio Nino Diaz return addr_mask; 209239b085cSAntonio Nino Diaz } 210239b085cSAntonio Nino Diaz #else 211239b085cSAntonio Nino Diaz #define _tzc_get_max_top_addr(addr_width)\ 212239b085cSAntonio Nino Diaz (UINT64_MAX >> (64 - (addr_width))) 213239b085cSAntonio Nino Diaz #endif /* AARCH32 */ 214239b085cSAntonio Nino Diaz 215aa61368eSAntonio Nino Diaz #endif /* ENABLE_ASSERTIONS */ 216239b085cSAntonio Nino Diaz 217239b085cSAntonio Nino Diaz #endif /* __TZC_COMMON_PRIVATE_H__ */ 218