1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2017-2019, 2021 NXP
4 *
5 * Brief CAAM Configuration.
6 */
7 #include <caam_common.h>
8 #include <caam_hal_cfg.h>
9 #include <caam_hal_jr.h>
10 #include <caam_jr.h>
11 #include <kernel/boot.h>
12 #include <kernel/dt.h>
13 #include <kernel/interrupt.h>
14 #include <libfdt.h>
15 #include <mm/core_memprot.h>
16 #include <mm/core_mmu.h>
17
18 static const char *dt_caam_match_table = {
19 "fsl,sec-v4.0",
20 };
21
22 static const char *dt_jr_match_table = {
23 "fsl,sec-v4.0-job-ring",
24 };
25
26 /*
27 * Finds the Job Ring reserved for the Secure Mode in the DTB
28 *
29 * @fdt Reference to the Device Tree
30 * @status Status mask flag of the node to found
31 * @find_node [out] Node offset found
32 */
find_jr_offset(void * fdt,int status,int * find_node)33 static paddr_t find_jr_offset(void *fdt, int status, int *find_node)
34 {
35 paddr_t jr_offset = 0;
36 int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table);
37
38 for (; node != -FDT_ERR_NOTFOUND;
39 node = fdt_node_offset_by_compatible(fdt, node,
40 dt_jr_match_table)) {
41 HAL_TRACE("Found Job Ring node status @%" PRId32, node);
42 if (fdt_get_status(fdt, node) == status) {
43 HAL_TRACE("Found Job Ring node @%" PRId32, node);
44 jr_offset = fdt_reg_base_address(fdt, node);
45 *find_node = node;
46 break;
47 }
48 }
49
50 HAL_TRACE("JR Offset return 0x%" PRIxPTR, jr_offset);
51 return jr_offset;
52 }
53
caam_hal_cfg_get_ctrl_dt(void * fdt,vaddr_t * ctrl_base)54 void caam_hal_cfg_get_ctrl_dt(void *fdt, vaddr_t *ctrl_base)
55 {
56 size_t size = 0;
57 int node = 0;
58 paddr_t pctrl_base = 0;
59
60 *ctrl_base = 0;
61 /* Get the CAAM Node to get the controller base address */
62 node = fdt_node_offset_by_compatible(fdt, 0, dt_caam_match_table);
63
64 if (node < 0)
65 return;
66
67 /*
68 * Map CAAM controller base address as Secure IO if not
69 * already present in the MMU table.
70 * Then get the virtual address of the CAAM controller
71 */
72 if (fdt_reg_info(fdt, node, &pctrl_base, &size)) {
73 HAL_TRACE("CAAM control base address or size not defined");
74 return;
75 }
76
77 *ctrl_base = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, pctrl_base,
78 size);
79 if (!*ctrl_base) {
80 EMSG("CAAM control base MMU PA mapping failure");
81 return;
82 }
83
84 HAL_TRACE("Map Controller 0x%" PRIxVA, *ctrl_base);
85 }
86
caam_hal_cfg_get_jobring_dt(void * fdt,struct caam_jrcfg * jrcfg)87 void caam_hal_cfg_get_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg)
88 {
89 paddr_t jr_offset = 0;
90 int jr_it_num = 0;
91 int node = 0;
92
93 jr_offset = find_jr_offset(fdt, DT_STATUS_OK_SEC, &node);
94 if (jr_offset) {
95 if (!is_embedded_dt(fdt)) {
96 /* Disable JR for Normal World */
97 if (dt_enable_secure_status(fdt, node)) {
98 EMSG("Not able to disable JR DTB entry");
99 return;
100 }
101 }
102
103 /* Get the job ring interrupt */
104 jr_it_num = dt_get_irq(fdt, node);
105 if (jr_it_num == DT_INFO_INVALID_INTERRUPT) {
106 EMSG("Job Ring interrupt number not defined in DTB");
107 return;
108 }
109
110 jrcfg->offset = jr_offset;
111 jrcfg->it_num = jr_it_num;
112 }
113 }
114
caam_hal_cfg_disable_jobring_dt(void * fdt,struct caam_jrcfg * jrcfg)115 void caam_hal_cfg_disable_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg)
116 {
117 int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table);
118
119 for (; node != -FDT_ERR_NOTFOUND;
120 node = fdt_node_offset_by_compatible(fdt, node,
121 dt_jr_match_table)) {
122 HAL_TRACE("Found Job Ring node @%" PRId32, node);
123 if (fdt_reg_base_address(fdt, node) == jrcfg->offset) {
124 HAL_TRACE("Disable Job Ring node @%" PRId32, node);
125 if (dt_enable_secure_status(fdt, node))
126 panic();
127 break;
128 }
129 }
130 }
131