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 <stddef.h> 9*09d40e0eSAntonio Nino Diaz 10*09d40e0eSAntonio Nino Diaz #include <common/debug.h> 11*09d40e0eSAntonio Nino Diaz #include <drivers/arm/tzc380.h> 12*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 1346f9b2c3SPeng Fan 1446f9b2c3SPeng Fan struct tzc380_instance { 1546f9b2c3SPeng Fan uintptr_t base; 1646f9b2c3SPeng Fan uint8_t addr_width; 1746f9b2c3SPeng Fan uint8_t num_regions; 1846f9b2c3SPeng Fan }; 1946f9b2c3SPeng Fan 2046f9b2c3SPeng Fan struct tzc380_instance tzc380; 2146f9b2c3SPeng Fan 2246f9b2c3SPeng Fan static unsigned int tzc380_read_build_config(uintptr_t base) 2346f9b2c3SPeng Fan { 2446f9b2c3SPeng Fan return mmio_read_32(base + TZC380_CONFIGURATION_OFF); 2546f9b2c3SPeng Fan } 2646f9b2c3SPeng Fan 2746f9b2c3SPeng Fan static void tzc380_write_action(uintptr_t base, tzc_action_t action) 2846f9b2c3SPeng Fan { 2946f9b2c3SPeng Fan mmio_write_32(base + ACTION_OFF, action); 3046f9b2c3SPeng Fan } 3146f9b2c3SPeng Fan 3246f9b2c3SPeng Fan static void tzc380_write_region_base_low(uintptr_t base, unsigned int region, 3346f9b2c3SPeng Fan unsigned int val) 3446f9b2c3SPeng Fan { 3546f9b2c3SPeng Fan mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val); 3646f9b2c3SPeng Fan } 3746f9b2c3SPeng Fan 3846f9b2c3SPeng Fan static void tzc380_write_region_base_high(uintptr_t base, unsigned int region, 3946f9b2c3SPeng Fan unsigned int val) 4046f9b2c3SPeng Fan { 4146f9b2c3SPeng Fan mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val); 4246f9b2c3SPeng Fan } 4346f9b2c3SPeng Fan 4446f9b2c3SPeng Fan static void tzc380_write_region_attributes(uintptr_t base, unsigned int region, 4546f9b2c3SPeng Fan unsigned int val) 4646f9b2c3SPeng Fan { 4746f9b2c3SPeng Fan mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val); 4846f9b2c3SPeng Fan } 4946f9b2c3SPeng Fan 5046f9b2c3SPeng Fan void tzc380_init(uintptr_t base) 5146f9b2c3SPeng Fan { 5246f9b2c3SPeng Fan unsigned int tzc_build; 5346f9b2c3SPeng Fan 54df54406dSAntonio Nino Diaz assert(base != 0U); 5546f9b2c3SPeng Fan tzc380.base = base; 5646f9b2c3SPeng Fan 5746f9b2c3SPeng Fan /* Save values we will use later. */ 5846f9b2c3SPeng Fan tzc_build = tzc380_read_build_config(tzc380.base); 5946f9b2c3SPeng Fan tzc380.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & 6046f9b2c3SPeng Fan BUILD_CONFIG_AW_MASK) + 1; 6146f9b2c3SPeng Fan tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & 6246f9b2c3SPeng Fan BUILD_CONFIG_NR_MASK) + 1; 6346f9b2c3SPeng Fan } 6446f9b2c3SPeng Fan 6546f9b2c3SPeng Fan static uint32_t addr_low(uintptr_t addr) 6646f9b2c3SPeng Fan { 6746f9b2c3SPeng Fan return (uint32_t)addr; 6846f9b2c3SPeng Fan } 6946f9b2c3SPeng Fan 7046f9b2c3SPeng Fan static uint32_t addr_high(uintptr_t addr __unused) 7146f9b2c3SPeng Fan { 7246f9b2c3SPeng Fan #if (UINTPTR_MAX == UINT64_MAX) 7346f9b2c3SPeng Fan return addr >> 32; 7446f9b2c3SPeng Fan #else 7546f9b2c3SPeng Fan return 0; 7646f9b2c3SPeng Fan #endif 7746f9b2c3SPeng Fan } 7846f9b2c3SPeng Fan 7946f9b2c3SPeng Fan /* 8046f9b2c3SPeng Fan * `tzc380_configure_region` is used to program regions into the TrustZone 8146f9b2c3SPeng Fan * controller. 8246f9b2c3SPeng Fan */ 8346f9b2c3SPeng Fan void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr) 8446f9b2c3SPeng Fan { 85df54406dSAntonio Nino Diaz assert(tzc380.base != 0U); 8646f9b2c3SPeng Fan 8746f9b2c3SPeng Fan assert(region < tzc380.num_regions); 8846f9b2c3SPeng Fan 8946f9b2c3SPeng Fan tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base)); 9046f9b2c3SPeng Fan tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base)); 9146f9b2c3SPeng Fan tzc380_write_region_attributes(tzc380.base, region, attr); 9246f9b2c3SPeng Fan } 9346f9b2c3SPeng Fan 9446f9b2c3SPeng Fan void tzc380_set_action(tzc_action_t action) 9546f9b2c3SPeng Fan { 96df54406dSAntonio Nino Diaz assert(tzc380.base != 0U); 9746f9b2c3SPeng Fan 9846f9b2c3SPeng Fan /* 9946f9b2c3SPeng Fan * - Currently no handler is provided to trap an error via interrupt 10046f9b2c3SPeng Fan * or exception. 10146f9b2c3SPeng Fan * - The interrupt action has not been tested. 10246f9b2c3SPeng Fan */ 10346f9b2c3SPeng Fan tzc380_write_action(tzc380.base, action); 10446f9b2c3SPeng Fan } 105