1239b085cSAntonio Nino Diaz /* 2239b085cSAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 3239b085cSAntonio Nino Diaz * 4239b085cSAntonio Nino Diaz * Redistribution and use in source and binary forms, with or without 5239b085cSAntonio Nino Diaz * modification, are permitted provided that the following conditions are met: 6239b085cSAntonio Nino Diaz * 7239b085cSAntonio Nino Diaz * Redistributions of source code must retain the above copyright notice, this 8239b085cSAntonio Nino Diaz * list of conditions and the following disclaimer. 9239b085cSAntonio Nino Diaz * 10239b085cSAntonio Nino Diaz * Redistributions in binary form must reproduce the above copyright notice, 11239b085cSAntonio Nino Diaz * this list of conditions and the following disclaimer in the documentation 12239b085cSAntonio Nino Diaz * and/or other materials provided with the distribution. 13239b085cSAntonio Nino Diaz * 14239b085cSAntonio Nino Diaz * Neither the name of ARM nor the names of its contributors may be used 15239b085cSAntonio Nino Diaz * to endorse or promote products derived from this software without specific 16239b085cSAntonio Nino Diaz * prior written permission. 17239b085cSAntonio Nino Diaz * 18239b085cSAntonio Nino Diaz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19239b085cSAntonio Nino Diaz * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20239b085cSAntonio Nino Diaz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21239b085cSAntonio Nino Diaz * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22239b085cSAntonio Nino Diaz * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23239b085cSAntonio Nino Diaz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24239b085cSAntonio Nino Diaz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25239b085cSAntonio Nino Diaz * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26239b085cSAntonio Nino Diaz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27239b085cSAntonio Nino Diaz * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28239b085cSAntonio Nino Diaz * POSSIBILITY OF SUCH DAMAGE. 29239b085cSAntonio Nino Diaz */ 30239b085cSAntonio Nino Diaz 31239b085cSAntonio Nino Diaz #ifndef __TZC_COMMON_PRIVATE_H__ 32239b085cSAntonio Nino Diaz #define __TZC_COMMON_PRIVATE_H__ 33239b085cSAntonio Nino Diaz 34239b085cSAntonio Nino Diaz #include <arch.h> 35239b085cSAntonio Nino Diaz #include <arch_helpers.h> 36239b085cSAntonio Nino Diaz #include <mmio.h> 37239b085cSAntonio Nino Diaz #include <tzc_common.h> 38239b085cSAntonio Nino Diaz 39239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \ 40239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_action( \ 41239b085cSAntonio Nino Diaz uintptr_t base, \ 42239b085cSAntonio Nino Diaz tzc_action_t action) \ 43239b085cSAntonio Nino Diaz { \ 44239b085cSAntonio Nino Diaz mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \ 45239b085cSAntonio Nino Diaz action); \ 46239b085cSAntonio Nino Diaz } 47239b085cSAntonio Nino Diaz 48239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \ 49239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_base( \ 50239b085cSAntonio Nino Diaz uintptr_t base, \ 51239b085cSAntonio Nino Diaz int region_no, \ 52239b085cSAntonio Nino Diaz unsigned long long region_base) \ 53239b085cSAntonio Nino Diaz { \ 54239b085cSAntonio Nino Diaz mmio_write_32(base + \ 55239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 56239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 57239b085cSAntonio Nino Diaz region_no) + \ 58239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \ 59239b085cSAntonio Nino Diaz (uint32_t)region_base); \ 60239b085cSAntonio Nino Diaz mmio_write_32(base + \ 61239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 62239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 63239b085cSAntonio Nino Diaz region_no) + \ 64239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \ 65239b085cSAntonio Nino Diaz (uint32_t)(region_base >> 32)); \ 66239b085cSAntonio Nino Diaz } 67239b085cSAntonio Nino Diaz 68239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \ 69239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_top( \ 70239b085cSAntonio Nino Diaz uintptr_t base, \ 71239b085cSAntonio Nino Diaz int region_no, \ 72239b085cSAntonio Nino Diaz unsigned long long region_top) \ 73239b085cSAntonio Nino Diaz { \ 74239b085cSAntonio Nino Diaz mmio_write_32(base + \ 75239b085cSAntonio Nino Diaz TZC_REGION_OFFSET \ 76239b085cSAntonio Nino Diaz (TZC_##macro_name##_REGION_SIZE, \ 77239b085cSAntonio Nino Diaz region_no) + \ 78239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \ 79239b085cSAntonio Nino Diaz (uint32_t)region_top); \ 80239b085cSAntonio Nino Diaz mmio_write_32(base + \ 81239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 82239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 83239b085cSAntonio Nino Diaz region_no) + \ 84239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \ 85239b085cSAntonio Nino Diaz (uint32_t)(region_top >> 32)); \ 86239b085cSAntonio Nino Diaz } 87239b085cSAntonio Nino Diaz 88239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \ 89239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_attributes( \ 90239b085cSAntonio Nino Diaz uintptr_t base, \ 91239b085cSAntonio Nino Diaz int region_no, \ 92239b085cSAntonio Nino Diaz unsigned int attr) \ 93239b085cSAntonio Nino Diaz { \ 94239b085cSAntonio Nino Diaz mmio_write_32(base + \ 95239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 96239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 97239b085cSAntonio Nino Diaz region_no) + \ 98239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ 99239b085cSAntonio Nino Diaz attr); \ 100239b085cSAntonio Nino Diaz } 101239b085cSAntonio Nino Diaz 102239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \ 103239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_id_access( \ 104239b085cSAntonio Nino Diaz uintptr_t base, \ 105239b085cSAntonio Nino Diaz int region_no, \ 106239b085cSAntonio Nino Diaz unsigned int val) \ 107239b085cSAntonio Nino Diaz { \ 108239b085cSAntonio Nino Diaz mmio_write_32(base + \ 109239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 110239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 111239b085cSAntonio Nino Diaz region_no) + \ 112239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \ 113239b085cSAntonio Nino Diaz val); \ 114239b085cSAntonio Nino Diaz } 115239b085cSAntonio Nino Diaz 116239b085cSAntonio Nino Diaz /* 117239b085cSAntonio Nino Diaz * It is used to program region 0 ATTRIBUTES and ACCESS register. 118239b085cSAntonio Nino Diaz */ 119239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \ 120239b085cSAntonio Nino Diaz void _tzc##fn_name##_configure_region0(uintptr_t base, \ 121239b085cSAntonio Nino Diaz tzc_region_attributes_t sec_attr, \ 122239b085cSAntonio Nino Diaz unsigned int ns_device_access) \ 123239b085cSAntonio Nino Diaz { \ 124239b085cSAntonio Nino Diaz assert(base); \ 125239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region 0 " \ 126239b085cSAntonio Nino Diaz "(TZC Interface Base=%p sec_attr=0x%x," \ 127239b085cSAntonio Nino Diaz " ns_devs=0x%x)\n", (void *)base, \ 128239b085cSAntonio Nino Diaz sec_attr, ns_device_access); \ 129239b085cSAntonio Nino Diaz \ 130239b085cSAntonio Nino Diaz /* Set secure attributes on region 0 */ \ 131239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_attributes(base, 0, \ 132239b085cSAntonio Nino Diaz sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \ 133239b085cSAntonio Nino Diaz \ 134239b085cSAntonio Nino Diaz /***************************************************/ \ 135239b085cSAntonio Nino Diaz /* Specify which non-secure devices have permission*/ \ 136239b085cSAntonio Nino Diaz /* to access region 0. */ \ 137239b085cSAntonio Nino Diaz /***************************************************/ \ 138239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_id_access(base, \ 139239b085cSAntonio Nino Diaz 0, \ 140239b085cSAntonio Nino Diaz ns_device_access); \ 141239b085cSAntonio Nino Diaz } 142239b085cSAntonio Nino Diaz 143239b085cSAntonio Nino Diaz /* 144239b085cSAntonio Nino Diaz * It is used to program a region from 1 to 8 in the TrustZone controller. 145239b085cSAntonio Nino Diaz * NOTE: 146239b085cSAntonio Nino Diaz * Region 0 is special; it is preferable to use 147239b085cSAntonio Nino Diaz * ##fn_name##_configure_region0 for this region (see comment for 148239b085cSAntonio Nino Diaz * that function). 149239b085cSAntonio Nino Diaz */ 150239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \ 151239b085cSAntonio Nino Diaz void _tzc##fn_name##_configure_region(uintptr_t base, \ 152239b085cSAntonio Nino Diaz unsigned int filters, \ 153239b085cSAntonio Nino Diaz int region_no, \ 154239b085cSAntonio Nino Diaz unsigned long long region_base, \ 155239b085cSAntonio Nino Diaz unsigned long long region_top, \ 156239b085cSAntonio Nino Diaz tzc_region_attributes_t sec_attr, \ 157239b085cSAntonio Nino Diaz unsigned int nsaid_permissions) \ 158239b085cSAntonio Nino Diaz { \ 159239b085cSAntonio Nino Diaz assert(base); \ 160239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region " \ 161239b085cSAntonio Nino Diaz "(TZC Interface Base: %p, region_no = %d)" \ 162239b085cSAntonio Nino Diaz "...\n", (void *)base, region_no); \ 163239b085cSAntonio Nino Diaz VERBOSE("TrustZone : ... base = %llx, top = %llx," \ 164239b085cSAntonio Nino Diaz "\n", region_base, region_top);\ 165239b085cSAntonio Nino Diaz VERBOSE("TrustZone : ... sec_attr = 0x%x," \ 166239b085cSAntonio Nino Diaz " ns_devs = 0x%x)\n", \ 167239b085cSAntonio Nino Diaz sec_attr, nsaid_permissions); \ 168239b085cSAntonio Nino Diaz \ 169239b085cSAntonio Nino Diaz /***************************************************/ \ 170239b085cSAntonio Nino Diaz /* Inputs look ok, start programming registers. */ \ 171239b085cSAntonio Nino Diaz /* All the address registers are 32 bits wide and */ \ 172239b085cSAntonio Nino Diaz /* have a LOW and HIGH */ \ 173239b085cSAntonio Nino Diaz /* component used to construct an address up to a */ \ 174239b085cSAntonio Nino Diaz /* 64bit. */ \ 175239b085cSAntonio Nino Diaz /***************************************************/ \ 176239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_base(base, \ 177239b085cSAntonio Nino Diaz region_no, region_base); \ 178239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_top(base, \ 179239b085cSAntonio Nino Diaz region_no, region_top); \ 180239b085cSAntonio Nino Diaz \ 181239b085cSAntonio Nino Diaz /* Enable filter to the region and set secure attributes */\ 182239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_attributes(base, \ 183239b085cSAntonio Nino Diaz region_no, \ 184239b085cSAntonio Nino Diaz (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\ 185239b085cSAntonio Nino Diaz (filters << TZC_REGION_ATTR_F_EN_SHIFT));\ 186239b085cSAntonio Nino Diaz \ 187239b085cSAntonio Nino Diaz /***************************************************/ \ 188239b085cSAntonio Nino Diaz /* Specify which non-secure devices have permission*/ \ 189239b085cSAntonio Nino Diaz /* to access this region. */ \ 190239b085cSAntonio Nino Diaz /***************************************************/ \ 191239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_id_access(base, \ 192239b085cSAntonio Nino Diaz region_no, \ 193239b085cSAntonio Nino Diaz nsaid_permissions); \ 194239b085cSAntonio Nino Diaz } 195239b085cSAntonio Nino Diaz 196*aa61368eSAntonio Nino Diaz #if ENABLE_ASSERTIONS 197*aa61368eSAntonio Nino Diaz 198239b085cSAntonio Nino Diaz static inline unsigned int _tzc_read_peripheral_id(uintptr_t base) 199239b085cSAntonio Nino Diaz { 200239b085cSAntonio Nino Diaz unsigned int id; 201239b085cSAntonio Nino Diaz 202239b085cSAntonio Nino Diaz id = mmio_read_32(base + PID0_OFF); 203239b085cSAntonio Nino Diaz /* Masks DESC part in PID1 */ 204239b085cSAntonio Nino Diaz id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8); 205239b085cSAntonio Nino Diaz 206239b085cSAntonio Nino Diaz return id; 207239b085cSAntonio Nino Diaz } 208239b085cSAntonio Nino Diaz 209239b085cSAntonio Nino Diaz #ifdef AARCH32 210239b085cSAntonio Nino Diaz static inline unsigned long long _tzc_get_max_top_addr(int addr_width) 211239b085cSAntonio Nino Diaz { 212239b085cSAntonio Nino Diaz /* 213239b085cSAntonio Nino Diaz * Assume at least 32 bit wide address and initialize the max. 214239b085cSAntonio Nino Diaz * This function doesn't use 64-bit integer arithmetic to avoid 215239b085cSAntonio Nino Diaz * having to implement additional compiler library functions. 216239b085cSAntonio Nino Diaz */ 217239b085cSAntonio Nino Diaz unsigned long long addr_mask = 0xFFFFFFFF; 218239b085cSAntonio Nino Diaz uint32_t *addr_ptr = (uint32_t *)&addr_mask; 219239b085cSAntonio Nino Diaz 220239b085cSAntonio Nino Diaz assert(addr_width >= 32); 221239b085cSAntonio Nino Diaz 222239b085cSAntonio Nino Diaz /* This logic works only on little - endian platforms */ 223239b085cSAntonio Nino Diaz assert((read_sctlr() & SCTLR_EE_BIT) == 0); 224239b085cSAntonio Nino Diaz 225239b085cSAntonio Nino Diaz /* 226239b085cSAntonio Nino Diaz * If required address width is greater than 32, populate the higher 227239b085cSAntonio Nino Diaz * 32 bits of the 64 bit field with the max address. 228239b085cSAntonio Nino Diaz */ 229239b085cSAntonio Nino Diaz if (addr_width > 32) 230239b085cSAntonio Nino Diaz *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1); 231239b085cSAntonio Nino Diaz 232239b085cSAntonio Nino Diaz return addr_mask; 233239b085cSAntonio Nino Diaz } 234239b085cSAntonio Nino Diaz #else 235239b085cSAntonio Nino Diaz #define _tzc_get_max_top_addr(addr_width)\ 236239b085cSAntonio Nino Diaz (UINT64_MAX >> (64 - (addr_width))) 237239b085cSAntonio Nino Diaz #endif /* AARCH32 */ 238239b085cSAntonio Nino Diaz 239*aa61368eSAntonio Nino Diaz #endif /* ENABLE_ASSERTIONS */ 240239b085cSAntonio Nino Diaz 241239b085cSAntonio Nino Diaz #endif /* __TZC_COMMON_PRIVATE_H__ */ 242