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