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