1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2018-2020 NXP
4 *
5 * Brief CAAM Controller Hardware Abstration Layer.
6 * Implementation of primitives to access HW.
7 */
8 #include <caam_hal_ctrl.h>
9 #include <caam_io.h>
10 #include <caam_trace.h>
11 #include <config.h>
12 #include <drivers/imx_snvs.h>
13 #include <platform_config.h>
14 #include <registers/ctrl_regs.h>
15 #include <registers/jr_regs.h>
16 #include <registers/version_regs.h>
17 #include <kernel/panic.h>
18
caam_hal_ctrl_era(vaddr_t baseaddr)19 uint8_t caam_hal_ctrl_era(vaddr_t baseaddr)
20 {
21 /* Read the number of instance */
22 uint32_t val = io_caam_read32(baseaddr + CCBVID);
23
24 return GET_CCBVID_CAAM_ERA(val);
25 }
26
caam_hal_ctrl_jrnum(vaddr_t baseaddr)27 uint8_t caam_hal_ctrl_jrnum(vaddr_t baseaddr)
28 {
29 uint32_t val = 0;
30 uint8_t jrnum = 0;
31
32 if (caam_hal_ctrl_era(baseaddr) < 10) {
33 val = io_caam_read32(baseaddr + CHANUM_MS);
34 jrnum = GET_CHANUM_MS_JRNUM(val);
35 } else {
36 val = io_caam_read32(baseaddr + JR_VERSION);
37 jrnum = GET_JR_VERSION_JRNUM(val);
38 }
39
40 return jrnum;
41 }
42
caam_hal_ctrl_hash_limit(vaddr_t baseaddr)43 uint8_t caam_hal_ctrl_hash_limit(vaddr_t baseaddr)
44 {
45 uint32_t val = 0;
46
47 if (caam_hal_ctrl_era(baseaddr) < 10) {
48 /* Read the number of instance */
49 val = io_caam_read32(baseaddr + CHANUM_LS);
50
51 if (GET_CHANUM_LS_MDNUM(val)) {
52 /* Hashing is supported */
53 val = io_caam_read32(baseaddr + CHAVID_LS);
54 val &= BM_CHAVID_LS_MDVID;
55 if (val == CHAVID_LS_MDVID_LP256)
56 return TEE_MAIN_ALGO_SHA256;
57
58 return TEE_MAIN_ALGO_SHA512;
59 }
60 } else {
61 /* Read the number of instance */
62 val = io_caam_read32(baseaddr + MDHA_VERSION);
63
64 if (GET_MDHA_VERSION_MDNUM(val)) {
65 /* Hashing is supported */
66 val &= BM_MDHA_VERSION_MDVID;
67 if (val == MDHA_VERSION_MDVID_LP256)
68 return TEE_MAIN_ALGO_SHA256;
69
70 return TEE_MAIN_ALGO_SHA512;
71 }
72 }
73
74 return UINT8_MAX;
75 }
76
caam_hal_ctrl_splitkey_support(vaddr_t baseaddr)77 bool caam_hal_ctrl_splitkey_support(vaddr_t baseaddr)
78 {
79 uint32_t val = io_caam_read32(baseaddr + CTPR_LS);
80
81 return GET_CTPR_LS_SPLIT_KEY(val);
82 }
83
caam_hal_ctrl_pknum(vaddr_t baseaddr)84 uint8_t caam_hal_ctrl_pknum(vaddr_t baseaddr)
85 {
86 uint32_t val = 0;
87 uint8_t pknum = 0;
88
89 if (caam_hal_ctrl_era(baseaddr) < 10) {
90 val = io_caam_read32(baseaddr + CHANUM_LS);
91 pknum = GET_CHANUM_LS_PKNUM(val);
92 } else {
93 val = io_caam_read32(baseaddr + PKHA_VERSION);
94 pknum = GET_PKHA_VERSION_PKNUM(val);
95 }
96
97 return pknum;
98 }
99
100 #define PRIBLOB_MASK GENMASK_32(1, 0)
101
caam_hal_ctrl_inc_priblob(vaddr_t baseaddr)102 void caam_hal_ctrl_inc_priblob(vaddr_t baseaddr)
103 {
104 uint32_t val = 0;
105 uint32_t blob = 0;
106
107 if (!IS_ENABLED(CFG_CAAM_INC_PRIBLOB))
108 return;
109
110 val = io_caam_read32(baseaddr + SCFGR);
111 val &= PRIBLOB_MASK;
112 CTRL_TRACE("Reading CAAM PRIBLOB: 0x%"PRIx32, val);
113
114 if (val == 0 || val == 2)
115 blob = val + 1;
116 else if (val == 1)
117 blob = val + 2;
118 else
119 panic("Error locking PRIBLOB, PRIBLOB =3");
120
121 CTRL_TRACE("New CAAM PRIBLOB value: 0x%"PRIx32, blob);
122
123 val = io_caam_read32(baseaddr + SCFGR);
124 val |= blob;
125 io_caam_write32(baseaddr + SCFGR, val);
126
127 val = io_caam_read32(baseaddr + SCFGR);
128 val &= PRIBLOB_MASK;
129 CTRL_TRACE("Checking: CAAM PRIBLOB: 0x%"PRIx32 " want: 0x%"PRIx32, val,
130 blob);
131 if (val != blob)
132 panic("Written PRIBLOB and read PRIBLOB do not match!");
133 }
134
135 #ifdef CFG_NXP_CAAM_MP_DRV
caam_hal_ctrl_get_mpcurve(vaddr_t ctrl_addr)136 uint8_t caam_hal_ctrl_get_mpcurve(vaddr_t ctrl_addr)
137 {
138 uint32_t val_scfgr = 0;
139
140 /*
141 * On i.MX8MQ B0, the MP is not usable, hence
142 * return UINT8_MAX
143 */
144 if (soc_is_imx8mq_b0_layer())
145 return UINT8_MAX;
146
147 /*
148 * Verify if the device is closed or not
149 * If device is closed, check get the MPCurve
150 */
151 if (snvs_is_device_closed()) {
152 /* Get the SCFGR content */
153 val_scfgr = io_caam_read32(ctrl_addr + SCFGR);
154
155 /* Get the MPCurve field value - 4 bits */
156 val_scfgr = (val_scfgr & BM_SCFGR_MPCURVE) >> BS_SCFGR_MPCURVE;
157
158 /*
159 * If the device is closed and the MPCurve field is 0
160 * return UINT8_MAX indicating that there is a problem and the
161 * MP can not be supported.
162 */
163 if (!val_scfgr)
164 return UINT8_MAX;
165 }
166
167 return val_scfgr;
168 }
169
caam_hal_ctrl_read_mpmr(vaddr_t ctrl_addr,struct caambuf * mpmr)170 TEE_Result caam_hal_ctrl_read_mpmr(vaddr_t ctrl_addr, struct caambuf *mpmr)
171 {
172 unsigned int i = 0;
173 uint32_t val = 0;
174
175 if (mpmr->length < MPMR_NB_REG) {
176 mpmr->length = MPMR_NB_REG;
177 return TEE_ERROR_SHORT_BUFFER;
178 }
179
180 /* MPMR endianness is reverted between write and read */
181 for (i = 0; i < MPMR_NB_REG; i += 4) {
182 val = io_caam_read32(ctrl_addr + MPMR + i);
183 mpmr->data[i] = (uint8_t)(val >> 24);
184 mpmr->data[i + 1] = (uint8_t)(val >> 16);
185 mpmr->data[i + 2] = (uint8_t)(val >> 8);
186 mpmr->data[i + 3] = (uint8_t)val;
187 }
188
189 mpmr->length = MPMR_NB_REG;
190 return TEE_SUCCESS;
191 }
192
caam_hal_ctrl_is_mp_set(vaddr_t ctrl_addr)193 bool caam_hal_ctrl_is_mp_set(vaddr_t ctrl_addr)
194 {
195 return io_caam_read32(ctrl_addr + SCFGR) & BM_SCFGR_MPMRL;
196 }
197
caam_hal_ctrl_fill_mpmr(vaddr_t ctrl_addr,struct caambuf * msg_mpmr)198 void caam_hal_ctrl_fill_mpmr(vaddr_t ctrl_addr, struct caambuf *msg_mpmr)
199 {
200 size_t i = 0;
201 vaddr_t reg = ctrl_addr + MPMR;
202 bool is_filled = false;
203 uint32_t val = 0;
204 size_t min_size = 0;
205 size_t remain_size = 0;
206
207 /* check if the MPMR is filled */
208 is_filled = caam_hal_ctrl_is_mp_set(ctrl_addr);
209
210 DMSG("is_filled = %s", is_filled ? "true" : "false");
211
212 if (!is_filled) {
213 /*
214 * Fill the MPMR with the most significant input value and
215 * complete with 0's if value too short.
216 */
217 min_size = MIN(msg_mpmr->length, (size_t)MPMR_NB_REG);
218 remain_size = min_size % 4;
219
220 for (i = 0; i < min_size - remain_size; i += 4, reg += 4) {
221 val = msg_mpmr->data[i] | msg_mpmr->data[i + 1] << 8 |
222 msg_mpmr->data[i + 2] << 16 |
223 msg_mpmr->data[i + 3] << 24;
224 io_caam_write32(reg, val);
225 }
226
227 /* Last input bytes value */
228 if (remain_size) {
229 val = 0;
230
231 /*
232 * Fill the MPMR with the 8 bits values
233 * until the end of the message length
234 */
235 for (i = 0; i < remain_size; i++)
236 val |= msg_mpmr->data[i] << (i * 8);
237 io_caam_write32(reg, val);
238 reg += 4;
239 }
240
241 /* Complete with 0's */
242 remain_size = (MPMR_NB_REG - ROUNDUP(msg_mpmr->length, 4)) / 4;
243 for (i = 0; i < remain_size; i++, reg += 4)
244 io_caam_write32(reg, 0x0);
245
246 /*
247 * Locks the MPMR for writing and remains locked until
248 * the next power-on session.
249 */
250 io_caam_write32(ctrl_addr + SCFGR,
251 io_caam_read32(ctrl_addr + SCFGR) |
252 BM_SCFGR_MPMRL);
253
254 DMSG("val_scfgr = %#"PRIx32, io_caam_read32(ctrl_addr + SCFGR));
255 }
256 }
257 #endif /* CFG_NXP_CAAM_MP_DRV */
258
259 #ifdef CFG_NXP_CAAM_SM_DRV
caam_hal_ctrl_get_smvaddr(vaddr_t ctrl_addr,paddr_t jr_offset)260 vaddr_t caam_hal_ctrl_get_smvaddr(vaddr_t ctrl_addr, paddr_t jr_offset)
261 {
262 /*
263 * The Secure Memory Virtual Base Address contains only the upper
264 * bits of the base address of Secure Memory in this Job Ring's virtual
265 * address space. Since the base address of Secure Memory must be on a
266 * 64 kbyte boundary, the least significant 16 bits are omitted.
267 */
268 return io_caam_read32(ctrl_addr + JRX_SMVBAR(JRX_IDX(jr_offset))) << 16;
269 }
270 #endif /* CFG_NXP_CAAM_SM_DRV */
271