1 // SPDX-License-Identifier: (BSD-2-Clause AND BSD-3-Clause)
2 /*
3 * Copyright (c) 2015, Linaro Limited
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 /*
29 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions are met:
33 *
34 * Redistributions of source code must retain the above copyright notice, this
35 * list of conditions and the following disclaimer.
36 *
37 * Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following disclaimer in the documentation
39 * and/or other materials provided with the distribution.
40 *
41 * Neither the name of ARM nor the names of its contributors may be used
42 * to endorse or promote products derived from this software without specific
43 * prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
49 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55 * POSSIBILITY OF SUCH DAMAGE.
56 */
57
58 #include <assert.h>
59 #include <drivers/tzc400.h>
60 #include <io.h>
61 #include <kernel/panic.h>
62 #include <stddef.h>
63 #include <trace.h>
64 #include <util.h>
65
66 /*
67 * Implementation defined values used to validate inputs later.
68 * Filters : max of 4 ; 0 to 3
69 * Regions : max of 9 ; 0 to 8
70 * Address width : Values between 32 to 64
71 */
72 struct tzc_instance {
73 vaddr_t base;
74 uint8_t addr_width;
75 uint8_t num_filters;
76 uint8_t num_regions;
77 };
78
79 static struct tzc_instance tzc;
80
81
tzc_read_build_config(vaddr_t base)82 static uint32_t tzc_read_build_config(vaddr_t base)
83 {
84 return io_read32(base + BUILD_CONFIG_OFF);
85 }
86
tzc_read_gate_keeper(vaddr_t base)87 static uint32_t tzc_read_gate_keeper(vaddr_t base)
88 {
89 return io_read32(base + GATE_KEEPER_OFF);
90 }
91
tzc_write_gate_keeper(vaddr_t base,uint32_t val)92 static void tzc_write_gate_keeper(vaddr_t base, uint32_t val)
93 {
94 io_write32(base + GATE_KEEPER_OFF, val);
95 }
96
tzc_write_action(vaddr_t base,enum tzc_action action)97 static void tzc_write_action(vaddr_t base, enum tzc_action action)
98 {
99 io_write32(base + ACTION_OFF, action);
100 }
101
tzc_read_region_base_low(vaddr_t base,uint32_t region)102 static uint32_t tzc_read_region_base_low(vaddr_t base, uint32_t region)
103 {
104 return io_read32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region));
105 }
106
tzc_write_region_base_low(vaddr_t base,uint32_t region,uint32_t val)107 static void tzc_write_region_base_low(vaddr_t base, uint32_t region,
108 uint32_t val)
109 {
110 io_write32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region), val);
111 }
112
tzc_read_region_base_high(vaddr_t base,uint32_t region)113 static uint32_t tzc_read_region_base_high(vaddr_t base, uint32_t region)
114 {
115 return io_read32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region));
116 }
117
tzc_write_region_base_high(vaddr_t base,uint32_t region,uint32_t val)118 static void tzc_write_region_base_high(vaddr_t base, uint32_t region,
119 uint32_t val)
120 {
121 io_write32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region), val);
122 }
123
tzc_read_region_top_low(vaddr_t base,uint32_t region)124 static uint32_t tzc_read_region_top_low(vaddr_t base, uint32_t region)
125 {
126 return io_read32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region));
127 }
128
tzc_write_region_top_low(vaddr_t base,uint32_t region,uint32_t val)129 static void tzc_write_region_top_low(vaddr_t base, uint32_t region,
130 uint32_t val)
131 {
132 io_write32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region), val);
133 }
134
tzc_read_region_top_high(vaddr_t base,uint32_t region)135 static uint32_t tzc_read_region_top_high(vaddr_t base, uint32_t region)
136 {
137 return io_read32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region));
138 }
139
tzc_write_region_top_high(vaddr_t base,uint32_t region,uint32_t val)140 static void tzc_write_region_top_high(vaddr_t base, uint32_t region,
141 uint32_t val)
142 {
143 io_write32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region), val);
144 }
145
tzc_read_region_attributes(vaddr_t base,uint32_t region)146 static uint32_t tzc_read_region_attributes(vaddr_t base, uint32_t region)
147 {
148 return io_read32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region));
149 }
150
tzc_write_region_attributes(vaddr_t base,uint32_t region,uint32_t val)151 static void tzc_write_region_attributes(vaddr_t base, uint32_t region,
152 uint32_t val)
153 {
154 io_write32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region), val);
155 }
156
tzc_read_region_id_access(vaddr_t base,uint32_t region)157 static uint32_t tzc_read_region_id_access(vaddr_t base, uint32_t region)
158 {
159 return io_read32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region));
160 }
161
tzc_write_region_id_access(vaddr_t base,uint32_t region,uint32_t val)162 static void tzc_write_region_id_access(vaddr_t base, uint32_t region,
163 uint32_t val)
164 {
165 io_write32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region), val);
166 }
167
tzc_read_component_id(vaddr_t base)168 static uint32_t tzc_read_component_id(vaddr_t base)
169 {
170 uint32_t id;
171
172 id = io_read8(base + CID0_OFF);
173 id |= SHIFT_U32(io_read8(base + CID1_OFF), 8);
174 id |= SHIFT_U32(io_read8(base + CID2_OFF), 16);
175 id |= SHIFT_U32(io_read8(base + CID3_OFF), 24);
176
177 return id;
178 }
179
tzc_get_gate_keeper(vaddr_t base,uint8_t filter)180 static uint32_t tzc_get_gate_keeper(vaddr_t base, uint8_t filter)
181 {
182 uint32_t tmp;
183
184 tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
185 GATE_KEEPER_OS_MASK;
186
187 return (tmp >> filter) & GATE_KEEPER_FILTER_MASK;
188 }
189
190 /* This function is not MP safe. */
tzc_set_gate_keeper(vaddr_t base,uint8_t filter,uint32_t val)191 static void tzc_set_gate_keeper(vaddr_t base, uint8_t filter, uint32_t val)
192 {
193 uint32_t tmp;
194
195 /* Upper half is current state. Lower half is requested state. */
196 tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
197 GATE_KEEPER_OS_MASK;
198
199 if (val)
200 tmp |= (1 << filter);
201 else
202 tmp &= ~(1 << filter);
203
204 tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) <<
205 GATE_KEEPER_OR_SHIFT);
206
207 /* Wait here until we see the change reflected in the TZC status. */
208 while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
209 GATE_KEEPER_OS_MASK) != tmp)
210 ;
211 }
212
213
tzc_init(vaddr_t base)214 void tzc_init(vaddr_t base)
215 {
216 uint32_t tzc_id, tzc_build;
217
218 assert(base);
219 tzc.base = base;
220
221 /*
222 * We expect to see a tzc400. Check component ID. The TZC-400 TRM shows
223 * component ID is expected to be "0xB105F00D".
224 */
225 tzc_id = tzc_read_component_id(tzc.base);
226 if (tzc_id != TZC400_COMPONENT_ID) {
227 EMSG("TZC : Wrong device ID (0x%" PRIx32 ")", tzc_id);
228 panic();
229 }
230
231 /* Save values we will use later. */
232 tzc_build = tzc_read_build_config(tzc.base);
233 tzc.num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) &
234 BUILD_CONFIG_NF_MASK) + 1;
235 tzc.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
236 BUILD_CONFIG_AW_MASK) + 1;
237 tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
238 BUILD_CONFIG_NR_MASK) + 1;
239 }
240
addr_low(vaddr_t addr)241 static uint32_t addr_low(vaddr_t addr)
242 {
243 return (uint32_t)addr;
244 }
245
addr_high(vaddr_t addr __unused)246 static uint32_t addr_high(vaddr_t addr __unused)
247 {
248 #if (UINTPTR_MAX == UINT64_MAX)
249 return (addr >> 32);
250 #else
251 return 0;
252 #endif
253 }
254
255
256 /*
257 * `tzc_configure_region` is used to program regions into the TrustZone
258 * controller. A region can be associated with more than one filter. The
259 * associated filters are passed in as a bitmap (bit0 = filter0).
260 * NOTE:
261 * The region 0 covers the whole address space and is enabled on all filters,
262 * this cannot be changed. It is, however, possible to change some region 0
263 * permissions.
264 */
tzc_configure_region(uint8_t region,const struct tzc_region_config * cfg)265 void tzc_configure_region(uint8_t region, const struct tzc_region_config *cfg)
266 {
267 assert(tzc.base && cfg);
268
269 /* Do range checks on filters and regions. */
270 assert(((cfg->filters >> tzc.num_filters) == 0) &&
271 (region < tzc.num_regions));
272
273 /*
274 * Do address range check based on TZC configuration. A 64bit address is
275 * the max and expected case.
276 */
277 #if (UINTPTR_MAX == UINT64_MAX)
278 assert(((cfg->top <= (UINT64_MAX >> (64 - tzc.addr_width))) &&
279 (cfg->base < cfg->top)));
280 #endif
281 /* region_base and (region_top + 1) must be 4KB aligned */
282 assert(((cfg->base | (cfg->top + 1)) & (4096 - 1)) == 0);
283
284 assert(cfg->sec_attr <= TZC_REGION_S_RDWR);
285
286 /*
287 * Inputs look ok, start programming registers.
288 * All the address registers are 32 bits wide and have a LOW and HIGH
289 * component used to construct a up to a 64bit address.
290 */
291 tzc_write_region_base_low(tzc.base, region, addr_low(cfg->base));
292 tzc_write_region_base_high(tzc.base, region, addr_high(cfg->base));
293
294 tzc_write_region_top_low(tzc.base, region, addr_low(cfg->top));
295 tzc_write_region_top_high(tzc.base, region, addr_high(cfg->top));
296
297 /* Assign the region to a filter and set secure attributes */
298 tzc_write_region_attributes(tzc.base, region,
299 (cfg->sec_attr << REG_ATTR_SEC_SHIFT) |
300 cfg->filters);
301
302 /*
303 * Specify which non-secure devices have permission to access this
304 * region.
305 */
306 tzc_write_region_id_access(tzc.base, region, cfg->ns_device_access);
307 }
308
tzc_get_region_config(uint8_t region,struct tzc_region_config * cfg)309 TEE_Result tzc_get_region_config(uint8_t region, struct tzc_region_config *cfg)
310 {
311 uint32_t val32 = 0;
312
313 if (region >= tzc.num_regions)
314 return TEE_ERROR_GENERIC;
315
316 cfg->base = reg_pair_to_64(tzc_read_region_base_high(tzc.base, region),
317 tzc_read_region_base_low(tzc.base, region));
318 cfg->top = reg_pair_to_64(tzc_read_region_top_high(tzc.base, region),
319 tzc_read_region_top_low(tzc.base, region));
320
321 cfg->ns_device_access = tzc_read_region_id_access(tzc.base, region);
322
323 val32 = tzc_read_region_attributes(tzc.base, region);
324 cfg->sec_attr = val32 >> REG_ATTR_SEC_SHIFT;
325 cfg->filters = val32 & REG_ATTR_F_EN_MASK;
326
327 return TEE_SUCCESS;
328 }
329
tzc_set_action(enum tzc_action action)330 void tzc_set_action(enum tzc_action action)
331 {
332 assert(tzc.base);
333
334 /*
335 * - Currently no handler is provided to trap an error via interrupt
336 * or exception.
337 * - The interrupt action has not been tested.
338 */
339 tzc_write_action(tzc.base, action);
340 }
341
342
tzc_enable_filters(void)343 void tzc_enable_filters(void)
344 {
345 uint32_t state;
346 uint32_t filter;
347
348 assert(tzc.base);
349
350 for (filter = 0; filter < tzc.num_filters; filter++) {
351 state = tzc_get_gate_keeper(tzc.base, filter);
352 if (state) {
353 /*
354 * The TZC filter is already configured. Changing the
355 * programmer's view in an active system can cause
356 * unpredictable behavior therefore panic for now rather
357 * than try to determine whether this is safe in this
358 * instance. See:
359 * http://infocenter.arm.com/help/index.jsp?\
360 * topic=/com.arm.doc.ddi0504c/CJHHECBF.html
361 */
362 EMSG("TZC : Filter %d Gatekeeper already enabled",
363 filter);
364 panic();
365 }
366 tzc_set_gate_keeper(tzc.base, filter, 1);
367 }
368 }
369
370
tzc_disable_filters(void)371 void tzc_disable_filters(void)
372 {
373 uint32_t filter;
374
375 assert(tzc.base);
376
377 /*
378 * We don't do the same state check as above as the Gatekeepers are
379 * disabled after reset.
380 */
381 for (filter = 0; filter < tzc.num_filters; filter++)
382 tzc_set_gate_keeper(tzc.base, filter, 0);
383 }
384
write_not_read(unsigned int filter)385 static bool __maybe_unused write_not_read(unsigned int filter)
386 {
387 return io_read32(tzc.base + FAIL_CONTROL(filter)) &
388 FAIL_CONTROL_DIRECTION_WRITE;
389 }
390
nonsecure_not_secure(unsigned int filter)391 static bool __maybe_unused nonsecure_not_secure(unsigned int filter)
392 {
393 return io_read32(tzc.base + FAIL_CONTROL(filter)) &
394 FAIL_CONTROL_NONSECURE;
395 }
396
priv_not_unpriv(unsigned int filter)397 static bool __maybe_unused priv_not_unpriv(unsigned int filter)
398 {
399 return io_read32(tzc.base + FAIL_CONTROL(filter)) &
400 FAIL_CONTROL_PRIVILEGED;
401 }
402
dump_fail_filter(unsigned int filter)403 static void dump_fail_filter(unsigned int filter)
404 {
405 uint64_t __maybe_unused addr = 0;
406 uint32_t status = io_read32(tzc.base + INT_STATUS);
407
408 if (!(status & BIT(filter + INT_STATUS_OVERLAP_SHIFT)) &&
409 !(status & BIT(filter + INT_STATUS_OVERRUN_SHIFT)) &&
410 !(status & BIT(filter + INT_STATUS_STATUS_SHIFT)))
411 return;
412
413 if (status & BIT(filter + INT_STATUS_OVERLAP_SHIFT))
414 EMSG("Overlap violation on filter %u", filter);
415
416 if (status & BIT(filter + INT_STATUS_OVERRUN_SHIFT))
417 EMSG("Overrun violation on filter %u", filter);
418
419 if (status & BIT(filter + INT_STATUS_STATUS_SHIFT))
420 EMSG("Permission violation on filter %u", filter);
421
422 addr = reg_pair_to_64(io_read32(tzc.base + FAIL_ADDRESS_HIGH(filter)),
423 io_read32(tzc.base + FAIL_ADDRESS_LOW(filter)));
424
425 EMSG("Violation @0x%"PRIx64", %ssecure %sprivileged %s, AXI ID %"PRIx32,
426 addr,
427 nonsecure_not_secure(filter) ? "non-" : "",
428 priv_not_unpriv(filter) ? "" : "un",
429 write_not_read(filter) ? "write" : "read",
430 io_read32(tzc.base + FAIL_ID(filter)));
431 }
432
433 /*
434 * Dump info when TZC400 catches an unallowed access with TZC
435 * interrupt enabled.
436 */
tzc_fail_dump(void)437 void tzc_fail_dump(void)
438 {
439 unsigned int filter = 0;
440
441 for (filter = 0; filter < tzc.num_filters; filter++)
442 dump_fail_filter(filter);
443 }
444
tzc_int_clear(void)445 void tzc_int_clear(void)
446 {
447 assert(tzc.base);
448
449 io_setbits32(tzc.base + INT_CLEAR, GENMASK_32(tzc.num_filters - 1, 0));
450 }
451
452 #if TRACE_LEVEL >= TRACE_DEBUG
453
454 #define REGION_MAX 8
455 static const __maybe_unused char * const tzc_attr_msg[] = {
456 "TZC_REGION_S_NONE",
457 "TZC_REGION_S_RD",
458 "TZC_REGION_S_WR",
459 "TZC_REGION_S_RDWR"
460 };
461
tzc_dump_state(void)462 void tzc_dump_state(void)
463 {
464 uint32_t n;
465 uint32_t temp_32reg, temp_32reg_h;
466 unsigned int filter = 0;
467
468 for (n = 0; n <= REGION_MAX; n++) {
469 temp_32reg = tzc_read_region_attributes(tzc.base, n);
470 if (!(temp_32reg & REG_ATTR_F_EN_MASK))
471 continue;
472
473 DMSG("region %d", n);
474 temp_32reg = tzc_read_region_base_low(tzc.base, n);
475 temp_32reg_h = tzc_read_region_base_high(tzc.base, n);
476 DMSG("region_base: 0x%08x%08x", temp_32reg_h, temp_32reg);
477 temp_32reg = tzc_read_region_top_low(tzc.base, n);
478 temp_32reg_h = tzc_read_region_top_high(tzc.base, n);
479 DMSG("region_top: 0x%08x%08x", temp_32reg_h, temp_32reg);
480 temp_32reg = tzc_read_region_attributes(tzc.base, n);
481 DMSG("secure rw: %s",
482 tzc_attr_msg[temp_32reg >> REG_ATTR_SEC_SHIFT]);
483
484 for (filter = 0; filter < tzc.num_filters; filter++)
485 if (temp_32reg & BIT(filter))
486 DMSG("filter %u enable", filter);
487 }
488 }
489
490 #endif /* CFG_TRACE_LEVEL >= TRACE_DEBUG */
491