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