1*5d1638f3SJens Wiklander /* 2*5d1638f3SJens Wiklander * Copyright (c) 2015, Linaro Limited 3*5d1638f3SJens Wiklander * All rights reserved. 4*5d1638f3SJens Wiklander * 5*5d1638f3SJens Wiklander * Redistribution and use in source and binary forms, with or without 6*5d1638f3SJens Wiklander * modification, are permitted provided that the following conditions are met: 7*5d1638f3SJens Wiklander * 8*5d1638f3SJens Wiklander * 1. Redistributions of source code must retain the above copyright notice, 9*5d1638f3SJens Wiklander * this list of conditions and the following disclaimer. 10*5d1638f3SJens Wiklander * 11*5d1638f3SJens Wiklander * 2. Redistributions in binary form must reproduce the above copyright notice, 12*5d1638f3SJens Wiklander * this list of conditions and the following disclaimer in the documentation 13*5d1638f3SJens Wiklander * and/or other materials provided with the distribution. 14*5d1638f3SJens Wiklander * 15*5d1638f3SJens Wiklander * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16*5d1638f3SJens Wiklander * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*5d1638f3SJens Wiklander * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*5d1638f3SJens Wiklander * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19*5d1638f3SJens Wiklander * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*5d1638f3SJens Wiklander * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*5d1638f3SJens Wiklander * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*5d1638f3SJens Wiklander * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*5d1638f3SJens Wiklander * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*5d1638f3SJens Wiklander * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*5d1638f3SJens Wiklander * POSSIBILITY OF SUCH DAMAGE. 26*5d1638f3SJens Wiklander */ 27*5d1638f3SJens Wiklander /* 28*5d1638f3SJens Wiklander * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. 29*5d1638f3SJens Wiklander * 30*5d1638f3SJens Wiklander * Redistribution and use in source and binary forms, with or without 31*5d1638f3SJens Wiklander * modification, are permitted provided that the following conditions are met: 32*5d1638f3SJens Wiklander * 33*5d1638f3SJens Wiklander * Redistributions of source code must retain the above copyright notice, this 34*5d1638f3SJens Wiklander * list of conditions and the following disclaimer. 35*5d1638f3SJens Wiklander * 36*5d1638f3SJens Wiklander * Redistributions in binary form must reproduce the above copyright notice, 37*5d1638f3SJens Wiklander * this list of conditions and the following disclaimer in the documentation 38*5d1638f3SJens Wiklander * and/or other materials provided with the distribution. 39*5d1638f3SJens Wiklander * 40*5d1638f3SJens Wiklander * Neither the name of ARM nor the names of its contributors may be used 41*5d1638f3SJens Wiklander * to endorse or promote products derived from this software without specific 42*5d1638f3SJens Wiklander * prior written permission. 43*5d1638f3SJens Wiklander * 44*5d1638f3SJens Wiklander * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 45*5d1638f3SJens Wiklander * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46*5d1638f3SJens Wiklander * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47*5d1638f3SJens Wiklander * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 48*5d1638f3SJens Wiklander * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 49*5d1638f3SJens Wiklander * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 50*5d1638f3SJens Wiklander * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 51*5d1638f3SJens Wiklander * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 52*5d1638f3SJens Wiklander * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 53*5d1638f3SJens Wiklander * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 54*5d1638f3SJens Wiklander * POSSIBILITY OF SUCH DAMAGE. 55*5d1638f3SJens Wiklander */ 56*5d1638f3SJens Wiklander 57*5d1638f3SJens Wiklander #include <assert.h> 58*5d1638f3SJens Wiklander #include <drivers/tzc400.h> 59*5d1638f3SJens Wiklander #include <io.h> 60*5d1638f3SJens Wiklander #include <kernel/panic.h> 61*5d1638f3SJens Wiklander #include <stddef.h> 62*5d1638f3SJens Wiklander #include <trace.h> 63*5d1638f3SJens Wiklander #include <util.h> 64*5d1638f3SJens Wiklander 65*5d1638f3SJens Wiklander /* 66*5d1638f3SJens Wiklander * Implementation defined values used to validate inputs later. 67*5d1638f3SJens Wiklander * Filters : max of 4 ; 0 to 3 68*5d1638f3SJens Wiklander * Regions : max of 9 ; 0 to 8 69*5d1638f3SJens Wiklander * Address width : Values between 32 to 64 70*5d1638f3SJens Wiklander */ 71*5d1638f3SJens Wiklander struct tzc_instance { 72*5d1638f3SJens Wiklander vaddr_t base; 73*5d1638f3SJens Wiklander uint8_t addr_width; 74*5d1638f3SJens Wiklander uint8_t num_filters; 75*5d1638f3SJens Wiklander uint8_t num_regions; 76*5d1638f3SJens Wiklander }; 77*5d1638f3SJens Wiklander 78*5d1638f3SJens Wiklander static struct tzc_instance tzc; 79*5d1638f3SJens Wiklander 80*5d1638f3SJens Wiklander 81*5d1638f3SJens Wiklander static uint32_t tzc_read_build_config(vaddr_t base) 82*5d1638f3SJens Wiklander { 83*5d1638f3SJens Wiklander return read32(base + BUILD_CONFIG_OFF); 84*5d1638f3SJens Wiklander } 85*5d1638f3SJens Wiklander 86*5d1638f3SJens Wiklander static uint32_t tzc_read_gate_keeper(vaddr_t base) 87*5d1638f3SJens Wiklander { 88*5d1638f3SJens Wiklander return read32(base + GATE_KEEPER_OFF); 89*5d1638f3SJens Wiklander } 90*5d1638f3SJens Wiklander 91*5d1638f3SJens Wiklander static void tzc_write_gate_keeper(vaddr_t base, uint32_t val) 92*5d1638f3SJens Wiklander { 93*5d1638f3SJens Wiklander write32(val, base + GATE_KEEPER_OFF); 94*5d1638f3SJens Wiklander } 95*5d1638f3SJens Wiklander 96*5d1638f3SJens Wiklander static void tzc_write_action(vaddr_t base, enum tzc_action action) 97*5d1638f3SJens Wiklander { 98*5d1638f3SJens Wiklander write32(action, base + ACTION_OFF); 99*5d1638f3SJens Wiklander } 100*5d1638f3SJens Wiklander 101*5d1638f3SJens Wiklander static void tzc_write_region_base_low(vaddr_t base, uint32_t region, 102*5d1638f3SJens Wiklander uint32_t val) 103*5d1638f3SJens Wiklander { 104*5d1638f3SJens Wiklander write32(val, base + REGION_BASE_LOW_OFF + 105*5d1638f3SJens Wiklander REGION_NUM_OFF(region)); 106*5d1638f3SJens Wiklander } 107*5d1638f3SJens Wiklander 108*5d1638f3SJens Wiklander static void tzc_write_region_base_high(vaddr_t base, uint32_t region, 109*5d1638f3SJens Wiklander uint32_t val) 110*5d1638f3SJens Wiklander { 111*5d1638f3SJens Wiklander write32(val, base + REGION_BASE_HIGH_OFF + 112*5d1638f3SJens Wiklander REGION_NUM_OFF(region)); 113*5d1638f3SJens Wiklander } 114*5d1638f3SJens Wiklander 115*5d1638f3SJens Wiklander static void tzc_write_region_top_low(vaddr_t base, uint32_t region, 116*5d1638f3SJens Wiklander uint32_t val) 117*5d1638f3SJens Wiklander { 118*5d1638f3SJens Wiklander write32(val, base + REGION_TOP_LOW_OFF + 119*5d1638f3SJens Wiklander REGION_NUM_OFF(region)); 120*5d1638f3SJens Wiklander } 121*5d1638f3SJens Wiklander 122*5d1638f3SJens Wiklander static void tzc_write_region_top_high(vaddr_t base, uint32_t region, 123*5d1638f3SJens Wiklander uint32_t val) 124*5d1638f3SJens Wiklander { 125*5d1638f3SJens Wiklander write32(val, base + REGION_TOP_HIGH_OFF + 126*5d1638f3SJens Wiklander REGION_NUM_OFF(region)); 127*5d1638f3SJens Wiklander } 128*5d1638f3SJens Wiklander 129*5d1638f3SJens Wiklander static void tzc_write_region_attributes(vaddr_t base, uint32_t region, 130*5d1638f3SJens Wiklander uint32_t val) 131*5d1638f3SJens Wiklander { 132*5d1638f3SJens Wiklander write32(val, base + REGION_ATTRIBUTES_OFF + 133*5d1638f3SJens Wiklander REGION_NUM_OFF(region)); 134*5d1638f3SJens Wiklander } 135*5d1638f3SJens Wiklander 136*5d1638f3SJens Wiklander static void tzc_write_region_id_access(vaddr_t base, uint32_t region, 137*5d1638f3SJens Wiklander uint32_t val) 138*5d1638f3SJens Wiklander { 139*5d1638f3SJens Wiklander write32(val, base + REGION_ID_ACCESS_OFF + 140*5d1638f3SJens Wiklander REGION_NUM_OFF(region)); 141*5d1638f3SJens Wiklander } 142*5d1638f3SJens Wiklander 143*5d1638f3SJens Wiklander static uint32_t tzc_read_component_id(vaddr_t base) 144*5d1638f3SJens Wiklander { 145*5d1638f3SJens Wiklander uint32_t id; 146*5d1638f3SJens Wiklander 147*5d1638f3SJens Wiklander id = read8(base + CID0_OFF); 148*5d1638f3SJens Wiklander id |= SHIFT_U32(read8(base + CID1_OFF), 8); 149*5d1638f3SJens Wiklander id |= SHIFT_U32(read8(base + CID2_OFF), 16); 150*5d1638f3SJens Wiklander id |= SHIFT_U32(read8(base + CID3_OFF), 24); 151*5d1638f3SJens Wiklander 152*5d1638f3SJens Wiklander return id; 153*5d1638f3SJens Wiklander } 154*5d1638f3SJens Wiklander 155*5d1638f3SJens Wiklander static uint32_t tzc_get_gate_keeper(vaddr_t base, uint8_t filter) 156*5d1638f3SJens Wiklander { 157*5d1638f3SJens Wiklander uint32_t tmp; 158*5d1638f3SJens Wiklander 159*5d1638f3SJens Wiklander tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 160*5d1638f3SJens Wiklander GATE_KEEPER_OS_MASK; 161*5d1638f3SJens Wiklander 162*5d1638f3SJens Wiklander return (tmp >> filter) & GATE_KEEPER_FILTER_MASK; 163*5d1638f3SJens Wiklander } 164*5d1638f3SJens Wiklander 165*5d1638f3SJens Wiklander /* This function is not MP safe. */ 166*5d1638f3SJens Wiklander static void tzc_set_gate_keeper(vaddr_t base, uint8_t filter, uint32_t val) 167*5d1638f3SJens Wiklander { 168*5d1638f3SJens Wiklander uint32_t tmp; 169*5d1638f3SJens Wiklander 170*5d1638f3SJens Wiklander /* Upper half is current state. Lower half is requested state. */ 171*5d1638f3SJens Wiklander tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 172*5d1638f3SJens Wiklander GATE_KEEPER_OS_MASK; 173*5d1638f3SJens Wiklander 174*5d1638f3SJens Wiklander if (val) 175*5d1638f3SJens Wiklander tmp |= (1 << filter); 176*5d1638f3SJens Wiklander else 177*5d1638f3SJens Wiklander tmp &= ~(1 << filter); 178*5d1638f3SJens Wiklander 179*5d1638f3SJens Wiklander tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) << 180*5d1638f3SJens Wiklander GATE_KEEPER_OR_SHIFT); 181*5d1638f3SJens Wiklander 182*5d1638f3SJens Wiklander /* Wait here until we see the change reflected in the TZC status. */ 183*5d1638f3SJens Wiklander while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 184*5d1638f3SJens Wiklander GATE_KEEPER_OS_MASK) != tmp) 185*5d1638f3SJens Wiklander ; 186*5d1638f3SJens Wiklander } 187*5d1638f3SJens Wiklander 188*5d1638f3SJens Wiklander 189*5d1638f3SJens Wiklander void tzc_init(vaddr_t base) 190*5d1638f3SJens Wiklander { 191*5d1638f3SJens Wiklander uint32_t tzc_id, tzc_build; 192*5d1638f3SJens Wiklander 193*5d1638f3SJens Wiklander assert(base); 194*5d1638f3SJens Wiklander tzc.base = base; 195*5d1638f3SJens Wiklander 196*5d1638f3SJens Wiklander /* 197*5d1638f3SJens Wiklander * We expect to see a tzc400. Check component ID. The TZC-400 TRM shows 198*5d1638f3SJens Wiklander * component ID is expected to be "0xB105F00D". 199*5d1638f3SJens Wiklander */ 200*5d1638f3SJens Wiklander tzc_id = tzc_read_component_id(tzc.base); 201*5d1638f3SJens Wiklander if (tzc_id != TZC400_COMPONENT_ID) { 202*5d1638f3SJens Wiklander EMSG("TZC : Wrong device ID (0x%x).\n", tzc_id); 203*5d1638f3SJens Wiklander panic(); 204*5d1638f3SJens Wiklander } 205*5d1638f3SJens Wiklander 206*5d1638f3SJens Wiklander /* Save values we will use later. */ 207*5d1638f3SJens Wiklander tzc_build = tzc_read_build_config(tzc.base); 208*5d1638f3SJens Wiklander tzc.num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) & 209*5d1638f3SJens Wiklander BUILD_CONFIG_NF_MASK) + 1; 210*5d1638f3SJens Wiklander tzc.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & 211*5d1638f3SJens Wiklander BUILD_CONFIG_AW_MASK) + 1; 212*5d1638f3SJens Wiklander tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & 213*5d1638f3SJens Wiklander BUILD_CONFIG_NR_MASK) + 1; 214*5d1638f3SJens Wiklander } 215*5d1638f3SJens Wiklander 216*5d1638f3SJens Wiklander static uint32_t addr_low(vaddr_t addr) 217*5d1638f3SJens Wiklander { 218*5d1638f3SJens Wiklander return (uint32_t)addr; 219*5d1638f3SJens Wiklander } 220*5d1638f3SJens Wiklander 221*5d1638f3SJens Wiklander static uint32_t addr_high(vaddr_t addr __unused) 222*5d1638f3SJens Wiklander { 223*5d1638f3SJens Wiklander #if (UINTPTR_MAX == UINT64_MAX) 224*5d1638f3SJens Wiklander return (addr >> 32); 225*5d1638f3SJens Wiklander #else 226*5d1638f3SJens Wiklander return 0; 227*5d1638f3SJens Wiklander #endif 228*5d1638f3SJens Wiklander } 229*5d1638f3SJens Wiklander 230*5d1638f3SJens Wiklander 231*5d1638f3SJens Wiklander /* 232*5d1638f3SJens Wiklander * `tzc_configure_region` is used to program regions into the TrustZone 233*5d1638f3SJens Wiklander * controller. A region can be associated with more than one filter. The 234*5d1638f3SJens Wiklander * associated filters are passed in as a bitmap (bit0 = filter0). 235*5d1638f3SJens Wiklander * NOTE: 236*5d1638f3SJens Wiklander * The region 0 covers the whole address space and is enabled on all filters, 237*5d1638f3SJens Wiklander * this cannot be changed. It is, however, possible to change some region 0 238*5d1638f3SJens Wiklander * permissions. 239*5d1638f3SJens Wiklander */ 240*5d1638f3SJens Wiklander void tzc_configure_region(uint32_t filters, 241*5d1638f3SJens Wiklander uint8_t region, 242*5d1638f3SJens Wiklander vaddr_t region_base, 243*5d1638f3SJens Wiklander vaddr_t region_top, 244*5d1638f3SJens Wiklander enum tzc_region_attributes sec_attr, 245*5d1638f3SJens Wiklander uint32_t ns_device_access) 246*5d1638f3SJens Wiklander { 247*5d1638f3SJens Wiklander assert(tzc.base); 248*5d1638f3SJens Wiklander 249*5d1638f3SJens Wiklander /* Do range checks on filters and regions. */ 250*5d1638f3SJens Wiklander assert(((filters >> tzc.num_filters) == 0) && 251*5d1638f3SJens Wiklander (region < tzc.num_regions)); 252*5d1638f3SJens Wiklander 253*5d1638f3SJens Wiklander /* 254*5d1638f3SJens Wiklander * Do address range check based on TZC configuration. A 64bit address is 255*5d1638f3SJens Wiklander * the max and expected case. 256*5d1638f3SJens Wiklander */ 257*5d1638f3SJens Wiklander #if (UINTPTR_MAX == UINT64_MAX) 258*5d1638f3SJens Wiklander assert(((region_top <= (UINT64_MAX >> (64 - tzc.addr_width))) && 259*5d1638f3SJens Wiklander (region_base < region_top))); 260*5d1638f3SJens Wiklander #endif 261*5d1638f3SJens Wiklander /* region_base and (region_top + 1) must be 4KB aligned */ 262*5d1638f3SJens Wiklander assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0); 263*5d1638f3SJens Wiklander 264*5d1638f3SJens Wiklander assert(sec_attr <= TZC_REGION_S_RDWR); 265*5d1638f3SJens Wiklander 266*5d1638f3SJens Wiklander /* 267*5d1638f3SJens Wiklander * Inputs look ok, start programming registers. 268*5d1638f3SJens Wiklander * All the address registers are 32 bits wide and have a LOW and HIGH 269*5d1638f3SJens Wiklander * component used to construct a up to a 64bit address. 270*5d1638f3SJens Wiklander */ 271*5d1638f3SJens Wiklander tzc_write_region_base_low(tzc.base, region, 272*5d1638f3SJens Wiklander addr_low(region_base)); 273*5d1638f3SJens Wiklander tzc_write_region_base_high(tzc.base, region, 274*5d1638f3SJens Wiklander addr_high(region_base)); 275*5d1638f3SJens Wiklander 276*5d1638f3SJens Wiklander tzc_write_region_top_low(tzc.base, region, 277*5d1638f3SJens Wiklander addr_low(region_top)); 278*5d1638f3SJens Wiklander tzc_write_region_top_high(tzc.base, region, 279*5d1638f3SJens Wiklander addr_high(region_top)); 280*5d1638f3SJens Wiklander 281*5d1638f3SJens Wiklander /* Assign the region to a filter and set secure attributes */ 282*5d1638f3SJens Wiklander tzc_write_region_attributes(tzc.base, region, 283*5d1638f3SJens Wiklander (sec_attr << REG_ATTR_SEC_SHIFT) | filters); 284*5d1638f3SJens Wiklander 285*5d1638f3SJens Wiklander /* 286*5d1638f3SJens Wiklander * Specify which non-secure devices have permission to access this 287*5d1638f3SJens Wiklander * region. 288*5d1638f3SJens Wiklander */ 289*5d1638f3SJens Wiklander tzc_write_region_id_access(tzc.base, region, ns_device_access); 290*5d1638f3SJens Wiklander } 291*5d1638f3SJens Wiklander 292*5d1638f3SJens Wiklander 293*5d1638f3SJens Wiklander void tzc_set_action(enum tzc_action action) 294*5d1638f3SJens Wiklander { 295*5d1638f3SJens Wiklander assert(tzc.base); 296*5d1638f3SJens Wiklander 297*5d1638f3SJens Wiklander /* 298*5d1638f3SJens Wiklander * - Currently no handler is provided to trap an error via interrupt 299*5d1638f3SJens Wiklander * or exception. 300*5d1638f3SJens Wiklander * - The interrupt action has not been tested. 301*5d1638f3SJens Wiklander */ 302*5d1638f3SJens Wiklander tzc_write_action(tzc.base, action); 303*5d1638f3SJens Wiklander } 304*5d1638f3SJens Wiklander 305*5d1638f3SJens Wiklander 306*5d1638f3SJens Wiklander void tzc_enable_filters(void) 307*5d1638f3SJens Wiklander { 308*5d1638f3SJens Wiklander uint32_t state; 309*5d1638f3SJens Wiklander uint32_t filter; 310*5d1638f3SJens Wiklander 311*5d1638f3SJens Wiklander assert(tzc.base); 312*5d1638f3SJens Wiklander 313*5d1638f3SJens Wiklander for (filter = 0; filter < tzc.num_filters; filter++) { 314*5d1638f3SJens Wiklander state = tzc_get_gate_keeper(tzc.base, filter); 315*5d1638f3SJens Wiklander if (state) { 316*5d1638f3SJens Wiklander /* 317*5d1638f3SJens Wiklander * The TZC filter is already configured. Changing the 318*5d1638f3SJens Wiklander * programmer's view in an active system can cause 319*5d1638f3SJens Wiklander * unpredictable behavior therefore panic for now rather 320*5d1638f3SJens Wiklander * than try to determine whether this is safe in this 321*5d1638f3SJens Wiklander * instance. See: 322*5d1638f3SJens Wiklander * http://infocenter.arm.com/help/index.jsp?\ 323*5d1638f3SJens Wiklander * topic=/com.arm.doc.ddi0504c/CJHHECBF.html 324*5d1638f3SJens Wiklander */ 325*5d1638f3SJens Wiklander EMSG("TZC : Filter %d Gatekeeper already enabled.\n", 326*5d1638f3SJens Wiklander filter); 327*5d1638f3SJens Wiklander panic(); 328*5d1638f3SJens Wiklander } 329*5d1638f3SJens Wiklander tzc_set_gate_keeper(tzc.base, filter, 1); 330*5d1638f3SJens Wiklander } 331*5d1638f3SJens Wiklander } 332*5d1638f3SJens Wiklander 333*5d1638f3SJens Wiklander 334*5d1638f3SJens Wiklander void tzc_disable_filters(void) 335*5d1638f3SJens Wiklander { 336*5d1638f3SJens Wiklander uint32_t filter; 337*5d1638f3SJens Wiklander 338*5d1638f3SJens Wiklander assert(tzc.base); 339*5d1638f3SJens Wiklander 340*5d1638f3SJens Wiklander /* 341*5d1638f3SJens Wiklander * We don't do the same state check as above as the Gatekeepers are 342*5d1638f3SJens Wiklander * disabled after reset. 343*5d1638f3SJens Wiklander */ 344*5d1638f3SJens Wiklander for (filter = 0; filter < tzc.num_filters; filter++) 345*5d1638f3SJens Wiklander tzc_set_gate_keeper(tzc.base, filter, 0); 346*5d1638f3SJens Wiklander } 347*5d1638f3SJens Wiklander 348*5d1638f3SJens Wiklander #if TRACE_LEVEL >= TRACE_DEBUG 349*5d1638f3SJens Wiklander 350*5d1638f3SJens Wiklander static uint32_t tzc_read_region_attributes(vaddr_t base, uint32_t region) 351*5d1638f3SJens Wiklander { 352*5d1638f3SJens Wiklander return read32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region)); 353*5d1638f3SJens Wiklander } 354*5d1638f3SJens Wiklander 355*5d1638f3SJens Wiklander static uint32_t tzc_read_region_base_low(vaddr_t base, uint32_t region) 356*5d1638f3SJens Wiklander { 357*5d1638f3SJens Wiklander return read32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region)); 358*5d1638f3SJens Wiklander } 359*5d1638f3SJens Wiklander 360*5d1638f3SJens Wiklander static uint32_t tzc_read_region_base_high(vaddr_t base, uint32_t region) 361*5d1638f3SJens Wiklander { 362*5d1638f3SJens Wiklander return read32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region)); 363*5d1638f3SJens Wiklander } 364*5d1638f3SJens Wiklander 365*5d1638f3SJens Wiklander static uint32_t tzc_read_region_top_low(vaddr_t base, uint32_t region) 366*5d1638f3SJens Wiklander { 367*5d1638f3SJens Wiklander return read32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region)); 368*5d1638f3SJens Wiklander } 369*5d1638f3SJens Wiklander 370*5d1638f3SJens Wiklander static uint32_t tzc_read_region_top_high(vaddr_t base, uint32_t region) 371*5d1638f3SJens Wiklander { 372*5d1638f3SJens Wiklander return read32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region)); 373*5d1638f3SJens Wiklander } 374*5d1638f3SJens Wiklander 375*5d1638f3SJens Wiklander #define REGION_MAX 8 376*5d1638f3SJens Wiklander static const __maybe_unused char * const tzc_attr_msg[] = { 377*5d1638f3SJens Wiklander "TZC_REGION_S_NONE", 378*5d1638f3SJens Wiklander "TZC_REGION_S_RD", 379*5d1638f3SJens Wiklander "TZC_REGION_S_WR", 380*5d1638f3SJens Wiklander "TZC_REGION_S_RDWR" 381*5d1638f3SJens Wiklander }; 382*5d1638f3SJens Wiklander 383*5d1638f3SJens Wiklander void tzc_dump_state(void) 384*5d1638f3SJens Wiklander { 385*5d1638f3SJens Wiklander uint32_t n; 386*5d1638f3SJens Wiklander uint32_t temp_32reg, temp_32reg_h; 387*5d1638f3SJens Wiklander 388*5d1638f3SJens Wiklander DMSG("enter"); 389*5d1638f3SJens Wiklander for (n = 0; n <= REGION_MAX; n++) { 390*5d1638f3SJens Wiklander temp_32reg = tzc_read_region_attributes(tzc.base, n); 391*5d1638f3SJens Wiklander if (!(temp_32reg & REG_ATTR_F_EN_MASK)) 392*5d1638f3SJens Wiklander continue; 393*5d1638f3SJens Wiklander 394*5d1638f3SJens Wiklander DMSG("\n"); 395*5d1638f3SJens Wiklander DMSG("region %d", n); 396*5d1638f3SJens Wiklander temp_32reg = tzc_read_region_base_low(tzc.base, n); 397*5d1638f3SJens Wiklander temp_32reg_h = tzc_read_region_base_high(tzc.base, n); 398*5d1638f3SJens Wiklander DMSG("region_base: 0x%08x%08x", temp_32reg_h, temp_32reg); 399*5d1638f3SJens Wiklander temp_32reg = tzc_read_region_top_low(tzc.base, n); 400*5d1638f3SJens Wiklander temp_32reg_h = tzc_read_region_top_high(tzc.base, n); 401*5d1638f3SJens Wiklander DMSG("region_top: 0x%08x%08x", temp_32reg_h, temp_32reg); 402*5d1638f3SJens Wiklander temp_32reg = tzc_read_region_attributes(tzc.base, n); 403*5d1638f3SJens Wiklander DMSG("secure rw: %s", 404*5d1638f3SJens Wiklander tzc_attr_msg[temp_32reg >> REG_ATTR_SEC_SHIFT]); 405*5d1638f3SJens Wiklander if (temp_32reg & (1 << 0)) 406*5d1638f3SJens Wiklander DMSG("filter 0 enable"); 407*5d1638f3SJens Wiklander if (temp_32reg & (1 << 1)) 408*5d1638f3SJens Wiklander DMSG("filter 1 enable"); 409*5d1638f3SJens Wiklander if (temp_32reg & (1 << 2)) 410*5d1638f3SJens Wiklander DMSG("filter 2 enable"); 411*5d1638f3SJens Wiklander if (temp_32reg & (1 << 3)) 412*5d1638f3SJens Wiklander DMSG("filter 3 enable"); 413*5d1638f3SJens Wiklander } 414*5d1638f3SJens Wiklander DMSG("exit"); 415*5d1638f3SJens Wiklander } 416*5d1638f3SJens Wiklander 417*5d1638f3SJens Wiklander #endif /* CFG_TRACE_LEVEL >= TRACE_DEBUG */ 418