blob: 95187485d15d342c6543a53062c325e2fe3e0433 [file] [log] [blame]
Peng Fan7af02142017-07-05 16:34:37 +08001/*
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>
Peng Fan7af02142017-07-05 16:34:37 +08008#include <stddef.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009
10#include <common/debug.h>
11#include <drivers/arm/tzc380.h>
12#include <lib/mmio.h>
Peng Fan7af02142017-07-05 16:34:37 +080013
14struct tzc380_instance {
15 uintptr_t base;
16 uint8_t addr_width;
17 uint8_t num_regions;
18};
19
20struct tzc380_instance tzc380;
21
22static unsigned int tzc380_read_build_config(uintptr_t base)
23{
24 return mmio_read_32(base + TZC380_CONFIGURATION_OFF);
25}
26
Ambroise Vincent912c6302019-03-27 16:03:24 +000027static void tzc380_write_action(uintptr_t base, unsigned int action)
Peng Fan7af02142017-07-05 16:34:37 +080028{
29 mmio_write_32(base + ACTION_OFF, action);
30}
31
32static void tzc380_write_region_base_low(uintptr_t base, unsigned int region,
33 unsigned int val)
34{
35 mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val);
36}
37
38static void tzc380_write_region_base_high(uintptr_t base, unsigned int region,
39 unsigned int val)
40{
41 mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val);
42}
43
44static void tzc380_write_region_attributes(uintptr_t base, unsigned int region,
45 unsigned int val)
46{
47 mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val);
48}
49
50void tzc380_init(uintptr_t base)
51{
52 unsigned int tzc_build;
53
Antonio Nino Diaz461b49e2018-12-05 11:01:17 +000054 assert(base != 0U);
Peng Fan7af02142017-07-05 16:34:37 +080055 tzc380.base = base;
56
57 /* Save values we will use later. */
58 tzc_build = tzc380_read_build_config(tzc380.base);
59 tzc380.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
60 BUILD_CONFIG_AW_MASK) + 1;
61 tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
62 BUILD_CONFIG_NR_MASK) + 1;
63}
64
65static uint32_t addr_low(uintptr_t addr)
66{
67 return (uint32_t)addr;
68}
69
70static uint32_t addr_high(uintptr_t addr __unused)
71{
72#if (UINTPTR_MAX == UINT64_MAX)
73 return addr >> 32;
74#else
75 return 0;
76#endif
77}
78
79/*
80 * `tzc380_configure_region` is used to program regions into the TrustZone
81 * controller.
82 */
83void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr)
84{
Antonio Nino Diaz461b49e2018-12-05 11:01:17 +000085 assert(tzc380.base != 0U);
Peng Fan7af02142017-07-05 16:34:37 +080086
87 assert(region < tzc380.num_regions);
88
89 tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base));
90 tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base));
91 tzc380_write_region_attributes(tzc380.base, region, attr);
92}
93
Ambroise Vincent912c6302019-03-27 16:03:24 +000094void tzc380_set_action(unsigned int action)
Peng Fan7af02142017-07-05 16:34:37 +080095{
Antonio Nino Diaz461b49e2018-12-05 11:01:17 +000096 assert(tzc380.base != 0U);
Peng Fan7af02142017-07-05 16:34:37 +080097
98 /*
99 * - Currently no handler is provided to trap an error via interrupt
100 * or exception.
101 * - The interrupt action has not been tested.
102 */
103 tzc380_write_action(tzc380.base, action);
104}