xref: /rk3399_ARM-atf/drivers/arm/tzc/tzc380.c (revision 46f9b2c3a2826b7dbb318b14d20239c39f2dee2d)
1*46f9b2c3SPeng Fan /*
2*46f9b2c3SPeng Fan  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3*46f9b2c3SPeng Fan  *
4*46f9b2c3SPeng Fan  * SPDX-License-Identifier: BSD-3-Clause
5*46f9b2c3SPeng Fan  */
6*46f9b2c3SPeng Fan 
7*46f9b2c3SPeng Fan #include <assert.h>
8*46f9b2c3SPeng Fan #include <debug.h>
9*46f9b2c3SPeng Fan #include <mmio.h>
10*46f9b2c3SPeng Fan #include <stddef.h>
11*46f9b2c3SPeng Fan #include <tzc380.h>
12*46f9b2c3SPeng Fan 
13*46f9b2c3SPeng Fan struct tzc380_instance {
14*46f9b2c3SPeng Fan 	uintptr_t base;
15*46f9b2c3SPeng Fan 	uint8_t addr_width;
16*46f9b2c3SPeng Fan 	uint8_t num_regions;
17*46f9b2c3SPeng Fan };
18*46f9b2c3SPeng Fan 
19*46f9b2c3SPeng Fan struct tzc380_instance tzc380;
20*46f9b2c3SPeng Fan 
21*46f9b2c3SPeng Fan static unsigned int tzc380_read_build_config(uintptr_t base)
22*46f9b2c3SPeng Fan {
23*46f9b2c3SPeng Fan 	return mmio_read_32(base + TZC380_CONFIGURATION_OFF);
24*46f9b2c3SPeng Fan }
25*46f9b2c3SPeng Fan 
26*46f9b2c3SPeng Fan static void tzc380_write_action(uintptr_t base, tzc_action_t action)
27*46f9b2c3SPeng Fan {
28*46f9b2c3SPeng Fan 	mmio_write_32(base + ACTION_OFF, action);
29*46f9b2c3SPeng Fan }
30*46f9b2c3SPeng Fan 
31*46f9b2c3SPeng Fan static void tzc380_write_region_base_low(uintptr_t base, unsigned int region,
32*46f9b2c3SPeng Fan 				      unsigned int val)
33*46f9b2c3SPeng Fan {
34*46f9b2c3SPeng Fan 	mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val);
35*46f9b2c3SPeng Fan }
36*46f9b2c3SPeng Fan 
37*46f9b2c3SPeng Fan static void tzc380_write_region_base_high(uintptr_t base, unsigned int region,
38*46f9b2c3SPeng Fan 				       unsigned int val)
39*46f9b2c3SPeng Fan {
40*46f9b2c3SPeng Fan 	mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val);
41*46f9b2c3SPeng Fan }
42*46f9b2c3SPeng Fan 
43*46f9b2c3SPeng Fan static void tzc380_write_region_attributes(uintptr_t base, unsigned int region,
44*46f9b2c3SPeng Fan 					unsigned int val)
45*46f9b2c3SPeng Fan {
46*46f9b2c3SPeng Fan 	mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val);
47*46f9b2c3SPeng Fan }
48*46f9b2c3SPeng Fan 
49*46f9b2c3SPeng Fan void tzc380_init(uintptr_t base)
50*46f9b2c3SPeng Fan {
51*46f9b2c3SPeng Fan 	unsigned int tzc_build;
52*46f9b2c3SPeng Fan 
53*46f9b2c3SPeng Fan 	assert(base != NULL);
54*46f9b2c3SPeng Fan 	tzc380.base = base;
55*46f9b2c3SPeng Fan 
56*46f9b2c3SPeng Fan 	/* Save values we will use later. */
57*46f9b2c3SPeng Fan 	tzc_build = tzc380_read_build_config(tzc380.base);
58*46f9b2c3SPeng Fan 	tzc380.addr_width  = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
59*46f9b2c3SPeng Fan 			      BUILD_CONFIG_AW_MASK) + 1;
60*46f9b2c3SPeng Fan 	tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
61*46f9b2c3SPeng Fan 			       BUILD_CONFIG_NR_MASK) + 1;
62*46f9b2c3SPeng Fan }
63*46f9b2c3SPeng Fan 
64*46f9b2c3SPeng Fan static uint32_t addr_low(uintptr_t addr)
65*46f9b2c3SPeng Fan {
66*46f9b2c3SPeng Fan 	return (uint32_t)addr;
67*46f9b2c3SPeng Fan }
68*46f9b2c3SPeng Fan 
69*46f9b2c3SPeng Fan static uint32_t addr_high(uintptr_t addr __unused)
70*46f9b2c3SPeng Fan {
71*46f9b2c3SPeng Fan #if (UINTPTR_MAX == UINT64_MAX)
72*46f9b2c3SPeng Fan 	return addr >> 32;
73*46f9b2c3SPeng Fan #else
74*46f9b2c3SPeng Fan 	return 0;
75*46f9b2c3SPeng Fan #endif
76*46f9b2c3SPeng Fan }
77*46f9b2c3SPeng Fan 
78*46f9b2c3SPeng Fan /*
79*46f9b2c3SPeng Fan  * `tzc380_configure_region` is used to program regions into the TrustZone
80*46f9b2c3SPeng Fan  * controller.
81*46f9b2c3SPeng Fan  */
82*46f9b2c3SPeng Fan void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr)
83*46f9b2c3SPeng Fan {
84*46f9b2c3SPeng Fan 	assert(tzc380.base != NULL);
85*46f9b2c3SPeng Fan 
86*46f9b2c3SPeng Fan 	assert(region < tzc380.num_regions);
87*46f9b2c3SPeng Fan 
88*46f9b2c3SPeng Fan 	tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base));
89*46f9b2c3SPeng Fan 	tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base));
90*46f9b2c3SPeng Fan 	tzc380_write_region_attributes(tzc380.base, region, attr);
91*46f9b2c3SPeng Fan }
92*46f9b2c3SPeng Fan 
93*46f9b2c3SPeng Fan void tzc380_set_action(tzc_action_t action)
94*46f9b2c3SPeng Fan {
95*46f9b2c3SPeng Fan 	assert(tzc380.base != NULL);
96*46f9b2c3SPeng Fan 
97*46f9b2c3SPeng Fan 	/*
98*46f9b2c3SPeng Fan 	 * - Currently no handler is provided to trap an error via interrupt
99*46f9b2c3SPeng Fan 	 *   or exception.
100*46f9b2c3SPeng Fan 	 * - The interrupt action has not been tested.
101*46f9b2c3SPeng Fan 	 */
102*46f9b2c3SPeng Fan 	tzc380_write_action(tzc380.base, action);
103*46f9b2c3SPeng Fan }
104