xref: /optee_os/core/arch/arm/plat-telechips/plat_tzc.c (revision c1e657096ec2f9ad6a373ac3265600252689933e)
1*c1e65709SSungmin Han // SPDX-License-Identifier: BSD-2-Clause
2*c1e65709SSungmin Han /*
3*c1e65709SSungmin Han  * Copyright (c) 2024, Telechips Inc.
4*c1e65709SSungmin Han  */
5*c1e65709SSungmin Han 
6*c1e65709SSungmin Han #include <drivers/openedges_omc.h>
7*c1e65709SSungmin Han #include <initcall.h>
8*c1e65709SSungmin Han #include <kernel/interrupt.h>
9*c1e65709SSungmin Han #include <kernel/panic.h>
10*c1e65709SSungmin Han #include <mm/core_memprot.h>
11*c1e65709SSungmin Han #include <trace.h>
12*c1e65709SSungmin Han 
13*c1e65709SSungmin Han #define NSEC_ALL_ACCESS   UINT32_MAX
14*c1e65709SSungmin Han 
tzc_protect_teeos(void)15*c1e65709SSungmin Han static void tzc_protect_teeos(void)
16*c1e65709SSungmin Han {
17*c1e65709SSungmin Han 	struct omc_region_config cfg = {
18*c1e65709SSungmin Han 		.filters = GENMASK_32(TZC_OMC_FILTERS - 1, 0),
19*c1e65709SSungmin Han 		.base = CFG_TZDRAM_START - DRAM0_BASE,
20*c1e65709SSungmin Han 		.top = (CFG_TZDRAM_START + CFG_TZDRAM_SIZE - 1) - DRAM0_BASE,
21*c1e65709SSungmin Han 		.ns_device_access = 0,
22*c1e65709SSungmin Han 		.flags = OMC_FLAG_RELATIVE_ADDR,
23*c1e65709SSungmin Han 	};
24*c1e65709SSungmin Han 
25*c1e65709SSungmin Han 	omc_configure_region(TZC_TEEOS_REGION_NUM, &cfg);
26*c1e65709SSungmin Han }
27*c1e65709SSungmin Han 
tzc_it_handler(struct itr_handler * h)28*c1e65709SSungmin Han static enum itr_return tzc_it_handler(struct itr_handler *h)
29*c1e65709SSungmin Han {
30*c1e65709SSungmin Han 	uint8_t filter = UINT8_MAX;
31*c1e65709SSungmin Han 	enum itr_return ret = ITRR_NONE;
32*c1e65709SSungmin Han 
33*c1e65709SSungmin Han 	switch (h->it) {
34*c1e65709SSungmin Han 	case TZC_OMC_INT_0:
35*c1e65709SSungmin Han 		filter = 0;
36*c1e65709SSungmin Han 		break;
37*c1e65709SSungmin Han #if defined(TZC_OMC_INT_1)
38*c1e65709SSungmin Han 	case TZC_OMC_INT_1:
39*c1e65709SSungmin Han 		filter = 1;
40*c1e65709SSungmin Han 		break;
41*c1e65709SSungmin Han #endif
42*c1e65709SSungmin Han #if defined(TZC_OMC_INT_2)
43*c1e65709SSungmin Han 	case TZC_OMC_INT_2:
44*c1e65709SSungmin Han 		filter = 2;
45*c1e65709SSungmin Han 		break;
46*c1e65709SSungmin Han #endif
47*c1e65709SSungmin Han #if defined(TZC_OMC_INT_3)
48*c1e65709SSungmin Han 	case TZC_OMC_INT_3:
49*c1e65709SSungmin Han 		filter = 3;
50*c1e65709SSungmin Han 		break;
51*c1e65709SSungmin Han #endif
52*c1e65709SSungmin Han 	default:
53*c1e65709SSungmin Han 		break;
54*c1e65709SSungmin Han 	}
55*c1e65709SSungmin Han 
56*c1e65709SSungmin Han 	if (filter != UINT8_MAX) {
57*c1e65709SSungmin Han 		EMSG("OMC(%"PRIu8") TZC permission failure", filter);
58*c1e65709SSungmin Han 		omc_fail_dump(filter);
59*c1e65709SSungmin Han 		omc_int_clear(filter);
60*c1e65709SSungmin Han 
61*c1e65709SSungmin Han 		ret = ITRR_HANDLED;
62*c1e65709SSungmin Han 	}
63*c1e65709SSungmin Han 
64*c1e65709SSungmin Han 	return ret;
65*c1e65709SSungmin Han }
66*c1e65709SSungmin Han 
67*c1e65709SSungmin Han static struct itr_handler tzc_itr_handler[] = {
68*c1e65709SSungmin Han 	{
69*c1e65709SSungmin Han 		.it = TZC_OMC_INT_0,
70*c1e65709SSungmin Han 		.handler = tzc_it_handler,
71*c1e65709SSungmin Han 	},
72*c1e65709SSungmin Han #if defined(TZC_OMC_INT_1)
73*c1e65709SSungmin Han 	{
74*c1e65709SSungmin Han 		.it = TZC_OMC_INT_1,
75*c1e65709SSungmin Han 		.handler = tzc_it_handler,
76*c1e65709SSungmin Han 	},
77*c1e65709SSungmin Han #endif
78*c1e65709SSungmin Han #if defined(TZC_OMC_INT_2)
79*c1e65709SSungmin Han 	{
80*c1e65709SSungmin Han 		.it = TZC_OMC_INT_2,
81*c1e65709SSungmin Han 		.handler = tzc_it_handler,
82*c1e65709SSungmin Han 	},
83*c1e65709SSungmin Han #endif
84*c1e65709SSungmin Han #if defined(TZC_OMC_INT_3)
85*c1e65709SSungmin Han 	{
86*c1e65709SSungmin Han 		.it = TZC_OMC_INT_3,
87*c1e65709SSungmin Han 		.handler = tzc_it_handler,
88*c1e65709SSungmin Han 	},
89*c1e65709SSungmin Han #endif
90*c1e65709SSungmin Han };
91*c1e65709SSungmin Han 
tzc_configure(void)92*c1e65709SSungmin Han static TEE_Result tzc_configure(void)
93*c1e65709SSungmin Han {
94*c1e65709SSungmin Han 	vaddr_t va = 0;
95*c1e65709SSungmin Han 	uint8_t filter = 0;
96*c1e65709SSungmin Han 	struct omc_region_config cfg = {
97*c1e65709SSungmin Han 		.filters = GENMASK_32(TZC_OMC_FILTERS - 1, 0),
98*c1e65709SSungmin Han 		.base = 0,
99*c1e65709SSungmin Han 		.top = UINT64_MAX,
100*c1e65709SSungmin Han 		.ns_device_access = NSEC_ALL_ACCESS,
101*c1e65709SSungmin Han 		.flags = 0,
102*c1e65709SSungmin Han 	};
103*c1e65709SSungmin Han 
104*c1e65709SSungmin Han 	DMSG("Initializing TZC");
105*c1e65709SSungmin Han 
106*c1e65709SSungmin Han 	va = (vaddr_t)phys_to_virt_io(TZC_OMC_BASE,
107*c1e65709SSungmin Han 				      TZC_OMC_FILTERS * TZC_OMC_FILTER_OFFS);
108*c1e65709SSungmin Han 	if (!va)
109*c1e65709SSungmin Han 		panic();
110*c1e65709SSungmin Han 
111*c1e65709SSungmin Han 	omc_init(va, TZC_OMC_FILTER_OFFS, TZC_OMC_FILTERS);
112*c1e65709SSungmin Han 	omc_configure_region(0, &cfg);
113*c1e65709SSungmin Han 	tzc_protect_teeos();
114*c1e65709SSungmin Han 
115*c1e65709SSungmin Han 	for (filter = 0; filter < ARRAY_SIZE(tzc_itr_handler); filter++) {
116*c1e65709SSungmin Han 		interrupt_add_handler_with_chip(interrupt_get_main_chip(),
117*c1e65709SSungmin Han 						&tzc_itr_handler[filter]);
118*c1e65709SSungmin Han 		interrupt_enable(interrupt_get_main_chip(),
119*c1e65709SSungmin Han 				 tzc_itr_handler[filter].it);
120*c1e65709SSungmin Han 	}
121*c1e65709SSungmin Han 	omc_set_action(OMC_ACTION_INT);
122*c1e65709SSungmin Han 
123*c1e65709SSungmin Han 	return TEE_SUCCESS;
124*c1e65709SSungmin Han }
125*c1e65709SSungmin Han service_init(tzc_configure);
126