xref: /rk3399_ARM-atf/drivers/arm/tzc/tzc380.c (revision 8a08e27232d0c1b906fd2f3e4b3b7a90661a50b9)
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 <stddef.h>
909d40e0eSAntonio Nino Diaz 
1009d40e0eSAntonio Nino Diaz #include <common/debug.h>
1109d40e0eSAntonio Nino Diaz #include <drivers/arm/tzc380.h>
1209d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1346f9b2c3SPeng Fan 
1446f9b2c3SPeng Fan struct tzc380_instance {
1546f9b2c3SPeng Fan 	uintptr_t base;
1646f9b2c3SPeng Fan 	uint8_t addr_width;
1746f9b2c3SPeng Fan 	uint8_t num_regions;
1846f9b2c3SPeng Fan };
1946f9b2c3SPeng Fan 
2046f9b2c3SPeng Fan struct tzc380_instance tzc380;
2146f9b2c3SPeng Fan 
tzc380_read_build_config(uintptr_t base)2246f9b2c3SPeng Fan static unsigned int tzc380_read_build_config(uintptr_t base)
2346f9b2c3SPeng Fan {
2446f9b2c3SPeng Fan 	return mmio_read_32(base + TZC380_CONFIGURATION_OFF);
2546f9b2c3SPeng Fan }
2646f9b2c3SPeng Fan 
tzc380_write_action(uintptr_t base,unsigned int action)27*cc69cfd2SAmbroise Vincent static void tzc380_write_action(uintptr_t base, unsigned int action)
2846f9b2c3SPeng Fan {
2946f9b2c3SPeng Fan 	mmio_write_32(base + ACTION_OFF, action);
3046f9b2c3SPeng Fan }
3146f9b2c3SPeng Fan 
tzc380_write_region_base_low(uintptr_t base,unsigned int region,unsigned int val)3246f9b2c3SPeng Fan static void tzc380_write_region_base_low(uintptr_t base, unsigned int region,
3346f9b2c3SPeng Fan 				      unsigned int val)
3446f9b2c3SPeng Fan {
3546f9b2c3SPeng Fan 	mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val);
3646f9b2c3SPeng Fan }
3746f9b2c3SPeng Fan 
tzc380_write_region_base_high(uintptr_t base,unsigned int region,unsigned int val)3846f9b2c3SPeng Fan static void tzc380_write_region_base_high(uintptr_t base, unsigned int region,
3946f9b2c3SPeng Fan 				       unsigned int val)
4046f9b2c3SPeng Fan {
4146f9b2c3SPeng Fan 	mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val);
4246f9b2c3SPeng Fan }
4346f9b2c3SPeng Fan 
tzc380_write_region_attributes(uintptr_t base,unsigned int region,unsigned int val)4446f9b2c3SPeng Fan static void tzc380_write_region_attributes(uintptr_t base, unsigned int region,
4546f9b2c3SPeng Fan 					unsigned int val)
4646f9b2c3SPeng Fan {
4746f9b2c3SPeng Fan 	mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val);
4846f9b2c3SPeng Fan }
4946f9b2c3SPeng Fan 
tzc380_init(uintptr_t base)5046f9b2c3SPeng Fan void tzc380_init(uintptr_t base)
5146f9b2c3SPeng Fan {
5246f9b2c3SPeng Fan 	unsigned int tzc_build;
5346f9b2c3SPeng Fan 
54df54406dSAntonio Nino Diaz 	assert(base != 0U);
5546f9b2c3SPeng Fan 	tzc380.base = base;
5646f9b2c3SPeng Fan 
5746f9b2c3SPeng Fan 	/* Save values we will use later. */
5846f9b2c3SPeng Fan 	tzc_build = tzc380_read_build_config(tzc380.base);
5946f9b2c3SPeng Fan 	tzc380.addr_width  = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
6046f9b2c3SPeng Fan 			      BUILD_CONFIG_AW_MASK) + 1;
6146f9b2c3SPeng Fan 	tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
6246f9b2c3SPeng Fan 			       BUILD_CONFIG_NR_MASK) + 1;
6346f9b2c3SPeng Fan }
6446f9b2c3SPeng Fan 
addr_low(uintptr_t addr)6546f9b2c3SPeng Fan static uint32_t addr_low(uintptr_t addr)
6646f9b2c3SPeng Fan {
6746f9b2c3SPeng Fan 	return (uint32_t)addr;
6846f9b2c3SPeng Fan }
6946f9b2c3SPeng Fan 
addr_high(uintptr_t addr __unused)7046f9b2c3SPeng Fan static uint32_t addr_high(uintptr_t addr __unused)
7146f9b2c3SPeng Fan {
7246f9b2c3SPeng Fan #if (UINTPTR_MAX == UINT64_MAX)
7346f9b2c3SPeng Fan 	return addr >> 32;
7446f9b2c3SPeng Fan #else
7546f9b2c3SPeng Fan 	return 0;
7646f9b2c3SPeng Fan #endif
7746f9b2c3SPeng Fan }
7846f9b2c3SPeng Fan 
7946f9b2c3SPeng Fan /*
8046f9b2c3SPeng Fan  * `tzc380_configure_region` is used to program regions into the TrustZone
8146f9b2c3SPeng Fan  * controller.
8246f9b2c3SPeng Fan  */
tzc380_configure_region(uint8_t region,uintptr_t region_base,unsigned int attr)8346f9b2c3SPeng Fan void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr)
8446f9b2c3SPeng Fan {
85df54406dSAntonio Nino Diaz 	assert(tzc380.base != 0U);
8646f9b2c3SPeng Fan 
8746f9b2c3SPeng Fan 	assert(region < tzc380.num_regions);
8846f9b2c3SPeng Fan 
8946f9b2c3SPeng Fan 	tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base));
9046f9b2c3SPeng Fan 	tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base));
9146f9b2c3SPeng Fan 	tzc380_write_region_attributes(tzc380.base, region, attr);
9246f9b2c3SPeng Fan }
9346f9b2c3SPeng Fan 
tzc380_set_action(unsigned int action)94*cc69cfd2SAmbroise Vincent void tzc380_set_action(unsigned int action)
9546f9b2c3SPeng Fan {
96df54406dSAntonio Nino Diaz 	assert(tzc380.base != 0U);
9746f9b2c3SPeng Fan 
9846f9b2c3SPeng Fan 	/*
9946f9b2c3SPeng Fan 	 * - Currently no handler is provided to trap an error via interrupt
10046f9b2c3SPeng Fan 	 *   or exception.
10146f9b2c3SPeng Fan 	 * - The interrupt action has not been tested.
10246f9b2c3SPeng Fan 	 */
10346f9b2c3SPeng Fan 	tzc380_write_action(tzc380.base, action);
10446f9b2c3SPeng Fan }
105