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