146f9b2c3SPeng Fan /* 246f9b2c3SPeng Fan * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 346f9b2c3SPeng Fan * 446f9b2c3SPeng Fan * SPDX-License-Identifier: BSD-3-Clause 546f9b2c3SPeng Fan */ 646f9b2c3SPeng Fan 746f9b2c3SPeng Fan #include <assert.h> 846f9b2c3SPeng Fan #include <debug.h> 946f9b2c3SPeng Fan #include <mmio.h> 1046f9b2c3SPeng Fan #include <stddef.h> 1146f9b2c3SPeng Fan #include <tzc380.h> 1246f9b2c3SPeng Fan 1346f9b2c3SPeng Fan struct tzc380_instance { 1446f9b2c3SPeng Fan uintptr_t base; 1546f9b2c3SPeng Fan uint8_t addr_width; 1646f9b2c3SPeng Fan uint8_t num_regions; 1746f9b2c3SPeng Fan }; 1846f9b2c3SPeng Fan 1946f9b2c3SPeng Fan struct tzc380_instance tzc380; 2046f9b2c3SPeng Fan 2146f9b2c3SPeng Fan static unsigned int tzc380_read_build_config(uintptr_t base) 2246f9b2c3SPeng Fan { 2346f9b2c3SPeng Fan return mmio_read_32(base + TZC380_CONFIGURATION_OFF); 2446f9b2c3SPeng Fan } 2546f9b2c3SPeng Fan 2646f9b2c3SPeng Fan static void tzc380_write_action(uintptr_t base, tzc_action_t action) 2746f9b2c3SPeng Fan { 2846f9b2c3SPeng Fan mmio_write_32(base + ACTION_OFF, action); 2946f9b2c3SPeng Fan } 3046f9b2c3SPeng Fan 3146f9b2c3SPeng Fan static void tzc380_write_region_base_low(uintptr_t base, unsigned int region, 3246f9b2c3SPeng Fan unsigned int val) 3346f9b2c3SPeng Fan { 3446f9b2c3SPeng Fan mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val); 3546f9b2c3SPeng Fan } 3646f9b2c3SPeng Fan 3746f9b2c3SPeng Fan static void tzc380_write_region_base_high(uintptr_t base, unsigned int region, 3846f9b2c3SPeng Fan unsigned int val) 3946f9b2c3SPeng Fan { 4046f9b2c3SPeng Fan mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val); 4146f9b2c3SPeng Fan } 4246f9b2c3SPeng Fan 4346f9b2c3SPeng Fan static void tzc380_write_region_attributes(uintptr_t base, unsigned int region, 4446f9b2c3SPeng Fan unsigned int val) 4546f9b2c3SPeng Fan { 4646f9b2c3SPeng Fan mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val); 4746f9b2c3SPeng Fan } 4846f9b2c3SPeng Fan 4946f9b2c3SPeng Fan void tzc380_init(uintptr_t base) 5046f9b2c3SPeng Fan { 5146f9b2c3SPeng Fan unsigned int tzc_build; 5246f9b2c3SPeng Fan 53*df54406dSAntonio Nino Diaz assert(base != 0U); 5446f9b2c3SPeng Fan tzc380.base = base; 5546f9b2c3SPeng Fan 5646f9b2c3SPeng Fan /* Save values we will use later. */ 5746f9b2c3SPeng Fan tzc_build = tzc380_read_build_config(tzc380.base); 5846f9b2c3SPeng Fan tzc380.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & 5946f9b2c3SPeng Fan BUILD_CONFIG_AW_MASK) + 1; 6046f9b2c3SPeng Fan tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & 6146f9b2c3SPeng Fan BUILD_CONFIG_NR_MASK) + 1; 6246f9b2c3SPeng Fan } 6346f9b2c3SPeng Fan 6446f9b2c3SPeng Fan static uint32_t addr_low(uintptr_t addr) 6546f9b2c3SPeng Fan { 6646f9b2c3SPeng Fan return (uint32_t)addr; 6746f9b2c3SPeng Fan } 6846f9b2c3SPeng Fan 6946f9b2c3SPeng Fan static uint32_t addr_high(uintptr_t addr __unused) 7046f9b2c3SPeng Fan { 7146f9b2c3SPeng Fan #if (UINTPTR_MAX == UINT64_MAX) 7246f9b2c3SPeng Fan return addr >> 32; 7346f9b2c3SPeng Fan #else 7446f9b2c3SPeng Fan return 0; 7546f9b2c3SPeng Fan #endif 7646f9b2c3SPeng Fan } 7746f9b2c3SPeng Fan 7846f9b2c3SPeng Fan /* 7946f9b2c3SPeng Fan * `tzc380_configure_region` is used to program regions into the TrustZone 8046f9b2c3SPeng Fan * controller. 8146f9b2c3SPeng Fan */ 8246f9b2c3SPeng Fan void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr) 8346f9b2c3SPeng Fan { 84*df54406dSAntonio Nino Diaz assert(tzc380.base != 0U); 8546f9b2c3SPeng Fan 8646f9b2c3SPeng Fan assert(region < tzc380.num_regions); 8746f9b2c3SPeng Fan 8846f9b2c3SPeng Fan tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base)); 8946f9b2c3SPeng Fan tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base)); 9046f9b2c3SPeng Fan tzc380_write_region_attributes(tzc380.base, region, attr); 9146f9b2c3SPeng Fan } 9246f9b2c3SPeng Fan 9346f9b2c3SPeng Fan void tzc380_set_action(tzc_action_t action) 9446f9b2c3SPeng Fan { 95*df54406dSAntonio Nino Diaz assert(tzc380.base != 0U); 9646f9b2c3SPeng Fan 9746f9b2c3SPeng Fan /* 9846f9b2c3SPeng Fan * - Currently no handler is provided to trap an error via interrupt 9946f9b2c3SPeng Fan * or exception. 10046f9b2c3SPeng Fan * - The interrupt action has not been tested. 10146f9b2c3SPeng Fan */ 10246f9b2c3SPeng Fan tzc380_write_action(tzc380.base, action); 10346f9b2c3SPeng Fan } 104