xref: /rk3399_ARM-atf/drivers/arm/tzc/tzc380.c (revision df54406df5c1addaf84940012c1c2c254af4129b)
146f9b2c3SPeng Fan /*
246f9b2c3SPeng Fan  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
346f9b2c3SPeng Fan  *
446f9b2c3SPeng Fan  * SPDX-License-Identifier: BSD-3-Clause
546f9b2c3SPeng Fan  */
646f9b2c3SPeng Fan 
746f9b2c3SPeng Fan #include <assert.h>
846f9b2c3SPeng Fan #include <debug.h>
946f9b2c3SPeng Fan #include <mmio.h>
1046f9b2c3SPeng Fan #include <stddef.h>
1146f9b2c3SPeng Fan #include <tzc380.h>
1246f9b2c3SPeng Fan 
1346f9b2c3SPeng Fan struct tzc380_instance {
1446f9b2c3SPeng Fan 	uintptr_t base;
1546f9b2c3SPeng Fan 	uint8_t addr_width;
1646f9b2c3SPeng Fan 	uint8_t num_regions;
1746f9b2c3SPeng Fan };
1846f9b2c3SPeng Fan 
1946f9b2c3SPeng Fan struct tzc380_instance tzc380;
2046f9b2c3SPeng Fan 
2146f9b2c3SPeng Fan static unsigned int tzc380_read_build_config(uintptr_t base)
2246f9b2c3SPeng Fan {
2346f9b2c3SPeng Fan 	return mmio_read_32(base + TZC380_CONFIGURATION_OFF);
2446f9b2c3SPeng Fan }
2546f9b2c3SPeng Fan 
2646f9b2c3SPeng Fan static void tzc380_write_action(uintptr_t base, tzc_action_t action)
2746f9b2c3SPeng Fan {
2846f9b2c3SPeng Fan 	mmio_write_32(base + ACTION_OFF, action);
2946f9b2c3SPeng Fan }
3046f9b2c3SPeng Fan 
3146f9b2c3SPeng Fan static void tzc380_write_region_base_low(uintptr_t base, unsigned int region,
3246f9b2c3SPeng Fan 				      unsigned int val)
3346f9b2c3SPeng Fan {
3446f9b2c3SPeng Fan 	mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val);
3546f9b2c3SPeng Fan }
3646f9b2c3SPeng Fan 
3746f9b2c3SPeng Fan static void tzc380_write_region_base_high(uintptr_t base, unsigned int region,
3846f9b2c3SPeng Fan 				       unsigned int val)
3946f9b2c3SPeng Fan {
4046f9b2c3SPeng Fan 	mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val);
4146f9b2c3SPeng Fan }
4246f9b2c3SPeng Fan 
4346f9b2c3SPeng Fan static void tzc380_write_region_attributes(uintptr_t base, unsigned int region,
4446f9b2c3SPeng Fan 					unsigned int val)
4546f9b2c3SPeng Fan {
4646f9b2c3SPeng Fan 	mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val);
4746f9b2c3SPeng Fan }
4846f9b2c3SPeng Fan 
4946f9b2c3SPeng Fan void tzc380_init(uintptr_t base)
5046f9b2c3SPeng Fan {
5146f9b2c3SPeng Fan 	unsigned int tzc_build;
5246f9b2c3SPeng Fan 
53*df54406dSAntonio Nino Diaz 	assert(base != 0U);
5446f9b2c3SPeng Fan 	tzc380.base = base;
5546f9b2c3SPeng Fan 
5646f9b2c3SPeng Fan 	/* Save values we will use later. */
5746f9b2c3SPeng Fan 	tzc_build = tzc380_read_build_config(tzc380.base);
5846f9b2c3SPeng Fan 	tzc380.addr_width  = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
5946f9b2c3SPeng Fan 			      BUILD_CONFIG_AW_MASK) + 1;
6046f9b2c3SPeng Fan 	tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
6146f9b2c3SPeng Fan 			       BUILD_CONFIG_NR_MASK) + 1;
6246f9b2c3SPeng Fan }
6346f9b2c3SPeng Fan 
6446f9b2c3SPeng Fan static uint32_t addr_low(uintptr_t addr)
6546f9b2c3SPeng Fan {
6646f9b2c3SPeng Fan 	return (uint32_t)addr;
6746f9b2c3SPeng Fan }
6846f9b2c3SPeng Fan 
6946f9b2c3SPeng Fan static uint32_t addr_high(uintptr_t addr __unused)
7046f9b2c3SPeng Fan {
7146f9b2c3SPeng Fan #if (UINTPTR_MAX == UINT64_MAX)
7246f9b2c3SPeng Fan 	return addr >> 32;
7346f9b2c3SPeng Fan #else
7446f9b2c3SPeng Fan 	return 0;
7546f9b2c3SPeng Fan #endif
7646f9b2c3SPeng Fan }
7746f9b2c3SPeng Fan 
7846f9b2c3SPeng Fan /*
7946f9b2c3SPeng Fan  * `tzc380_configure_region` is used to program regions into the TrustZone
8046f9b2c3SPeng Fan  * controller.
8146f9b2c3SPeng Fan  */
8246f9b2c3SPeng Fan void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr)
8346f9b2c3SPeng Fan {
84*df54406dSAntonio Nino Diaz 	assert(tzc380.base != 0U);
8546f9b2c3SPeng Fan 
8646f9b2c3SPeng Fan 	assert(region < tzc380.num_regions);
8746f9b2c3SPeng Fan 
8846f9b2c3SPeng Fan 	tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base));
8946f9b2c3SPeng Fan 	tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base));
9046f9b2c3SPeng Fan 	tzc380_write_region_attributes(tzc380.base, region, attr);
9146f9b2c3SPeng Fan }
9246f9b2c3SPeng Fan 
9346f9b2c3SPeng Fan void tzc380_set_action(tzc_action_t action)
9446f9b2c3SPeng Fan {
95*df54406dSAntonio Nino Diaz 	assert(tzc380.base != 0U);
9646f9b2c3SPeng Fan 
9746f9b2c3SPeng Fan 	/*
9846f9b2c3SPeng Fan 	 * - Currently no handler is provided to trap an error via interrupt
9946f9b2c3SPeng Fan 	 *   or exception.
10046f9b2c3SPeng Fan 	 * - The interrupt action has not been tested.
10146f9b2c3SPeng Fan 	 */
10246f9b2c3SPeng Fan 	tzc380_write_action(tzc380.base, action);
10346f9b2c3SPeng Fan }
104