1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #ifndef TZC_COMMON_PRIVATE_H 8*91f16700Schasinglulu #define TZC_COMMON_PRIVATE_H 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <arch.h> 11*91f16700Schasinglulu #include <arch_helpers.h> 12*91f16700Schasinglulu #include <drivers/arm/tzc_common.h> 13*91f16700Schasinglulu #include <lib/mmio.h> 14*91f16700Schasinglulu 15*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \ 16*91f16700Schasinglulu static inline void _tzc##fn_name##_write_action( \ 17*91f16700Schasinglulu uintptr_t base, \ 18*91f16700Schasinglulu unsigned int action) \ 19*91f16700Schasinglulu { \ 20*91f16700Schasinglulu mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \ 21*91f16700Schasinglulu action); \ 22*91f16700Schasinglulu } 23*91f16700Schasinglulu 24*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \ 25*91f16700Schasinglulu static inline void _tzc##fn_name##_write_region_base( \ 26*91f16700Schasinglulu uintptr_t base, \ 27*91f16700Schasinglulu unsigned int region_no, \ 28*91f16700Schasinglulu unsigned long long region_base) \ 29*91f16700Schasinglulu { \ 30*91f16700Schasinglulu mmio_write_32(base + \ 31*91f16700Schasinglulu TZC_REGION_OFFSET( \ 32*91f16700Schasinglulu TZC_##macro_name##_REGION_SIZE, \ 33*91f16700Schasinglulu (u_register_t)region_no) + \ 34*91f16700Schasinglulu TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \ 35*91f16700Schasinglulu (uint32_t)region_base); \ 36*91f16700Schasinglulu mmio_write_32(base + \ 37*91f16700Schasinglulu TZC_REGION_OFFSET( \ 38*91f16700Schasinglulu TZC_##macro_name##_REGION_SIZE, \ 39*91f16700Schasinglulu (u_register_t)region_no) + \ 40*91f16700Schasinglulu TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \ 41*91f16700Schasinglulu (uint32_t)(region_base >> 32)); \ 42*91f16700Schasinglulu } 43*91f16700Schasinglulu 44*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \ 45*91f16700Schasinglulu static inline void _tzc##fn_name##_write_region_top( \ 46*91f16700Schasinglulu uintptr_t base, \ 47*91f16700Schasinglulu unsigned int region_no, \ 48*91f16700Schasinglulu unsigned long long region_top) \ 49*91f16700Schasinglulu { \ 50*91f16700Schasinglulu mmio_write_32(base + \ 51*91f16700Schasinglulu TZC_REGION_OFFSET( \ 52*91f16700Schasinglulu TZC_##macro_name##_REGION_SIZE, \ 53*91f16700Schasinglulu (u_register_t)region_no) + \ 54*91f16700Schasinglulu TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \ 55*91f16700Schasinglulu (uint32_t)region_top); \ 56*91f16700Schasinglulu mmio_write_32(base + \ 57*91f16700Schasinglulu TZC_REGION_OFFSET( \ 58*91f16700Schasinglulu TZC_##macro_name##_REGION_SIZE, \ 59*91f16700Schasinglulu (u_register_t)region_no) + \ 60*91f16700Schasinglulu TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \ 61*91f16700Schasinglulu (uint32_t)(region_top >> 32)); \ 62*91f16700Schasinglulu } 63*91f16700Schasinglulu 64*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \ 65*91f16700Schasinglulu static inline void _tzc##fn_name##_write_region_attributes( \ 66*91f16700Schasinglulu uintptr_t base, \ 67*91f16700Schasinglulu unsigned int region_no, \ 68*91f16700Schasinglulu unsigned int attr) \ 69*91f16700Schasinglulu { \ 70*91f16700Schasinglulu mmio_write_32(base + \ 71*91f16700Schasinglulu TZC_REGION_OFFSET( \ 72*91f16700Schasinglulu TZC_##macro_name##_REGION_SIZE, \ 73*91f16700Schasinglulu (u_register_t)region_no) + \ 74*91f16700Schasinglulu TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ 75*91f16700Schasinglulu attr); \ 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \ 79*91f16700Schasinglulu static inline void _tzc##fn_name##_write_region_id_access( \ 80*91f16700Schasinglulu uintptr_t base, \ 81*91f16700Schasinglulu unsigned int region_no, \ 82*91f16700Schasinglulu unsigned int val) \ 83*91f16700Schasinglulu { \ 84*91f16700Schasinglulu mmio_write_32(base + \ 85*91f16700Schasinglulu TZC_REGION_OFFSET( \ 86*91f16700Schasinglulu TZC_##macro_name##_REGION_SIZE, \ 87*91f16700Schasinglulu (u_register_t)region_no) + \ 88*91f16700Schasinglulu TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \ 89*91f16700Schasinglulu val); \ 90*91f16700Schasinglulu } 91*91f16700Schasinglulu 92*91f16700Schasinglulu /* 93*91f16700Schasinglulu * It is used to modify the filters status for a defined region. 94*91f16700Schasinglulu */ 95*91f16700Schasinglulu #define DEFINE_TZC_COMMON_UPDATE_FILTERS(fn_name, macro_name) \ 96*91f16700Schasinglulu static inline void _tzc##fn_name##_update_filters( \ 97*91f16700Schasinglulu uintptr_t base, \ 98*91f16700Schasinglulu unsigned int region_no, \ 99*91f16700Schasinglulu unsigned int nbfilters, \ 100*91f16700Schasinglulu unsigned int filters) \ 101*91f16700Schasinglulu { \ 102*91f16700Schasinglulu uint32_t filters_mask = GENMASK(nbfilters - 1U, 0); \ 103*91f16700Schasinglulu \ 104*91f16700Schasinglulu mmio_clrsetbits_32(base + \ 105*91f16700Schasinglulu TZC_REGION_OFFSET( \ 106*91f16700Schasinglulu TZC_##macro_name##_REGION_SIZE, \ 107*91f16700Schasinglulu region_no) + \ 108*91f16700Schasinglulu TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ 109*91f16700Schasinglulu filters_mask << TZC_REGION_ATTR_F_EN_SHIFT, \ 110*91f16700Schasinglulu filters << TZC_REGION_ATTR_F_EN_SHIFT); \ 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu /* 114*91f16700Schasinglulu * It is used to program region 0 ATTRIBUTES and ACCESS register. 115*91f16700Schasinglulu */ 116*91f16700Schasinglulu #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \ 117*91f16700Schasinglulu static void _tzc##fn_name##_configure_region0(uintptr_t base, \ 118*91f16700Schasinglulu unsigned int sec_attr, \ 119*91f16700Schasinglulu unsigned int ns_device_access) \ 120*91f16700Schasinglulu { \ 121*91f16700Schasinglulu assert(base != 0U); \ 122*91f16700Schasinglulu VERBOSE("TrustZone : Configuring region 0 " \ 123*91f16700Schasinglulu "(TZC Interface Base=0x%lx sec_attr=0x%x," \ 124*91f16700Schasinglulu " ns_devs=0x%x)\n", base, \ 125*91f16700Schasinglulu sec_attr, ns_device_access); \ 126*91f16700Schasinglulu \ 127*91f16700Schasinglulu /* Set secure attributes on region 0 */ \ 128*91f16700Schasinglulu _tzc##fn_name##_write_region_attributes(base, 0, \ 129*91f16700Schasinglulu sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \ 130*91f16700Schasinglulu \ 131*91f16700Schasinglulu /***************************************************/ \ 132*91f16700Schasinglulu /* Specify which non-secure devices have permission*/ \ 133*91f16700Schasinglulu /* to access region 0. */ \ 134*91f16700Schasinglulu /***************************************************/ \ 135*91f16700Schasinglulu _tzc##fn_name##_write_region_id_access(base, \ 136*91f16700Schasinglulu 0, \ 137*91f16700Schasinglulu ns_device_access); \ 138*91f16700Schasinglulu } 139*91f16700Schasinglulu 140*91f16700Schasinglulu /* 141*91f16700Schasinglulu * It is used to program a region from 1 to 8 in the TrustZone controller. 142*91f16700Schasinglulu * NOTE: 143*91f16700Schasinglulu * Region 0 is special; it is preferable to use 144*91f16700Schasinglulu * ##fn_name##_configure_region0 for this region (see comment for 145*91f16700Schasinglulu * that function). 146*91f16700Schasinglulu */ 147*91f16700Schasinglulu #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \ 148*91f16700Schasinglulu static void _tzc##fn_name##_configure_region(uintptr_t base, \ 149*91f16700Schasinglulu unsigned int filters, \ 150*91f16700Schasinglulu unsigned int region_no, \ 151*91f16700Schasinglulu unsigned long long region_base, \ 152*91f16700Schasinglulu unsigned long long region_top, \ 153*91f16700Schasinglulu unsigned int sec_attr, \ 154*91f16700Schasinglulu unsigned int nsaid_permissions) \ 155*91f16700Schasinglulu { \ 156*91f16700Schasinglulu assert(base != 0U); \ 157*91f16700Schasinglulu VERBOSE("TrustZone : Configuring region " \ 158*91f16700Schasinglulu "(TZC Interface Base: 0x%lx, region_no = %u)" \ 159*91f16700Schasinglulu "...\n", base, region_no); \ 160*91f16700Schasinglulu VERBOSE("TrustZone : ... base = %llx, top = %llx," \ 161*91f16700Schasinglulu "\n", region_base, region_top); \ 162*91f16700Schasinglulu VERBOSE("TrustZone : ... sec_attr = 0x%x," \ 163*91f16700Schasinglulu " ns_devs = 0x%x)\n", \ 164*91f16700Schasinglulu sec_attr, nsaid_permissions); \ 165*91f16700Schasinglulu \ 166*91f16700Schasinglulu /***************************************************/ \ 167*91f16700Schasinglulu /* Inputs look ok, start programming registers. */ \ 168*91f16700Schasinglulu /* All the address registers are 32 bits wide and */ \ 169*91f16700Schasinglulu /* have a LOW and HIGH */ \ 170*91f16700Schasinglulu /* component used to construct an address up to a */ \ 171*91f16700Schasinglulu /* 64bit. */ \ 172*91f16700Schasinglulu /***************************************************/ \ 173*91f16700Schasinglulu _tzc##fn_name##_write_region_base(base, \ 174*91f16700Schasinglulu region_no, region_base); \ 175*91f16700Schasinglulu _tzc##fn_name##_write_region_top(base, \ 176*91f16700Schasinglulu region_no, region_top); \ 177*91f16700Schasinglulu \ 178*91f16700Schasinglulu /* Enable filter to the region and set secure attributes */\ 179*91f16700Schasinglulu _tzc##fn_name##_write_region_attributes(base, \ 180*91f16700Schasinglulu region_no, \ 181*91f16700Schasinglulu (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\ 182*91f16700Schasinglulu (filters << TZC_REGION_ATTR_F_EN_SHIFT));\ 183*91f16700Schasinglulu \ 184*91f16700Schasinglulu /***************************************************/ \ 185*91f16700Schasinglulu /* Specify which non-secure devices have permission*/ \ 186*91f16700Schasinglulu /* to access this region. */ \ 187*91f16700Schasinglulu /***************************************************/ \ 188*91f16700Schasinglulu _tzc##fn_name##_write_region_id_access(base, \ 189*91f16700Schasinglulu region_no, \ 190*91f16700Schasinglulu nsaid_permissions); \ 191*91f16700Schasinglulu } 192*91f16700Schasinglulu 193*91f16700Schasinglulu static inline unsigned int _tzc_read_peripheral_id(uintptr_t base) 194*91f16700Schasinglulu { 195*91f16700Schasinglulu unsigned int id; 196*91f16700Schasinglulu 197*91f16700Schasinglulu id = mmio_read_32(base + PID0_OFF); 198*91f16700Schasinglulu /* Masks DESC part in PID1 */ 199*91f16700Schasinglulu id |= ((mmio_read_32(base + PID1_OFF) & 0xFU) << 8U); 200*91f16700Schasinglulu 201*91f16700Schasinglulu return id; 202*91f16700Schasinglulu } 203*91f16700Schasinglulu 204*91f16700Schasinglulu #endif /* TZC_COMMON_PRIVATE_H */ 205