summaryrefslogtreecommitdiffstats
path: root/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
blob: f2568ab5a0a04d1704559dd824d0083391c5beb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>

#include <common/debug.h>
#include <common/fdt_wrappers.h>
#include <drivers/arm/tzc400.h>
#include <drivers/clk.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <lib/fconf/fconf.h>
#include <lib/object_pool.h>
#include <libfdt.h>
#include <tools_share/firmware_image_package.h>

#include <platform_def.h>
#include <stm32mp_fconf_getter.h>

#define STM32MP_REGION_PARAMS	4
#define STM32MP_MAX_REGIONS	8
#define FORCE_SEC_REGION	BIT(31)

static uint32_t nb_regions;

struct dt_id_attr {
	fdt32_t id_attr[STM32MP_MAX_REGIONS];
};

void stm32mp1_arch_security_setup(void)
{
#if STM32MP13
	clk_enable(TZC);
#endif
#if STM32MP15
	clk_enable(TZC1);
	clk_enable(TZC2);
#endif

	tzc400_init(STM32MP1_TZC_BASE);
	tzc400_disable_filters();

	/*
	 * Region 0 set to cover all DRAM at 0xC000_0000
	 * Only secure access is granted in read/write.
	 */
	tzc400_configure_region0(TZC_REGION_S_RDWR, 0);

	tzc400_set_action(TZC_ACTION_ERR);
	tzc400_enable_filters();
}

void stm32mp1_security_setup(void)
{
	uint8_t i;

	assert(nb_regions > 0U);

	tzc400_init(STM32MP1_TZC_BASE);
	tzc400_disable_filters();

	/*
	 * Region 0 set to cover all DRAM at 0xC000_0000
	 * No access is allowed.
	 */
	tzc400_configure_region0(TZC_REGION_S_NONE, 0);

	for (i = 1U; i <= nb_regions; i++) {
		tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
	}

	tzc400_set_action(TZC_ACTION_INT);
	tzc400_enable_filters();
}

static int fconf_populate_stm32mp1_firewall(uintptr_t config)
{
	int node, len;
	unsigned int i;
	const struct dt_id_attr *conf_list;
	const void *dtb = (const void *)config;

	/* Assert the node offset point to "st,mem-firewall" compatible property */
	const char *compatible_str = "st,mem-firewall";

	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
	if (node < 0) {
		ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
		return node;
	}

	conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
	if (conf_list == NULL) {
		WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
		return -1;
	}

	/* Locate the memory cells and read all values */
	for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
		uint32_t base;
		uint32_t size;
		uint32_t sec_attr;
		uint32_t nsaid;

		base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
		size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
		sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
		nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);

		VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
			base, size, sec_attr, nsaid);

		nb_regions++;

		/* Configure region but keep disabled for secure access for BL2 load */
		tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
					(unsigned long long)base + size - 1ULL, sec_attr, nsaid);
	}

	/* Force flush as the value will be used cache off */
	flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));

	return 0;
}

FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);