blob: ee278ec92c2c8f01d5426f0b996230ddc3b9607b [file] [log] [blame]
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +00001/*
Antonio Nino Diaz0ffc4492017-02-28 10:58:25 +00002 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
Antonio Nino Diaz0ffc4492017-02-28 10:58:25 +000031#ifndef __TZC_COMMON_PRIVATE_H__
32#define __TZC_COMMON_PRIVATE_H__
33
Soby Mathewd6452322016-05-05 13:59:07 +010034#include <arch.h>
35#include <arch_helpers.h>
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000036#include <mmio.h>
37#include <tzc_common.h>
38
39#define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \
40 static inline void _tzc##fn_name##_write_action( \
41 uintptr_t base, \
42 tzc_action_t action) \
43 { \
44 mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \
45 action); \
46 }
47
48#define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \
49 static inline void _tzc##fn_name##_write_region_base( \
Yatharth Kocharfc719752016-04-08 14:40:44 +010050 uintptr_t base, \
51 int region_no, \
52 unsigned long long region_base) \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000053 { \
54 mmio_write_32(base + \
55 TZC_REGION_OFFSET( \
56 TZC_##macro_name##_REGION_SIZE, \
57 region_no) + \
Yatharth Kocharfc719752016-04-08 14:40:44 +010058 TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \
59 (uint32_t)region_base); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000060 mmio_write_32(base + \
61 TZC_REGION_OFFSET( \
62 TZC_##macro_name##_REGION_SIZE, \
63 region_no) + \
64 TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \
Yatharth Kocharfc719752016-04-08 14:40:44 +010065 (uint32_t)(region_base >> 32)); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000066 }
67
68#define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \
69 static inline void _tzc##fn_name##_write_region_top( \
Yatharth Kocharfc719752016-04-08 14:40:44 +010070 uintptr_t base, \
71 int region_no, \
72 unsigned long long region_top) \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000073 { \
74 mmio_write_32(base + \
75 TZC_REGION_OFFSET \
76 (TZC_##macro_name##_REGION_SIZE, \
77 region_no) + \
78 TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \
Yatharth Kocharfc719752016-04-08 14:40:44 +010079 (uint32_t)region_top); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000080 mmio_write_32(base + \
81 TZC_REGION_OFFSET( \
82 TZC_##macro_name##_REGION_SIZE, \
83 region_no) + \
84 TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \
Yatharth Kocharfc719752016-04-08 14:40:44 +010085 (uint32_t)(region_top >> 32)); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000086 }
87
88#define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \
89 static inline void _tzc##fn_name##_write_region_attributes( \
90 uintptr_t base, \
91 int region_no, \
92 unsigned int attr) \
93 { \
94 mmio_write_32(base + \
95 TZC_REGION_OFFSET( \
96 TZC_##macro_name##_REGION_SIZE, \
97 region_no) + \
98 TZC_##macro_name##_REGION_ATTR_0_OFFSET, \
99 attr); \
100 }
101
102#define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \
103 static inline void _tzc##fn_name##_write_region_id_access( \
104 uintptr_t base, \
105 int region_no, \
106 unsigned int val) \
107 { \
108 mmio_write_32(base + \
109 TZC_REGION_OFFSET( \
110 TZC_##macro_name##_REGION_SIZE, \
111 region_no) + \
112 TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \
113 val); \
114 }
115
116/*
117 * It is used to program region 0 ATTRIBUTES and ACCESS register.
118 */
119#define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \
120 void _tzc##fn_name##_configure_region0(uintptr_t base, \
121 tzc_region_attributes_t sec_attr, \
122 unsigned int ns_device_access) \
123 { \
124 assert(base); \
125 VERBOSE("TrustZone : Configuring region 0 " \
126 "(TZC Interface Base=%p sec_attr=0x%x," \
127 " ns_devs=0x%x)\n", (void *)base, \
128 sec_attr, ns_device_access); \
129 \
130 /* Set secure attributes on region 0 */ \
131 _tzc##fn_name##_write_region_attributes(base, 0, \
132 sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \
133 \
134 /***************************************************/ \
135 /* Specify which non-secure devices have permission*/ \
136 /* to access region 0. */ \
137 /***************************************************/ \
138 _tzc##fn_name##_write_region_id_access(base, \
139 0, \
140 ns_device_access); \
141 }
142
143/*
144 * It is used to program a region from 1 to 8 in the TrustZone controller.
145 * NOTE:
146 * Region 0 is special; it is preferable to use
147 * ##fn_name##_configure_region0 for this region (see comment for
148 * that function).
149 */
150#define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \
151 void _tzc##fn_name##_configure_region(uintptr_t base, \
152 unsigned int filters, \
153 int region_no, \
Yatharth Kocharfc719752016-04-08 14:40:44 +0100154 unsigned long long region_base, \
155 unsigned long long region_top, \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +0000156 tzc_region_attributes_t sec_attr, \
157 unsigned int nsaid_permissions) \
158 { \
159 assert(base); \
160 VERBOSE("TrustZone : Configuring region " \
161 "(TZC Interface Base: %p, region_no = %d)" \
162 "...\n", (void *)base, region_no); \
Yatharth Kocharfc719752016-04-08 14:40:44 +0100163 VERBOSE("TrustZone : ... base = %llx, top = %llx," \
164 "\n", region_base, region_top);\
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +0000165 VERBOSE("TrustZone : ... sec_attr = 0x%x," \
166 " ns_devs = 0x%x)\n", \
167 sec_attr, nsaid_permissions); \
168 \
169 /***************************************************/ \
170 /* Inputs look ok, start programming registers. */ \
171 /* All the address registers are 32 bits wide and */ \
172 /* have a LOW and HIGH */ \
173 /* component used to construct an address up to a */ \
174 /* 64bit. */ \
175 /***************************************************/ \
176 _tzc##fn_name##_write_region_base(base, \
177 region_no, region_base); \
178 _tzc##fn_name##_write_region_top(base, \
179 region_no, region_top); \
180 \
181 /* Enable filter to the region and set secure attributes */\
182 _tzc##fn_name##_write_region_attributes(base, \
183 region_no, \
184 (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\
185 (filters << TZC_REGION_ATTR_F_EN_SHIFT));\
186 \
187 /***************************************************/ \
188 /* Specify which non-secure devices have permission*/ \
189 /* to access this region. */ \
190 /***************************************************/ \
191 _tzc##fn_name##_write_region_id_access(base, \
192 region_no, \
193 nsaid_permissions); \
194 }
195
Antonio Nino Diaz3759e3f2017-03-22 15:48:51 +0000196#if ENABLE_ASSERTIONS
197
Antonio Nino Diaz0ffc4492017-02-28 10:58:25 +0000198static inline unsigned int _tzc_read_peripheral_id(uintptr_t base)
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +0000199{
200 unsigned int id;
201
202 id = mmio_read_32(base + PID0_OFF);
203 /* Masks DESC part in PID1 */
204 id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8);
205
206 return id;
207}
Soby Mathewd6452322016-05-05 13:59:07 +0100208
209#ifdef AARCH32
Antonio Nino Diaz0ffc4492017-02-28 10:58:25 +0000210static inline unsigned long long _tzc_get_max_top_addr(int addr_width)
Soby Mathewd6452322016-05-05 13:59:07 +0100211{
212 /*
213 * Assume at least 32 bit wide address and initialize the max.
214 * This function doesn't use 64-bit integer arithmetic to avoid
215 * having to implement additional compiler library functions.
216 */
217 unsigned long long addr_mask = 0xFFFFFFFF;
218 uint32_t *addr_ptr = (uint32_t *)&addr_mask;
219
220 assert(addr_width >= 32);
221
222 /* This logic works only on little - endian platforms */
223 assert((read_sctlr() & SCTLR_EE_BIT) == 0);
224
225 /*
226 * If required address width is greater than 32, populate the higher
227 * 32 bits of the 64 bit field with the max address.
228 */
229 if (addr_width > 32)
230 *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1);
231
232 return addr_mask;
233}
234#else
235#define _tzc_get_max_top_addr(addr_width)\
236 (UINT64_MAX >> (64 - (addr_width)))
237#endif /* AARCH32 */
238
Antonio Nino Diaz3759e3f2017-03-22 15:48:51 +0000239#endif /* ENABLE_ASSERTIONS */
Antonio Nino Diaz0ffc4492017-02-28 10:58:25 +0000240
241#endif /* __TZC_COMMON_PRIVATE_H__ */