blob: 8b1ddf498fff2ffc897d8dcdd50721a7d680a017 [file] [log] [blame]
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +00001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
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
Soby Mathewd6452322016-05-05 13:59:07 +010031#include <arch.h>
32#include <arch_helpers.h>
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000033#include <mmio.h>
34#include <tzc_common.h>
35
36#define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \
37 static inline void _tzc##fn_name##_write_action( \
38 uintptr_t base, \
39 tzc_action_t action) \
40 { \
41 mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \
42 action); \
43 }
44
45#define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \
46 static inline void _tzc##fn_name##_write_region_base( \
Yatharth Kocharfc719752016-04-08 14:40:44 +010047 uintptr_t base, \
48 int region_no, \
49 unsigned long long region_base) \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000050 { \
51 mmio_write_32(base + \
52 TZC_REGION_OFFSET( \
53 TZC_##macro_name##_REGION_SIZE, \
54 region_no) + \
Yatharth Kocharfc719752016-04-08 14:40:44 +010055 TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \
56 (uint32_t)region_base); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000057 mmio_write_32(base + \
58 TZC_REGION_OFFSET( \
59 TZC_##macro_name##_REGION_SIZE, \
60 region_no) + \
61 TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \
Yatharth Kocharfc719752016-04-08 14:40:44 +010062 (uint32_t)(region_base >> 32)); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000063 }
64
65#define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \
66 static inline void _tzc##fn_name##_write_region_top( \
Yatharth Kocharfc719752016-04-08 14:40:44 +010067 uintptr_t base, \
68 int region_no, \
69 unsigned long long region_top) \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000070 { \
71 mmio_write_32(base + \
72 TZC_REGION_OFFSET \
73 (TZC_##macro_name##_REGION_SIZE, \
74 region_no) + \
75 TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \
Yatharth Kocharfc719752016-04-08 14:40:44 +010076 (uint32_t)region_top); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000077 mmio_write_32(base + \
78 TZC_REGION_OFFSET( \
79 TZC_##macro_name##_REGION_SIZE, \
80 region_no) + \
81 TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \
Yatharth Kocharfc719752016-04-08 14:40:44 +010082 (uint32_t)(region_top >> 32)); \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +000083 }
84
85#define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \
86 static inline void _tzc##fn_name##_write_region_attributes( \
87 uintptr_t base, \
88 int region_no, \
89 unsigned int attr) \
90 { \
91 mmio_write_32(base + \
92 TZC_REGION_OFFSET( \
93 TZC_##macro_name##_REGION_SIZE, \
94 region_no) + \
95 TZC_##macro_name##_REGION_ATTR_0_OFFSET, \
96 attr); \
97 }
98
99#define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \
100 static inline void _tzc##fn_name##_write_region_id_access( \
101 uintptr_t base, \
102 int region_no, \
103 unsigned int val) \
104 { \
105 mmio_write_32(base + \
106 TZC_REGION_OFFSET( \
107 TZC_##macro_name##_REGION_SIZE, \
108 region_no) + \
109 TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \
110 val); \
111 }
112
113/*
114 * It is used to program region 0 ATTRIBUTES and ACCESS register.
115 */
116#define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \
117 void _tzc##fn_name##_configure_region0(uintptr_t base, \
118 tzc_region_attributes_t sec_attr, \
119 unsigned int ns_device_access) \
120 { \
121 assert(base); \
122 VERBOSE("TrustZone : Configuring region 0 " \
123 "(TZC Interface Base=%p sec_attr=0x%x," \
124 " ns_devs=0x%x)\n", (void *)base, \
125 sec_attr, ns_device_access); \
126 \
127 /* Set secure attributes on region 0 */ \
128 _tzc##fn_name##_write_region_attributes(base, 0, \
129 sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \
130 \
131 /***************************************************/ \
132 /* Specify which non-secure devices have permission*/ \
133 /* to access region 0. */ \
134 /***************************************************/ \
135 _tzc##fn_name##_write_region_id_access(base, \
136 0, \
137 ns_device_access); \
138 }
139
140/*
141 * It is used to program a region from 1 to 8 in the TrustZone controller.
142 * NOTE:
143 * Region 0 is special; it is preferable to use
144 * ##fn_name##_configure_region0 for this region (see comment for
145 * that function).
146 */
147#define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \
148 void _tzc##fn_name##_configure_region(uintptr_t base, \
149 unsigned int filters, \
150 int region_no, \
Yatharth Kocharfc719752016-04-08 14:40:44 +0100151 unsigned long long region_base, \
152 unsigned long long region_top, \
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +0000153 tzc_region_attributes_t sec_attr, \
154 unsigned int nsaid_permissions) \
155 { \
156 assert(base); \
157 VERBOSE("TrustZone : Configuring region " \
158 "(TZC Interface Base: %p, region_no = %d)" \
159 "...\n", (void *)base, region_no); \
Yatharth Kocharfc719752016-04-08 14:40:44 +0100160 VERBOSE("TrustZone : ... base = %llx, top = %llx," \
161 "\n", region_base, region_top);\
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +0000162 VERBOSE("TrustZone : ... sec_attr = 0x%x," \
163 " ns_devs = 0x%x)\n", \
164 sec_attr, nsaid_permissions); \
165 \
166 /***************************************************/ \
167 /* Inputs look ok, start programming registers. */ \
168 /* All the address registers are 32 bits wide and */ \
169 /* have a LOW and HIGH */ \
170 /* component used to construct an address up to a */ \
171 /* 64bit. */ \
172 /***************************************************/ \
173 _tzc##fn_name##_write_region_base(base, \
174 region_no, region_base); \
175 _tzc##fn_name##_write_region_top(base, \
176 region_no, region_top); \
177 \
178 /* Enable filter to the region and set secure attributes */\
179 _tzc##fn_name##_write_region_attributes(base, \
180 region_no, \
181 (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\
182 (filters << TZC_REGION_ATTR_F_EN_SHIFT));\
183 \
184 /***************************************************/ \
185 /* Specify which non-secure devices have permission*/ \
186 /* to access this region. */ \
187 /***************************************************/ \
188 _tzc##fn_name##_write_region_id_access(base, \
189 region_no, \
190 nsaid_permissions); \
191 }
192
193#if DEBUG
194static unsigned int _tzc_read_peripheral_id(uintptr_t base)
195{
196 unsigned int id;
197
198 id = mmio_read_32(base + PID0_OFF);
199 /* Masks DESC part in PID1 */
200 id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8);
201
202 return id;
203}
Soby Mathewd6452322016-05-05 13:59:07 +0100204
205#ifdef AARCH32
206static unsigned long long _tzc_get_max_top_addr(int addr_width)
207{
208 /*
209 * Assume at least 32 bit wide address and initialize the max.
210 * This function doesn't use 64-bit integer arithmetic to avoid
211 * having to implement additional compiler library functions.
212 */
213 unsigned long long addr_mask = 0xFFFFFFFF;
214 uint32_t *addr_ptr = (uint32_t *)&addr_mask;
215
216 assert(addr_width >= 32);
217
218 /* This logic works only on little - endian platforms */
219 assert((read_sctlr() & SCTLR_EE_BIT) == 0);
220
221 /*
222 * If required address width is greater than 32, populate the higher
223 * 32 bits of the 64 bit field with the max address.
224 */
225 if (addr_width > 32)
226 *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1);
227
228 return addr_mask;
229}
230#else
231#define _tzc_get_max_top_addr(addr_width)\
232 (UINT64_MAX >> (64 - (addr_width)))
233#endif /* AARCH32 */
234
Vikram Kanigiri1eabdbc2016-01-28 17:22:16 +0000235#endif