1*239b085cSAntonio Nino Diaz /* 2*239b085cSAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 3*239b085cSAntonio Nino Diaz * 4*239b085cSAntonio Nino Diaz * Redistribution and use in source and binary forms, with or without 5*239b085cSAntonio Nino Diaz * modification, are permitted provided that the following conditions are met: 6*239b085cSAntonio Nino Diaz * 7*239b085cSAntonio Nino Diaz * Redistributions of source code must retain the above copyright notice, this 8*239b085cSAntonio Nino Diaz * list of conditions and the following disclaimer. 9*239b085cSAntonio Nino Diaz * 10*239b085cSAntonio Nino Diaz * Redistributions in binary form must reproduce the above copyright notice, 11*239b085cSAntonio Nino Diaz * this list of conditions and the following disclaimer in the documentation 12*239b085cSAntonio Nino Diaz * and/or other materials provided with the distribution. 13*239b085cSAntonio Nino Diaz * 14*239b085cSAntonio Nino Diaz * Neither the name of ARM nor the names of its contributors may be used 15*239b085cSAntonio Nino Diaz * to endorse or promote products derived from this software without specific 16*239b085cSAntonio Nino Diaz * prior written permission. 17*239b085cSAntonio Nino Diaz * 18*239b085cSAntonio Nino Diaz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*239b085cSAntonio Nino Diaz * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*239b085cSAntonio Nino Diaz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*239b085cSAntonio Nino Diaz * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*239b085cSAntonio Nino Diaz * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*239b085cSAntonio Nino Diaz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*239b085cSAntonio Nino Diaz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*239b085cSAntonio Nino Diaz * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*239b085cSAntonio Nino Diaz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*239b085cSAntonio Nino Diaz * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*239b085cSAntonio Nino Diaz * POSSIBILITY OF SUCH DAMAGE. 29*239b085cSAntonio Nino Diaz */ 30*239b085cSAntonio Nino Diaz 31*239b085cSAntonio Nino Diaz #ifndef __TZC_COMMON_PRIVATE_H__ 32*239b085cSAntonio Nino Diaz #define __TZC_COMMON_PRIVATE_H__ 33*239b085cSAntonio Nino Diaz 34*239b085cSAntonio Nino Diaz #include <arch.h> 35*239b085cSAntonio Nino Diaz #include <arch_helpers.h> 36*239b085cSAntonio Nino Diaz #include <mmio.h> 37*239b085cSAntonio Nino Diaz #include <tzc_common.h> 38*239b085cSAntonio Nino Diaz 39*239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \ 40*239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_action( \ 41*239b085cSAntonio Nino Diaz uintptr_t base, \ 42*239b085cSAntonio Nino Diaz tzc_action_t action) \ 43*239b085cSAntonio Nino Diaz { \ 44*239b085cSAntonio Nino Diaz mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \ 45*239b085cSAntonio Nino Diaz action); \ 46*239b085cSAntonio Nino Diaz } 47*239b085cSAntonio Nino Diaz 48*239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \ 49*239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_base( \ 50*239b085cSAntonio Nino Diaz uintptr_t base, \ 51*239b085cSAntonio Nino Diaz int region_no, \ 52*239b085cSAntonio Nino Diaz unsigned long long region_base) \ 53*239b085cSAntonio Nino Diaz { \ 54*239b085cSAntonio Nino Diaz mmio_write_32(base + \ 55*239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 56*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 57*239b085cSAntonio Nino Diaz region_no) + \ 58*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \ 59*239b085cSAntonio Nino Diaz (uint32_t)region_base); \ 60*239b085cSAntonio Nino Diaz mmio_write_32(base + \ 61*239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 62*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 63*239b085cSAntonio Nino Diaz region_no) + \ 64*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \ 65*239b085cSAntonio Nino Diaz (uint32_t)(region_base >> 32)); \ 66*239b085cSAntonio Nino Diaz } 67*239b085cSAntonio Nino Diaz 68*239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \ 69*239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_top( \ 70*239b085cSAntonio Nino Diaz uintptr_t base, \ 71*239b085cSAntonio Nino Diaz int region_no, \ 72*239b085cSAntonio Nino Diaz unsigned long long region_top) \ 73*239b085cSAntonio Nino Diaz { \ 74*239b085cSAntonio Nino Diaz mmio_write_32(base + \ 75*239b085cSAntonio Nino Diaz TZC_REGION_OFFSET \ 76*239b085cSAntonio Nino Diaz (TZC_##macro_name##_REGION_SIZE, \ 77*239b085cSAntonio Nino Diaz region_no) + \ 78*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \ 79*239b085cSAntonio Nino Diaz (uint32_t)region_top); \ 80*239b085cSAntonio Nino Diaz mmio_write_32(base + \ 81*239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 82*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 83*239b085cSAntonio Nino Diaz region_no) + \ 84*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \ 85*239b085cSAntonio Nino Diaz (uint32_t)(region_top >> 32)); \ 86*239b085cSAntonio Nino Diaz } 87*239b085cSAntonio Nino Diaz 88*239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \ 89*239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_attributes( \ 90*239b085cSAntonio Nino Diaz uintptr_t base, \ 91*239b085cSAntonio Nino Diaz int region_no, \ 92*239b085cSAntonio Nino Diaz unsigned int attr) \ 93*239b085cSAntonio Nino Diaz { \ 94*239b085cSAntonio Nino Diaz mmio_write_32(base + \ 95*239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 96*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 97*239b085cSAntonio Nino Diaz region_no) + \ 98*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ 99*239b085cSAntonio Nino Diaz attr); \ 100*239b085cSAntonio Nino Diaz } 101*239b085cSAntonio Nino Diaz 102*239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \ 103*239b085cSAntonio Nino Diaz static inline void _tzc##fn_name##_write_region_id_access( \ 104*239b085cSAntonio Nino Diaz uintptr_t base, \ 105*239b085cSAntonio Nino Diaz int region_no, \ 106*239b085cSAntonio Nino Diaz unsigned int val) \ 107*239b085cSAntonio Nino Diaz { \ 108*239b085cSAntonio Nino Diaz mmio_write_32(base + \ 109*239b085cSAntonio Nino Diaz TZC_REGION_OFFSET( \ 110*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_SIZE, \ 111*239b085cSAntonio Nino Diaz region_no) + \ 112*239b085cSAntonio Nino Diaz TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \ 113*239b085cSAntonio Nino Diaz val); \ 114*239b085cSAntonio Nino Diaz } 115*239b085cSAntonio Nino Diaz 116*239b085cSAntonio Nino Diaz /* 117*239b085cSAntonio Nino Diaz * It is used to program region 0 ATTRIBUTES and ACCESS register. 118*239b085cSAntonio Nino Diaz */ 119*239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \ 120*239b085cSAntonio Nino Diaz void _tzc##fn_name##_configure_region0(uintptr_t base, \ 121*239b085cSAntonio Nino Diaz tzc_region_attributes_t sec_attr, \ 122*239b085cSAntonio Nino Diaz unsigned int ns_device_access) \ 123*239b085cSAntonio Nino Diaz { \ 124*239b085cSAntonio Nino Diaz assert(base); \ 125*239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region 0 " \ 126*239b085cSAntonio Nino Diaz "(TZC Interface Base=%p sec_attr=0x%x," \ 127*239b085cSAntonio Nino Diaz " ns_devs=0x%x)\n", (void *)base, \ 128*239b085cSAntonio Nino Diaz sec_attr, ns_device_access); \ 129*239b085cSAntonio Nino Diaz \ 130*239b085cSAntonio Nino Diaz /* Set secure attributes on region 0 */ \ 131*239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_attributes(base, 0, \ 132*239b085cSAntonio Nino Diaz sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \ 133*239b085cSAntonio Nino Diaz \ 134*239b085cSAntonio Nino Diaz /***************************************************/ \ 135*239b085cSAntonio Nino Diaz /* Specify which non-secure devices have permission*/ \ 136*239b085cSAntonio Nino Diaz /* to access region 0. */ \ 137*239b085cSAntonio Nino Diaz /***************************************************/ \ 138*239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_id_access(base, \ 139*239b085cSAntonio Nino Diaz 0, \ 140*239b085cSAntonio Nino Diaz ns_device_access); \ 141*239b085cSAntonio Nino Diaz } 142*239b085cSAntonio Nino Diaz 143*239b085cSAntonio Nino Diaz /* 144*239b085cSAntonio Nino Diaz * It is used to program a region from 1 to 8 in the TrustZone controller. 145*239b085cSAntonio Nino Diaz * NOTE: 146*239b085cSAntonio Nino Diaz * Region 0 is special; it is preferable to use 147*239b085cSAntonio Nino Diaz * ##fn_name##_configure_region0 for this region (see comment for 148*239b085cSAntonio Nino Diaz * that function). 149*239b085cSAntonio Nino Diaz */ 150*239b085cSAntonio Nino Diaz #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \ 151*239b085cSAntonio Nino Diaz void _tzc##fn_name##_configure_region(uintptr_t base, \ 152*239b085cSAntonio Nino Diaz unsigned int filters, \ 153*239b085cSAntonio Nino Diaz int region_no, \ 154*239b085cSAntonio Nino Diaz unsigned long long region_base, \ 155*239b085cSAntonio Nino Diaz unsigned long long region_top, \ 156*239b085cSAntonio Nino Diaz tzc_region_attributes_t sec_attr, \ 157*239b085cSAntonio Nino Diaz unsigned int nsaid_permissions) \ 158*239b085cSAntonio Nino Diaz { \ 159*239b085cSAntonio Nino Diaz assert(base); \ 160*239b085cSAntonio Nino Diaz VERBOSE("TrustZone : Configuring region " \ 161*239b085cSAntonio Nino Diaz "(TZC Interface Base: %p, region_no = %d)" \ 162*239b085cSAntonio Nino Diaz "...\n", (void *)base, region_no); \ 163*239b085cSAntonio Nino Diaz VERBOSE("TrustZone : ... base = %llx, top = %llx," \ 164*239b085cSAntonio Nino Diaz "\n", region_base, region_top);\ 165*239b085cSAntonio Nino Diaz VERBOSE("TrustZone : ... sec_attr = 0x%x," \ 166*239b085cSAntonio Nino Diaz " ns_devs = 0x%x)\n", \ 167*239b085cSAntonio Nino Diaz sec_attr, nsaid_permissions); \ 168*239b085cSAntonio Nino Diaz \ 169*239b085cSAntonio Nino Diaz /***************************************************/ \ 170*239b085cSAntonio Nino Diaz /* Inputs look ok, start programming registers. */ \ 171*239b085cSAntonio Nino Diaz /* All the address registers are 32 bits wide and */ \ 172*239b085cSAntonio Nino Diaz /* have a LOW and HIGH */ \ 173*239b085cSAntonio Nino Diaz /* component used to construct an address up to a */ \ 174*239b085cSAntonio Nino Diaz /* 64bit. */ \ 175*239b085cSAntonio Nino Diaz /***************************************************/ \ 176*239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_base(base, \ 177*239b085cSAntonio Nino Diaz region_no, region_base); \ 178*239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_top(base, \ 179*239b085cSAntonio Nino Diaz region_no, region_top); \ 180*239b085cSAntonio Nino Diaz \ 181*239b085cSAntonio Nino Diaz /* Enable filter to the region and set secure attributes */\ 182*239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_attributes(base, \ 183*239b085cSAntonio Nino Diaz region_no, \ 184*239b085cSAntonio Nino Diaz (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\ 185*239b085cSAntonio Nino Diaz (filters << TZC_REGION_ATTR_F_EN_SHIFT));\ 186*239b085cSAntonio Nino Diaz \ 187*239b085cSAntonio Nino Diaz /***************************************************/ \ 188*239b085cSAntonio Nino Diaz /* Specify which non-secure devices have permission*/ \ 189*239b085cSAntonio Nino Diaz /* to access this region. */ \ 190*239b085cSAntonio Nino Diaz /***************************************************/ \ 191*239b085cSAntonio Nino Diaz _tzc##fn_name##_write_region_id_access(base, \ 192*239b085cSAntonio Nino Diaz region_no, \ 193*239b085cSAntonio Nino Diaz nsaid_permissions); \ 194*239b085cSAntonio Nino Diaz } 195*239b085cSAntonio Nino Diaz 196*239b085cSAntonio Nino Diaz #if DEBUG 197*239b085cSAntonio Nino Diaz static inline unsigned int _tzc_read_peripheral_id(uintptr_t base) 198*239b085cSAntonio Nino Diaz { 199*239b085cSAntonio Nino Diaz unsigned int id; 200*239b085cSAntonio Nino Diaz 201*239b085cSAntonio Nino Diaz id = mmio_read_32(base + PID0_OFF); 202*239b085cSAntonio Nino Diaz /* Masks DESC part in PID1 */ 203*239b085cSAntonio Nino Diaz id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8); 204*239b085cSAntonio Nino Diaz 205*239b085cSAntonio Nino Diaz return id; 206*239b085cSAntonio Nino Diaz } 207*239b085cSAntonio Nino Diaz 208*239b085cSAntonio Nino Diaz #ifdef AARCH32 209*239b085cSAntonio Nino Diaz static inline unsigned long long _tzc_get_max_top_addr(int addr_width) 210*239b085cSAntonio Nino Diaz { 211*239b085cSAntonio Nino Diaz /* 212*239b085cSAntonio Nino Diaz * Assume at least 32 bit wide address and initialize the max. 213*239b085cSAntonio Nino Diaz * This function doesn't use 64-bit integer arithmetic to avoid 214*239b085cSAntonio Nino Diaz * having to implement additional compiler library functions. 215*239b085cSAntonio Nino Diaz */ 216*239b085cSAntonio Nino Diaz unsigned long long addr_mask = 0xFFFFFFFF; 217*239b085cSAntonio Nino Diaz uint32_t *addr_ptr = (uint32_t *)&addr_mask; 218*239b085cSAntonio Nino Diaz 219*239b085cSAntonio Nino Diaz assert(addr_width >= 32); 220*239b085cSAntonio Nino Diaz 221*239b085cSAntonio Nino Diaz /* This logic works only on little - endian platforms */ 222*239b085cSAntonio Nino Diaz assert((read_sctlr() & SCTLR_EE_BIT) == 0); 223*239b085cSAntonio Nino Diaz 224*239b085cSAntonio Nino Diaz /* 225*239b085cSAntonio Nino Diaz * If required address width is greater than 32, populate the higher 226*239b085cSAntonio Nino Diaz * 32 bits of the 64 bit field with the max address. 227*239b085cSAntonio Nino Diaz */ 228*239b085cSAntonio Nino Diaz if (addr_width > 32) 229*239b085cSAntonio Nino Diaz *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1); 230*239b085cSAntonio Nino Diaz 231*239b085cSAntonio Nino Diaz return addr_mask; 232*239b085cSAntonio Nino Diaz } 233*239b085cSAntonio Nino Diaz #else 234*239b085cSAntonio Nino Diaz #define _tzc_get_max_top_addr(addr_width)\ 235*239b085cSAntonio Nino Diaz (UINT64_MAX >> (64 - (addr_width))) 236*239b085cSAntonio Nino Diaz #endif /* AARCH32 */ 237*239b085cSAntonio Nino Diaz 238*239b085cSAntonio Nino Diaz #endif 239*239b085cSAntonio Nino Diaz 240*239b085cSAntonio Nino Diaz #endif /* __TZC_COMMON_PRIVATE_H__ */ 241