xref: /rk3399_ARM-atf/drivers/arm/tzc/tzc380.c (revision 81136819928e373f7753b88d81fa5c11700b11e1)
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