1 /*
2 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef __TZC_COMMON_PRIVATE_H__
8 #define __TZC_COMMON_PRIVATE_H__
9
10 #include <arch.h>
11 #include <arch_helpers.h>
12 #include <mmio.h>
13 #include <tzc_common.h>
14
15 #define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \
16 static inline void _tzc##fn_name##_write_action( \
17 uintptr_t base, \
18 tzc_action_t action) \
19 { \
20 mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \
21 action); \
22 }
23
24 #define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \
25 static inline void _tzc##fn_name##_write_region_base( \
26 uintptr_t base, \
27 int region_no, \
28 unsigned long long region_base) \
29 { \
30 mmio_write_32(base + \
31 TZC_REGION_OFFSET( \
32 TZC_##macro_name##_REGION_SIZE, \
33 region_no) + \
34 TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \
35 (uint32_t)region_base); \
36 mmio_write_32(base + \
37 TZC_REGION_OFFSET( \
38 TZC_##macro_name##_REGION_SIZE, \
39 region_no) + \
40 TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \
41 (uint32_t)(region_base >> 32)); \
42 }
43
44 #define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \
45 static inline void _tzc##fn_name##_write_region_top( \
46 uintptr_t base, \
47 int region_no, \
48 unsigned long long region_top) \
49 { \
50 mmio_write_32(base + \
51 TZC_REGION_OFFSET \
52 (TZC_##macro_name##_REGION_SIZE, \
53 region_no) + \
54 TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \
55 (uint32_t)region_top); \
56 mmio_write_32(base + \
57 TZC_REGION_OFFSET( \
58 TZC_##macro_name##_REGION_SIZE, \
59 region_no) + \
60 TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \
61 (uint32_t)(region_top >> 32)); \
62 }
63
64 #define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \
65 static inline void _tzc##fn_name##_write_region_attributes( \
66 uintptr_t base, \
67 int region_no, \
68 unsigned int attr) \
69 { \
70 mmio_write_32(base + \
71 TZC_REGION_OFFSET( \
72 TZC_##macro_name##_REGION_SIZE, \
73 region_no) + \
74 TZC_##macro_name##_REGION_ATTR_0_OFFSET, \
75 attr); \
76 }
77
78 #define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \
79 static inline void _tzc##fn_name##_write_region_id_access( \
80 uintptr_t base, \
81 int region_no, \
82 unsigned int val) \
83 { \
84 mmio_write_32(base + \
85 TZC_REGION_OFFSET( \
86 TZC_##macro_name##_REGION_SIZE, \
87 region_no) + \
88 TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \
89 val); \
90 }
91
92 /*
93 * It is used to program region 0 ATTRIBUTES and ACCESS register.
94 */
95 #define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \
96 void _tzc##fn_name##_configure_region0(uintptr_t base, \
97 tzc_region_attributes_t sec_attr, \
98 unsigned int ns_device_access) \
99 { \
100 assert(base); \
101 VERBOSE("TrustZone : Configuring region 0 " \
102 "(TZC Interface Base=%p sec_attr=0x%x," \
103 " ns_devs=0x%x)\n", (void *)base, \
104 sec_attr, ns_device_access); \
105 \
106 /* Set secure attributes on region 0 */ \
107 _tzc##fn_name##_write_region_attributes(base, 0, \
108 sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \
109 \
110 /***************************************************/ \
111 /* Specify which non-secure devices have permission*/ \
112 /* to access region 0. */ \
113 /***************************************************/ \
114 _tzc##fn_name##_write_region_id_access(base, \
115 0, \
116 ns_device_access); \
117 }
118
119 /*
120 * It is used to program a region from 1 to 8 in the TrustZone controller.
121 * NOTE:
122 * Region 0 is special; it is preferable to use
123 * ##fn_name##_configure_region0 for this region (see comment for
124 * that function).
125 */
126 #define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \
127 void _tzc##fn_name##_configure_region(uintptr_t base, \
128 unsigned int filters, \
129 int region_no, \
130 unsigned long long region_base, \
131 unsigned long long region_top, \
132 tzc_region_attributes_t sec_attr, \
133 unsigned int nsaid_permissions) \
134 { \
135 assert(base); \
136 VERBOSE("TrustZone : Configuring region " \
137 "(TZC Interface Base: %p, region_no = %d)" \
138 "...\n", (void *)base, region_no); \
139 VERBOSE("TrustZone : ... base = %llx, top = %llx," \
140 "\n", region_base, region_top);\
141 VERBOSE("TrustZone : ... sec_attr = 0x%x," \
142 " ns_devs = 0x%x)\n", \
143 sec_attr, nsaid_permissions); \
144 \
145 /***************************************************/ \
146 /* Inputs look ok, start programming registers. */ \
147 /* All the address registers are 32 bits wide and */ \
148 /* have a LOW and HIGH */ \
149 /* component used to construct an address up to a */ \
150 /* 64bit. */ \
151 /***************************************************/ \
152 _tzc##fn_name##_write_region_base(base, \
153 region_no, region_base); \
154 _tzc##fn_name##_write_region_top(base, \
155 region_no, region_top); \
156 \
157 /* Enable filter to the region and set secure attributes */\
158 _tzc##fn_name##_write_region_attributes(base, \
159 region_no, \
160 (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\
161 (filters << TZC_REGION_ATTR_F_EN_SHIFT));\
162 \
163 /***************************************************/ \
164 /* Specify which non-secure devices have permission*/ \
165 /* to access this region. */ \
166 /***************************************************/ \
167 _tzc##fn_name##_write_region_id_access(base, \
168 region_no, \
169 nsaid_permissions); \
170 }
171
172 #if ENABLE_ASSERTIONS
173
_tzc_read_peripheral_id(uintptr_t base)174 static inline unsigned int _tzc_read_peripheral_id(uintptr_t base)
175 {
176 unsigned int id;
177
178 id = mmio_read_32(base + PID0_OFF);
179 /* Masks DESC part in PID1 */
180 id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8);
181
182 return id;
183 }
184
185 #ifdef AARCH32
_tzc_get_max_top_addr(int addr_width)186 static inline unsigned long long _tzc_get_max_top_addr(int addr_width)
187 {
188 /*
189 * Assume at least 32 bit wide address and initialize the max.
190 * This function doesn't use 64-bit integer arithmetic to avoid
191 * having to implement additional compiler library functions.
192 */
193 unsigned long long addr_mask = 0xFFFFFFFF;
194 uint32_t *addr_ptr = (uint32_t *)&addr_mask;
195
196 assert(addr_width >= 32);
197
198 /* This logic works only on little - endian platforms */
199 assert((read_sctlr() & SCTLR_EE_BIT) == 0);
200
201 /*
202 * If required address width is greater than 32, populate the higher
203 * 32 bits of the 64 bit field with the max address.
204 */
205 if (addr_width > 32)
206 *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1);
207
208 return addr_mask;
209 }
210 #else
211 #define _tzc_get_max_top_addr(addr_width)\
212 (UINT64_MAX >> (64 - (addr_width)))
213 #endif /* AARCH32 */
214
215 #endif /* ENABLE_ASSERTIONS */
216
217 #endif /* __TZC_COMMON_PRIVATE_H__ */
218