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