1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <stddef.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <common/debug.h> 11*91f16700Schasinglulu #include <drivers/arm/tzc380.h> 12*91f16700Schasinglulu #include <lib/mmio.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu struct tzc380_instance { 15*91f16700Schasinglulu uintptr_t base; 16*91f16700Schasinglulu uint8_t addr_width; 17*91f16700Schasinglulu uint8_t num_regions; 18*91f16700Schasinglulu }; 19*91f16700Schasinglulu 20*91f16700Schasinglulu struct tzc380_instance tzc380; 21*91f16700Schasinglulu 22*91f16700Schasinglulu static unsigned int tzc380_read_build_config(uintptr_t base) 23*91f16700Schasinglulu { 24*91f16700Schasinglulu return mmio_read_32(base + TZC380_CONFIGURATION_OFF); 25*91f16700Schasinglulu } 26*91f16700Schasinglulu 27*91f16700Schasinglulu static void tzc380_write_action(uintptr_t base, unsigned int action) 28*91f16700Schasinglulu { 29*91f16700Schasinglulu mmio_write_32(base + ACTION_OFF, action); 30*91f16700Schasinglulu } 31*91f16700Schasinglulu 32*91f16700Schasinglulu static void tzc380_write_region_base_low(uintptr_t base, unsigned int region, 33*91f16700Schasinglulu unsigned int val) 34*91f16700Schasinglulu { 35*91f16700Schasinglulu mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val); 36*91f16700Schasinglulu } 37*91f16700Schasinglulu 38*91f16700Schasinglulu static void tzc380_write_region_base_high(uintptr_t base, unsigned int region, 39*91f16700Schasinglulu unsigned int val) 40*91f16700Schasinglulu { 41*91f16700Schasinglulu mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val); 42*91f16700Schasinglulu } 43*91f16700Schasinglulu 44*91f16700Schasinglulu static void tzc380_write_region_attributes(uintptr_t base, unsigned int region, 45*91f16700Schasinglulu unsigned int val) 46*91f16700Schasinglulu { 47*91f16700Schasinglulu mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val); 48*91f16700Schasinglulu } 49*91f16700Schasinglulu 50*91f16700Schasinglulu void tzc380_init(uintptr_t base) 51*91f16700Schasinglulu { 52*91f16700Schasinglulu unsigned int tzc_build; 53*91f16700Schasinglulu 54*91f16700Schasinglulu assert(base != 0U); 55*91f16700Schasinglulu tzc380.base = base; 56*91f16700Schasinglulu 57*91f16700Schasinglulu /* Save values we will use later. */ 58*91f16700Schasinglulu tzc_build = tzc380_read_build_config(tzc380.base); 59*91f16700Schasinglulu tzc380.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & 60*91f16700Schasinglulu BUILD_CONFIG_AW_MASK) + 1; 61*91f16700Schasinglulu tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & 62*91f16700Schasinglulu BUILD_CONFIG_NR_MASK) + 1; 63*91f16700Schasinglulu } 64*91f16700Schasinglulu 65*91f16700Schasinglulu static uint32_t addr_low(uintptr_t addr) 66*91f16700Schasinglulu { 67*91f16700Schasinglulu return (uint32_t)addr; 68*91f16700Schasinglulu } 69*91f16700Schasinglulu 70*91f16700Schasinglulu static uint32_t addr_high(uintptr_t addr __unused) 71*91f16700Schasinglulu { 72*91f16700Schasinglulu #if (UINTPTR_MAX == UINT64_MAX) 73*91f16700Schasinglulu return addr >> 32; 74*91f16700Schasinglulu #else 75*91f16700Schasinglulu return 0; 76*91f16700Schasinglulu #endif 77*91f16700Schasinglulu } 78*91f16700Schasinglulu 79*91f16700Schasinglulu /* 80*91f16700Schasinglulu * `tzc380_configure_region` is used to program regions into the TrustZone 81*91f16700Schasinglulu * controller. 82*91f16700Schasinglulu */ 83*91f16700Schasinglulu void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr) 84*91f16700Schasinglulu { 85*91f16700Schasinglulu assert(tzc380.base != 0U); 86*91f16700Schasinglulu 87*91f16700Schasinglulu assert(region < tzc380.num_regions); 88*91f16700Schasinglulu 89*91f16700Schasinglulu tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base)); 90*91f16700Schasinglulu tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base)); 91*91f16700Schasinglulu tzc380_write_region_attributes(tzc380.base, region, attr); 92*91f16700Schasinglulu } 93*91f16700Schasinglulu 94*91f16700Schasinglulu void tzc380_set_action(unsigned int action) 95*91f16700Schasinglulu { 96*91f16700Schasinglulu assert(tzc380.base != 0U); 97*91f16700Schasinglulu 98*91f16700Schasinglulu /* 99*91f16700Schasinglulu * - Currently no handler is provided to trap an error via interrupt 100*91f16700Schasinglulu * or exception. 101*91f16700Schasinglulu * - The interrupt action has not been tested. 102*91f16700Schasinglulu */ 103*91f16700Schasinglulu tzc380_write_action(tzc380.base, action); 104*91f16700Schasinglulu } 105