1 /*
2 * Copyright (c) 2026, Qualcomm Technologies, Inc. and/or its subsidiaries.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <string.h>
8
9 #include <common/debug.h>
10 #include <lib/utils_def.h>
11 #include <vmidmt_hal.h>
12 #include <vmidmt_hal_hwio.h>
13
14 #define HAL_VMIDMT_DEFAULT_CR0 0x00000111
15 #define HAL_VMIDMT_DEFAULT_CR2 0
16 #define HAL_VMIDMT_DEFAULT_ACR 0
17 #define HAL_VMIDMT_DEFAULT_S2VR 0x00010000
18 #define HAL_VMIDMT_MAX_SSD 4
19
20 #define VMIDMT_ALL_VMID_MASK 0xFFFFFFFF
21 #define VMIDMT_NUM_NSSTATE_BITS 32
22 #define VMIDMT_MEMATTR_MAX_BITS 3
23
24 #define IS_NUM_SSD_VALID(num_ssd) (num_ssd <= HAL_VMIDMT_MAX_SSD)
25
26 #define ALL_ERROR_OPTIONS \
27 (HAL_VMIDMT_ERROR_O_SMCFCFG_EN | HAL_VMIDMT_ERROR_O_USFCFG_EN | \
28 HAL_VMIDMT_ERROR_O_GCFGFIE | HAL_VMIDMT_ERROR_O_GCFGFRE | \
29 HAL_VMIDMT_ERROR_O_GFIE)
30
31 #define CR0_ERE_MASK \
32 (VMIDMT_FMSK(CR0, SMCFCFG) | VMIDMT_FMSK(CR0, USFCFG) | \
33 VMIDMT_FMSK(CR0, GCFGFIE) | VMIDMT_FMSK(CR0, GCFGFRE) | \
34 VMIDMT_FMSK(CR0, GFIE))
35
36 #define CR0_BUS_MASK \
37 (VMIDMT_FMSK(CR0, WACFG) | VMIDMT_FMSK(CR0, RACFG) | \
38 VMIDMT_FMSK(CR0, SHCFG) | VMIDMT_FMSK(CR0, MTCFG) | \
39 VMIDMT_FMSK(CR0, MEMATTR) | VMIDMT_FMSK(CR0, TRANSIENTCFG))
40
read_id_registers(struct hal_vmidmt_info * info)41 static void read_id_registers(struct hal_vmidmt_info *info)
42 {
43 uint32_t reg;
44
45 reg = VMIDMT_IN(info->base_addr, IDR0);
46 info->dev_params.stream_match_support = VMIDMT_INFC(reg, IDR0, SMS);
47 info->dev_params.num_stream_id_bits = VMIDMT_INFC(reg, IDR0, NUMSIDB);
48 info->dev_params.entry_count = VMIDMT_INFC(reg, IDR0, NUMSMRG);
49 reg = VMIDMT_IN(info->base_addr, IDR1);
50 info->dev_params.num_ssd_index_bits =
51 VMIDMT_INFC(reg, IDR1, NUMSSDNDXB);
52 reg = VMIDMT_IN(info->base_addr, IDR2);
53 info->dev_params.input_addr_size = VMIDMT_INFC(reg, IDR2, IAS);
54 reg = VMIDMT_IN(info->base_addr, IDR5);
55 info->dev_params.num_vmid = VMIDMT_INFC(reg, IDR5, NVMID);
56 }
57
58 static inline enum hal_vmidmt_access
get_permissions(const struct hal_vmidmt_access_config * cfg,uint32_t vmid)59 get_permissions(const struct hal_vmidmt_access_config *cfg, uint32_t vmid)
60 {
61 uint32_t field = vmid % HAL_VMIDMT_PERMS_PER_FIELD;
62 uint32_t word = vmid / HAL_VMIDMT_PERMS_PER_FIELD;
63 uint32_t shift = field * HAL_VMIDMT_PERM_WIDTH;
64 uint32_t perm = cfg->au_vmid_perm[word];
65
66 return (enum hal_vmidmt_access)((perm >> shift) & HAL_VMIDMT_PERM_MASK);
67 }
68
mask_bit_set(const struct hal_vmidmt_access_config * cfg,uint32_t vmid)69 static inline bool mask_bit_set(const struct hal_vmidmt_access_config *cfg,
70 uint32_t vmid)
71 {
72 uint32_t field = vmid % HAL_VMIDMT_MASKS_PER_FIELD;
73 uint32_t word = vmid / HAL_VMIDMT_MASKS_PER_FIELD;
74 uint32_t bit = field * HAL_VMIDMT_PERM_WIDTH;
75 uint32_t mask = (uint32_t)BIT(bit);
76
77 return (cfg->au_vmid[word] & mask) != 0U;
78 }
79
80 static enum hal_vmidmt_status
configure_acr(uint64_t addr,struct hal_vmidmt_access_config * cfg)81 configure_acr(uint64_t addr, struct hal_vmidmt_access_config *cfg)
82 {
83 enum hal_vmidmt_access perm;
84 uint32_t acr_val = 0;
85 uint32_t acr = 0;
86
87 for (size_t vmid = 0; vmid <= HAL_VMIDMT_MAX_VMID; vmid++) {
88 if (!mask_bit_set(cfg, vmid))
89 continue;
90
91 /* only set bits for full access masters */
92 perm = get_permissions(cfg, vmid);
93 if (perm == HAL_VMIDMT_FULL_ACCESS)
94 acr |= 1 << vmid;
95 }
96
97 VMIDMT_OUTM(addr, VMIDMTACR, cfg->au_vmid[0], acr);
98 acr_val = VMIDMT_INM(addr, VMIDMTACR, cfg->au_vmid[0]);
99 if (acr_val != acr)
100 return HAL_VMIDMT_READ_WRITE_MISMATCH;
101
102 return HAL_VMIDMT_NO_ERROR;
103 }
104
set_default_config_bus(struct hal_vmidmt_bus_attrib * bus)105 static uint32_t set_default_config_bus(struct hal_vmidmt_bus_attrib *bus)
106 {
107 uint32_t attrib = 0;
108
109 if (bus->e_wacfg < HAL_VMIDMT_WACFG_DEFAULT)
110 attrib |= bus->e_wacfg << VMIDMT_SHFT(CR0, WACFG);
111
112 if (bus->e_racfg < HAL_VMIDMT_RACFG_DEFAULT)
113 attrib |= bus->e_racfg << VMIDMT_SHFT(CR0, RACFG);
114
115 if (bus->e_shcfg < HAL_VMIDMT_SHCFG_DEFAULT)
116 attrib |= bus->e_shcfg << VMIDMT_SHFT(CR0, SHCFG);
117
118 if (bus->e_mtcfg < HAL_VMIDMT_MTCFG_DEFAULT)
119 attrib |= bus->e_mtcfg << VMIDMT_SHFT(CR0, MTCFG);
120
121 attrib |= bus->mem_attr << VMIDMT_SHFT(CR0, MEMATTR);
122
123 if (bus->e_transient_cfg < HAL_VMIDMT_TRANSIENTCFG_DEFAULT)
124 attrib |= bus->e_transient_cfg
125 << VMIDMT_SHFT(CR0, TRANSIENTCFG);
126
127 return attrib;
128 }
129
set_default_config_aux(struct hal_vmidmt_aux_config * aux)130 static uint32_t set_default_config_aux(struct hal_vmidmt_aux_config *aux)
131 {
132 uint32_t config = 0;
133
134 if (aux->e_rcnsh < HAL_VMIDMT_RCNSH_DEFAULT)
135 config |= aux->e_rcnsh << VMIDMT_SHFT(ACR, BPRCNSH);
136
137 if (aux->e_rcish < HAL_VMIDMT_RCISH_DEFAULT)
138 config |= aux->e_rcish << VMIDMT_SHFT(ACR, BPRCISH);
139
140 if (aux->e_rcosh < HAL_VMIDMT_RCOSH_DEFAULT)
141 config |= aux->e_rcosh << VMIDMT_SHFT(ACR, BPRCOSH);
142
143 if (aux->e_req_priority_cfg < HAL_VMIDMT_REQPRICFG_DEFAULT)
144 config |= aux->e_req_priority_cfg
145 << VMIDMT_SHFT(ACR, REQPRIORITYCFG);
146
147 if (aux->e_req_priority < HAL_VMIDMT_REQPRI_DEFAULT)
148 config |= aux->e_req_priority << VMIDMT_SHFT(ACR, REQPRIORITY);
149
150 return config;
151 }
152
153 static enum hal_vmidmt_status
set_default_config(const struct hal_vmidmt_info * p,const struct hal_vmidmt_default_vmid_config * cfg,bool sec)154 set_default_config(const struct hal_vmidmt_info *p,
155 const struct hal_vmidmt_default_vmid_config *cfg, bool sec)
156 {
157 struct hal_vmidmt_bus_attrib *bypass_bus = cfg->p_bypass_bus_attrib;
158 struct hal_vmidmt_aux_config *bypass_aux = cfg->p_bypass_aux_config;
159 uint32_t attrib = 0;
160 uint32_t config = 0;
161 uint32_t val = 0;
162 enum hal_vmidmt_status rc = HAL_VMIDMT_NO_ERROR;
163
164 if (!cfg)
165 return HAL_VMIDMT_INVALID_PARAM;
166
167 if (bypass_bus &&
168 bypass_bus->mem_attr > (1 << VMIDMT_MEMATTR_MAX_BITS) - 1)
169 return HAL_VMIDMT_INVALID_PARAM;
170
171 if (cfg->p_access_control) {
172 rc = configure_acr(p->base_addr, cfg->p_access_control);
173 if (rc != HAL_VMIDMT_NO_ERROR)
174 return rc;
175 }
176
177 if (bypass_bus)
178 attrib |= set_default_config_bus(bypass_bus);
179
180 if (bypass_aux)
181 config |= set_default_config_aux(bypass_aux);
182
183 if (sec) {
184 if (bypass_bus &&
185 bypass_bus->e_nscfg < HAL_VMIDMT_NSCFG_DEFAULT)
186 attrib |= bypass_bus->e_nscfg
187 << VMIDMT_SHFT(SCR0, NSCFG);
188
189 VMIDMT_OUTM(p->base_addr, SCR0,
190 (CR0_BUS_MASK | VMIDMT_FMSK(SCR0, NSCFG)), attrib);
191 val = VMIDMT_INM(p->base_addr, SCR0,
192 (CR0_BUS_MASK | VMIDMT_FMSK(SCR0, NSCFG)));
193 if (val != attrib)
194 return HAL_VMIDMT_READ_WRITE_MISMATCH;
195
196 VMIDMT_OUTF(p->base_addr, SCR0, VMIDPNE,
197 cfg->b_vmid_private_namespace_enable);
198 val = VMIDMT_INF(p->base_addr, SCR0, VMIDPNE);
199 if (val != (uint32_t)cfg->b_vmid_private_namespace_enable)
200 return HAL_VMIDMT_READ_WRITE_MISMATCH;
201
202 VMIDMT_OUTF(p->base_addr, SCR2, BPVMID, cfg->bypass_vmid);
203 val = VMIDMT_INF(p->base_addr, SCR2, BPVMID);
204 if (val != (uint32_t)cfg->bypass_vmid)
205 return HAL_VMIDMT_READ_WRITE_MISMATCH;
206
207 VMIDMT_OUTM(p->base_addr, SACR, VMIDMT_RMSK(SACR), config);
208 val = VMIDMT_INM(p->base_addr, SACR, VMIDMT_RMSK(SACR));
209 if (val != config)
210 return HAL_VMIDMT_READ_WRITE_MISMATCH;
211 } else {
212 VMIDMT_OUTM(p->base_addr, NSCR0, CR0_BUS_MASK, attrib);
213 val = VMIDMT_INM(p->base_addr, NSCR0, CR0_BUS_MASK);
214 if (val != attrib)
215 return HAL_VMIDMT_READ_WRITE_MISMATCH;
216
217 VMIDMT_OUTF(p->base_addr, NSCR0, VMIDPNE,
218 cfg->b_vmid_private_namespace_enable);
219 val = VMIDMT_INF(p->base_addr, NSCR0, VMIDPNE);
220 if (val != (uint32_t)cfg->b_vmid_private_namespace_enable)
221 return HAL_VMIDMT_READ_WRITE_MISMATCH;
222
223 VMIDMT_OUTF(p->base_addr, NSCR2, BPVMID, cfg->bypass_vmid);
224 val = VMIDMT_INF(p->base_addr, NSCR2, BPVMID);
225 if (val != (uint32_t)cfg->bypass_vmid)
226 return HAL_VMIDMT_READ_WRITE_MISMATCH;
227
228 VMIDMT_OUTM(p->base_addr, NSACR, VMIDMT_RMSK(NSACR), config);
229 val = VMIDMT_INM(p->base_addr, NSACR, VMIDMT_RMSK(NSACR));
230 if (val != config)
231 return HAL_VMIDMT_READ_WRITE_MISMATCH;
232 }
233
234 return HAL_VMIDMT_NO_ERROR;
235 }
236
swap_context(const struct hal_vmidmt_info * info,uint32_t old_idx,uint32_t new_idx)237 static enum hal_vmidmt_status swap_context(const struct hal_vmidmt_info *info,
238 uint32_t old_idx, uint32_t new_idx)
239 {
240 uint32_t s2vr_msk = VMIDMT_RMSK(S2VRn);
241 uint32_t src_val = 0;
242 uint32_t dst_val = 0;
243
244 src_val = VMIDMT_INI(info->base_addr, SMRn, old_idx);
245
246 VMIDMT_OUTI(info->base_addr, SMRn, new_idx, src_val);
247
248 dst_val = VMIDMT_INI(info->base_addr, SMRn, new_idx);
249 if (dst_val != src_val)
250 return HAL_VMIDMT_READ_WRITE_MISMATCH;
251
252 src_val = VMIDMT_INMI(info->base_addr, S2VRn, old_idx, s2vr_msk);
253
254 VMIDMT_OUTMI(info->base_addr, S2VRn, new_idx, s2vr_msk, src_val);
255
256 dst_val = VMIDMT_INMI(info->base_addr, S2VRn, new_idx, s2vr_msk);
257 if (dst_val != src_val)
258 return HAL_VMIDMT_READ_WRITE_MISMATCH;
259
260 src_val = VMIDMT_INI(info->base_addr, AS2VRn, old_idx);
261
262 VMIDMT_OUTI(info->base_addr, AS2VRn, new_idx, src_val);
263
264 dst_val = VMIDMT_INI(info->base_addr, AS2VRn, new_idx);
265 if (dst_val != src_val)
266 return HAL_VMIDMT_READ_WRITE_MISMATCH;
267
268 return HAL_VMIDMT_NO_ERROR;
269 }
270
erase_context(const struct hal_vmidmt_info * info,uint32_t ctx_idx)271 static enum hal_vmidmt_status erase_context(const struct hal_vmidmt_info *info,
272 uint32_t ctx_idx)
273 {
274 uint32_t s2vr_mask = VMIDMT_RMSK(S2VRn);
275 uint32_t rd_val;
276
277 VMIDMT_OUTI(info->base_addr, SMRn, ctx_idx, 0);
278
279 rd_val = VMIDMT_INI(info->base_addr, SMRn, ctx_idx);
280 if (rd_val != 0U)
281 return HAL_VMIDMT_READ_WRITE_MISMATCH;
282
283 VMIDMT_OUTMI(info->base_addr, S2VRn, ctx_idx, s2vr_mask, 0);
284
285 rd_val = VMIDMT_INMI(info->base_addr, S2VRn, ctx_idx, s2vr_mask);
286 if (rd_val != 0U)
287 return HAL_VMIDMT_READ_WRITE_MISMATCH;
288
289 VMIDMT_OUTI(info->base_addr, AS2VRn, ctx_idx, 0);
290
291 rd_val = VMIDMT_INI(info->base_addr, AS2VRn, ctx_idx);
292 if (rd_val != 0U)
293 return HAL_VMIDMT_READ_WRITE_MISMATCH;
294
295 return HAL_VMIDMT_NO_ERROR;
296 }
297
configure_context_bus(const struct hal_vmidmt_bus_attrib * bus)298 static uint32_t configure_context_bus(const struct hal_vmidmt_bus_attrib *bus)
299 {
300 uint32_t s2vr = 0;
301
302 if (bus->e_nscfg < HAL_VMIDMT_NSCFG_DEFAULT)
303 s2vr |= bus->e_nscfg << VMIDMT_SHFT(S2VRn, NSCFG);
304
305 if (bus->e_wacfg < HAL_VMIDMT_WACFG_DEFAULT)
306 s2vr |= bus->e_wacfg << VMIDMT_SHFT(S2VRn, WACFG);
307
308 if (bus->e_racfg < HAL_VMIDMT_RACFG_DEFAULT)
309 s2vr |= bus->e_racfg << VMIDMT_SHFT(S2VRn, RACFG);
310
311 if (bus->e_shcfg < HAL_VMIDMT_SHCFG_DEFAULT)
312 s2vr |= bus->e_shcfg << VMIDMT_SHFT(S2VRn, SHCFG);
313
314 if (bus->e_mtcfg < HAL_VMIDMT_MTCFG_DEFAULT)
315 s2vr |= bus->e_mtcfg << VMIDMT_SHFT(S2VRn, MTCFG);
316
317 s2vr |= bus->mem_attr << VMIDMT_SHFT(S2VRn, MEMATTR);
318
319 if (bus->e_transient_cfg < HAL_VMIDMT_TRANSIENTCFG_DEFAULT)
320 s2vr |= bus->e_transient_cfg
321 << VMIDMT_SHFT(S2VRn, TRANSIENTCFG);
322
323 return s2vr;
324 }
325
configure_context_aux(const struct hal_vmidmt_aux_config * aux)326 static uint32_t configure_context_aux(const struct hal_vmidmt_aux_config *aux)
327 {
328 uint32_t as2vr = 0;
329
330 if (aux->e_rcnsh < HAL_VMIDMT_RCNSH_DEFAULT)
331 as2vr |= aux->e_rcnsh << VMIDMT_SHFT(AS2VRn, RCNSH);
332
333 if (aux->e_rcish < HAL_VMIDMT_RCISH_DEFAULT)
334 as2vr |= aux->e_rcish << VMIDMT_SHFT(AS2VRn, RCISH);
335
336 if (aux->e_rcosh < HAL_VMIDMT_RCOSH_DEFAULT)
337 as2vr |= aux->e_rcosh << VMIDMT_SHFT(AS2VRn, RCOSH);
338
339 if (aux->e_req_priority_cfg < HAL_VMIDMT_REQPRICFG_DEFAULT)
340 as2vr |= aux->e_req_priority_cfg
341 << VMIDMT_SHFT(AS2VRn, REQPRIORITYCFG);
342
343 if (aux->e_req_priority < HAL_VMIDMT_REQPRI_DEFAULT)
344 as2vr |= aux->e_req_priority
345 << VMIDMT_SHFT(AS2VRn, REQPRIORITY);
346
347 return as2vr;
348 }
349
350 static enum hal_vmidmt_status
configure_context(const struct hal_vmidmt_info * info,uint32_t index,const struct hal_vmidmt_context_config * config)351 configure_context(const struct hal_vmidmt_info *info, uint32_t index,
352 const struct hal_vmidmt_context_config *config)
353 {
354 const struct hal_vmidmt_bus_attrib *bus_attrib = config->p_bus_attrib;
355 const struct hal_vmidmt_aux_config *aux_config = config->p_aux_config;
356 uint32_t as2vr_val = 0;
357 uint32_t s2vr_val = 0;
358 uint32_t readback;
359
360 s2vr_val |= config->u_vmid << VMIDMT_SHFT(S2VRn, VMID);
361
362 if (bus_attrib != NULL)
363 s2vr_val |= configure_context_bus(bus_attrib);
364
365 VMIDMT_OUTMI(info->base_addr, S2VRn, index, VMIDMT_RMSK(S2VRn),
366 s2vr_val);
367
368 readback =
369 VMIDMT_INMI(info->base_addr, S2VRn, index, VMIDMT_RMSK(S2VRn));
370 if (readback != s2vr_val)
371 return HAL_VMIDMT_READ_WRITE_MISMATCH;
372
373 if (aux_config != NULL)
374 as2vr_val |= configure_context_aux(aux_config);
375
376 VMIDMT_OUTI(info->base_addr, AS2VRn, index, as2vr_val);
377
378 readback = VMIDMT_INI(info->base_addr, AS2VRn, index);
379 if (readback != as2vr_val)
380 return HAL_VMIDMT_READ_WRITE_MISMATCH;
381
382 return HAL_VMIDMT_NO_ERROR;
383 }
384
vmidmt_hal_enable_client(const struct hal_vmidmt_info * p,bool sec)385 enum hal_vmidmt_status vmidmt_hal_enable_client(const struct hal_vmidmt_info *p,
386 bool sec)
387 {
388 uint32_t read_back = 0;
389
390 if (sec) {
391 VMIDMT_OUTF(p->base_addr, SCR0, CLIENTPD, read_back);
392 read_back = VMIDMT_INF(p->base_addr, SCR0, CLIENTPD);
393 } else {
394 VMIDMT_OUTF(p->base_addr, NSCR0, CLIENTPD, read_back);
395 read_back = VMIDMT_INF(p->base_addr, NSCR0, CLIENTPD);
396 }
397
398 return read_back ? HAL_VMIDMT_READ_WRITE_MISMATCH : HAL_VMIDMT_NO_ERROR;
399 }
400
401 enum hal_vmidmt_status
vmidmt_hal_config_ssdt(const struct hal_vmidmt_info * p,const hal_vmidmt_secure_status_det * status,uint32_t elements)402 vmidmt_hal_config_ssdt(const struct hal_vmidmt_info *p,
403 const hal_vmidmt_secure_status_det *status,
404 uint32_t elements)
405 {
406 uint32_t length = 0;
407
408 if (!p || !status || !IS_NUM_SSD_VALID(elements))
409 return HAL_VMIDMT_INVALID_PARAM;
410
411 length = 1 << p->dev_params.num_ssd_index_bits;
412
413 if (length < VMIDMT_NUM_NSSTATE_BITS) {
414 if (elements > 1)
415 return HAL_VMIDMT_INVALID_PARAM;
416 } else {
417 if (elements > length / VMIDMT_NUM_NSSTATE_BITS)
418 return HAL_VMIDMT_INVALID_PARAM;
419 }
420
421 for (size_t i = 0; i < elements; i++)
422 VMIDMT_OUTMI(p->base_addr, SSDRn, i, ~status[i], status[i]);
423
424 return HAL_VMIDMT_NO_ERROR;
425 }
426
427 enum hal_vmidmt_status
vmidmt_hal_init(struct hal_vmidmt_info * info,const struct hal_vmidmt_default_secure_vmid_config * sec_cfg,const struct hal_vmidmt_default_vmid_config * nsec_cfg,char ** ver)428 vmidmt_hal_init(struct hal_vmidmt_info *info,
429 const struct hal_vmidmt_default_secure_vmid_config *sec_cfg,
430 const struct hal_vmidmt_default_vmid_config *nsec_cfg,
431 char **ver)
432 {
433 uint32_t ssd_words = 0;
434 uint32_t ssd_mask_bits = 0;
435 uint8_t sec_ext = 0;
436 uint32_t scr1_init = 0;
437 uint32_t rb_val = 0;
438 uint32_t idx;
439 enum hal_vmidmt_status st = HAL_VMIDMT_NO_ERROR;
440
441 if (sec_cfg && nsec_cfg)
442 return HAL_VMIDMT_INVALID_PARAM;
443
444 read_id_registers(info);
445
446 VMIDMT_OUT(info->base_addr, VMIDMTACR, VMIDMT_ALL_VMID_MASK);
447
448 if (sec_cfg) {
449 sec_ext = sec_cfg->secure_extensions;
450
451 if (sec_cfg->secure_extensions ==
452 HAL_VMIDMT_SECURE_EXT_DEFAULT) {
453 sec_ext = info->dev_params.entry_count;
454
455 } else if (sec_cfg->secure_extensions >
456 info->dev_params.entry_count) {
457 st = HAL_VMIDMT_INVALID_PARAM;
458 goto out;
459 }
460
461 st = set_default_config(info, sec_cfg->p_default_secure_config,
462 true);
463 if (st != HAL_VMIDMT_NO_ERROR)
464 goto out;
465
466 VMIDMT_OUTF(info->base_addr, SCR1, GASRAE,
467 sec_cfg->b_glb_addr_space_restricted_acc_enable);
468
469 rb_val = VMIDMT_INF(info->base_addr, SCR1, GASRAE);
470 if (rb_val != sec_cfg->b_glb_addr_space_restricted_acc_enable) {
471 st = HAL_VMIDMT_READ_WRITE_MISMATCH;
472 goto out;
473 }
474
475 VMIDMT_OUTF(info->base_addr, SCR1, NSNUMSMRGO, sec_ext);
476
477 rb_val = VMIDMT_INF(info->base_addr, SCR1, NSNUMSMRGO);
478 if (rb_val != sec_ext) {
479 st = HAL_VMIDMT_READ_WRITE_MISMATCH;
480 goto out;
481 }
482
483 VMIDMT_OUT(info->base_addr, NSCR0, HAL_VMIDMT_DEFAULT_CR0);
484
485 VMIDMT_OUT(info->base_addr, NSCR2, HAL_VMIDMT_DEFAULT_CR2);
486
487 VMIDMT_OUT(info->base_addr, NSACR, HAL_VMIDMT_DEFAULT_ACR);
488
489 } else {
490 VMIDMT_OUT(info->base_addr, SCR0, HAL_VMIDMT_DEFAULT_CR0);
491
492 scr1_init = info->dev_params.entry_count
493 << VMIDMT_SHFT(SCR1, NSNUMSMRGO);
494
495 VMIDMT_OUT(info->base_addr, SCR1, scr1_init);
496
497 VMIDMT_OUT(info->base_addr, SCR2, HAL_VMIDMT_DEFAULT_CR2);
498
499 VMIDMT_OUT(info->base_addr, SACR, HAL_VMIDMT_DEFAULT_ACR);
500
501 st = set_default_config(info, nsec_cfg, false);
502 if (st != HAL_VMIDMT_NO_ERROR)
503 goto out;
504 }
505
506 VMIDMT_OUT(info->base_addr, SVMIDMTCR0, 1);
507 VMIDMT_OUT(info->base_addr, NSVMIDMTCR0, 1);
508 VMIDMT_OUT(info->base_addr, SGFSRRESTORE, 0);
509 VMIDMT_OUT(info->base_addr, NSGFSRRESTORE, 0);
510
511 ssd_words = 1;
512 ssd_mask_bits = BIT(info->dev_params.num_ssd_index_bits);
513
514 if (ssd_mask_bits >= VMIDMT_NUM_NSSTATE_BITS) {
515 ssd_words = ssd_mask_bits / VMIDMT_NUM_NSSTATE_BITS;
516
517 if (!IS_NUM_SSD_VALID(ssd_words)) {
518 st = HAL_VMIDMT_INVALID_HW_VALUE;
519 goto out;
520 }
521 }
522
523 for (idx = 0; idx < ssd_words; idx++) {
524 VMIDMT_OUTI(info->base_addr, SSDRn, idx, 0xFFFFFFFF);
525 }
526
527 out:
528 for (idx = 0; idx < info->dev_params.entry_count; idx++) {
529 if (info->dev_params.stream_match_support)
530 VMIDMT_OUTI(info->base_addr, SMRn, idx, 0);
531
532 VMIDMT_OUTI(info->base_addr, S2VRn, idx,
533 HAL_VMIDMT_DEFAULT_S2VR);
534
535 VMIDMT_OUTI(info->base_addr, AS2VRn, idx, 0);
536 }
537
538 return st;
539 }
540
541 static enum hal_vmidmt_status
validate_ctx_args(const struct hal_vmidmt_info * info,uint32_t stream,const struct hal_vmidmt_context_config * cfg,bool * secure)542 validate_ctx_args(const struct hal_vmidmt_info *info, uint32_t stream,
543 const struct hal_vmidmt_context_config *cfg, bool *secure)
544 {
545 const uint32_t max_attr = (1U << VMIDMT_MEMATTR_MAX_BITS) - 1U;
546 uint32_t max_stream_id;
547
548 if (cfg == NULL)
549 return HAL_VMIDMT_INVALID_PARAM;
550
551 max_stream_id = (1U << info->dev_params.num_stream_id_bits) - 1U;
552
553 if (stream > max_stream_id && stream >= info->dev_params.entry_count)
554 return HAL_VMIDMT_INVALID_PARAM;
555
556 *secure = false;
557
558 if (!cfg->p_bus_attrib)
559 return HAL_VMIDMT_NO_ERROR;
560
561 if (cfg->p_bus_attrib->mem_attr > max_attr)
562 return HAL_VMIDMT_INVALID_PARAM;
563
564 if (cfg->p_bus_attrib->e_nscfg == HAL_VMIDMT_NSCFG_SECURE)
565 *secure = true;
566
567 return HAL_VMIDMT_NO_ERROR;
568 }
569
update_ssdrn(const struct hal_vmidmt_info * info,uint32_t stream,bool is_secure)570 static enum hal_vmidmt_status update_ssdrn(const struct hal_vmidmt_info *info,
571 uint32_t stream, bool is_secure)
572 {
573 uint32_t ssd_index;
574 uint32_t bit_mask;
575 uint32_t desired;
576 uint32_t ssdrn_val;
577
578 ssd_index = stream / VMIDMT_NUM_NSSTATE_BITS;
579 bit_mask = BIT(stream % VMIDMT_NUM_NSSTATE_BITS);
580
581 /* 0 = secure, 1 = non-secure */
582 desired = is_secure ? 0U : bit_mask;
583
584 VMIDMT_OUTMI(info->base_addr, SSDRn, ssd_index, bit_mask, desired);
585
586 ssdrn_val = VMIDMT_INMI(info->base_addr, SSDRn, ssd_index, bit_mask);
587
588 if ((ssdrn_val & bit_mask) != desired)
589 return HAL_VMIDMT_READ_WRITE_MISMATCH;
590
591 return HAL_VMIDMT_NO_ERROR;
592 }
593
find_matching_smr(const struct hal_vmidmt_info * info,uint32_t entry_count,uint32_t smr_val)594 static int32_t find_matching_smr(const struct hal_vmidmt_info *info,
595 uint32_t entry_count, uint32_t smr_val)
596 {
597 for (int32_t i = 0; i < (int32_t)entry_count; i++) {
598 if (VMIDMT_INI(info->base_addr, SMRn, (uint32_t)i) == smr_val)
599 return i;
600 }
601
602 return -1;
603 }
604
605 static enum hal_vmidmt_status
move_to_ns_tail(const struct hal_vmidmt_info * info,uint32_t ns_smr_count,int32_t * idx)606 move_to_ns_tail(const struct hal_vmidmt_info *info, uint32_t ns_smr_count,
607 int32_t *idx)
608 {
609 enum hal_vmidmt_status rc = HAL_VMIDMT_NO_ERROR;
610 int32_t i = *idx;
611
612 for (; (uint32_t)i < ns_smr_count - 1U; i++) {
613 rc = swap_context(info, (uint32_t)i + 1U, (uint32_t)i);
614 if (rc != HAL_VMIDMT_NO_ERROR)
615 return rc;
616 }
617
618 *idx = i;
619 return HAL_VMIDMT_NO_ERROR;
620 }
621
622 static enum hal_vmidmt_status
move_to_ns_head(const struct hal_vmidmt_info * info,uint32_t * ns_smr_count,int32_t * idx)623 move_to_ns_head(const struct hal_vmidmt_info *info, uint32_t *ns_smr_count,
624 int32_t *idx)
625 {
626 enum hal_vmidmt_status rc = HAL_VMIDMT_NO_ERROR;
627 uint32_t read_back;
628 int32_t i = *idx;
629
630 for (; (uint32_t)i > *ns_smr_count; i--) {
631 rc = swap_context(info, (uint32_t)i - 1U, (uint32_t)i);
632 if (rc != HAL_VMIDMT_NO_ERROR)
633 return rc;
634 }
635
636 *idx = i;
637 (*ns_smr_count)++;
638
639 VMIDMT_OUTF(info->base_addr, SCR1, NSNUMSMRGO, *ns_smr_count);
640
641 read_back = VMIDMT_INF(info->base_addr, SCR1, NSNUMSMRGO);
642 if (read_back != *ns_smr_count)
643 return HAL_VMIDMT_READ_WRITE_MISMATCH;
644
645 return HAL_VMIDMT_NO_ERROR;
646 }
647
648 static enum hal_vmidmt_status
find_secure_slot(const struct hal_vmidmt_info * info,uint32_t entry_count,uint32_t ns_smr_count,uint32_t stream,int32_t * idx)649 find_secure_slot(const struct hal_vmidmt_info *info, uint32_t entry_count,
650 uint32_t ns_smr_count, uint32_t stream, int32_t *idx)
651 {
652 int32_t i;
653
654 for (i = (int32_t)entry_count - 1; i >= 0; i--) {
655 if (VMIDMT_INFI(info->base_addr, SMRn, (uint32_t)i, VALID) !=
656 1U)
657 break;
658
659 if (VMIDMT_INFI(info->base_addr, SMRn, (uint32_t)i, ID) ==
660 stream)
661 break;
662 }
663
664 if (i < 0 || (uint32_t)i < ns_smr_count - 1U)
665 return HAL_VMIDMT_INVALID_PARAM;
666
667 /* found */
668 *idx = i;
669 return HAL_VMIDMT_NO_ERROR;
670 }
671
672 static enum hal_vmidmt_status
find_nonsecure_slot(const struct hal_vmidmt_info * info,uint32_t ns_smr_count,uint32_t stream,int32_t * idx)673 find_nonsecure_slot(const struct hal_vmidmt_info *info, uint32_t ns_smr_count,
674 uint32_t stream, int32_t *idx)
675 {
676 int32_t i;
677
678 for (i = 0; (uint32_t)i < ns_smr_count; i++) {
679 if (VMIDMT_INFI(info->base_addr, SMRn, (uint32_t)i, VALID) !=
680 1U)
681 break;
682
683 if (VMIDMT_INFI(info->base_addr, SMRn, (uint32_t)i, ID) ==
684 stream)
685 break;
686 }
687
688 if ((uint32_t)i >= ns_smr_count)
689 return HAL_VMIDMT_INVALID_PARAM;
690
691 /* found */
692 *idx = i;
693 return HAL_VMIDMT_NO_ERROR;
694 }
695
write_smr(const struct hal_vmidmt_info * info,bool is_secure,uint32_t smr_val,int32_t idx,uint32_t * ns_smr_count)696 static enum hal_vmidmt_status write_smr(const struct hal_vmidmt_info *info,
697 bool is_secure, uint32_t smr_val,
698 int32_t idx, uint32_t *ns_smr_count)
699 {
700 uint32_t rd_val;
701 uint32_t i = (uint32_t)idx;
702
703 VMIDMT_OUTI(info->base_addr, SMRn, i, smr_val);
704
705 rd_val = VMIDMT_INI(info->base_addr, SMRn, i);
706 if (rd_val != smr_val)
707 return HAL_VMIDMT_READ_WRITE_MISMATCH;
708
709 if (is_secure && i < *ns_smr_count) {
710 (*ns_smr_count)--;
711
712 VMIDMT_OUTF(info->base_addr, SCR1, NSNUMSMRGO, *ns_smr_count);
713
714 rd_val = VMIDMT_INF(info->base_addr, SCR1, NSNUMSMRGO);
715 if (rd_val != *ns_smr_count)
716 return HAL_VMIDMT_READ_WRITE_MISMATCH;
717 }
718
719 return HAL_VMIDMT_NO_ERROR;
720 }
721
update_smr(const struct hal_vmidmt_info * info,uint32_t stream,bool is_secure,uint32_t * index_out)722 static enum hal_vmidmt_status update_smr(const struct hal_vmidmt_info *info,
723 uint32_t stream, bool is_secure,
724 uint32_t *index_out)
725 {
726 enum hal_vmidmt_status rc = HAL_VMIDMT_NO_ERROR;
727 uint32_t entry_count = info->dev_params.entry_count;
728 uint32_t ns_smr_count;
729 uint32_t smr_val = 0U;
730 int32_t i;
731
732 ns_smr_count = VMIDMT_INF(info->base_addr, SCR1, NSNUMSMRGO);
733
734 smr_val |= BIT(VMIDMT_SHFT(SMRn, VALID));
735 smr_val |= stream << VMIDMT_SHFT(SMRn, ID);
736
737 i = find_matching_smr(info, entry_count, smr_val);
738
739 if (i >= 0) {
740 /* Existing SMR entry with same value. */
741 if (is_secure && (uint32_t)i >= ns_smr_count - 1U)
742 goto write_and_adjust;
743
744 if (!is_secure && (uint32_t)i < ns_smr_count)
745 goto write_and_adjust;
746
747 if ((uint32_t)i < ns_smr_count) {
748 rc = move_to_ns_tail(info, ns_smr_count, &i);
749 if (rc != HAL_VMIDMT_NO_ERROR)
750 return rc;
751 } else {
752 rc = move_to_ns_head(info, &ns_smr_count, &i);
753 if (rc != HAL_VMIDMT_NO_ERROR)
754 return rc;
755 }
756
757 rc = erase_context(info, (uint32_t)i);
758 if (rc != HAL_VMIDMT_NO_ERROR)
759 return rc;
760 } else {
761 /* No existing SMR entry with this value; find a slot. */
762 if (is_secure) {
763 rc = find_secure_slot(info, entry_count, ns_smr_count,
764 stream, &i);
765 if (rc != HAL_VMIDMT_NO_ERROR)
766 return rc;
767 } else {
768 rc = find_nonsecure_slot(info, ns_smr_count, stream,
769 &i);
770 if (rc != HAL_VMIDMT_NO_ERROR)
771 return rc;
772 }
773 }
774
775 write_and_adjust:
776 rc = write_smr(info, is_secure, smr_val, i, &ns_smr_count);
777 if (rc != HAL_VMIDMT_NO_ERROR)
778 return rc;
779
780 *index_out = (uint32_t)i;
781
782 return HAL_VMIDMT_NO_ERROR;
783 }
784
785 enum hal_vmidmt_status
vmidmt_hal_config_ctx(const struct hal_vmidmt_info * info,uint32_t stream,const struct hal_vmidmt_context_config * cfg)786 vmidmt_hal_config_ctx(const struct hal_vmidmt_info *info, uint32_t stream,
787 const struct hal_vmidmt_context_config *cfg)
788 {
789 enum hal_vmidmt_status rc;
790 bool secure = false;
791 uint32_t ctx_index = 0;
792
793 rc = validate_ctx_args(info, stream, cfg, &secure);
794 if (rc != HAL_VMIDMT_NO_ERROR)
795 return rc;
796
797 rc = update_ssdrn(info, stream, secure);
798 if (rc != HAL_VMIDMT_NO_ERROR)
799 return rc;
800
801 if (info->dev_params.stream_match_support) {
802 rc = update_smr(info, stream, secure, &ctx_index);
803 if (rc != HAL_VMIDMT_NO_ERROR)
804 return rc;
805 } else {
806 ctx_index = 0;
807 }
808
809 return configure_context(info, ctx_index, cfg);
810 }
811
812 enum hal_vmidmt_status
vmidmt_hal_config_ctx_ext(const struct hal_vmidmt_info * info,uint32_t smr_index,const uint32_t * stream_list,uint32_t stream_count,const struct hal_vmidmt_context_config * ctx)813 vmidmt_hal_config_ctx_ext(const struct hal_vmidmt_info *info,
814 uint32_t smr_index, const uint32_t *stream_list,
815 uint32_t stream_count,
816 const struct hal_vmidmt_context_config *ctx)
817 {
818 const uint32_t max_attr = (1U << VMIDMT_MEMATTR_MAX_BITS) - 1U;
819 uint32_t valid_range_mask = 0;
820 uint32_t id_or = 0;
821 uint32_t mask_or = 0;
822 uint8_t sid_bits = 0;
823 uint32_t smr_val = 0;
824 uint32_t rd_val = 0;
825 uint32_t i;
826
827 if (!info || !ctx)
828 return HAL_VMIDMT_INVALID_PARAM;
829
830 /* Simple case: single stream → reuse normal API */
831 if (stream_count == 1U)
832 return vmidmt_hal_config_ctx(info, smr_index, ctx);
833
834 if (smr_index >= info->dev_params.entry_count)
835 return HAL_VMIDMT_INVALID_PARAM;
836
837 if (ctx->p_bus_attrib && ctx->p_bus_attrib->mem_attr > max_attr)
838 return HAL_VMIDMT_INVALID_PARAM;
839
840 if (!info->dev_params.stream_match_support)
841 goto configure_ctx;
842
843 if (!stream_list || stream_count == 0U)
844 return HAL_VMIDMT_INVALID_PARAM;
845
846 sid_bits = info->dev_params.num_stream_id_bits;
847 if (sid_bits == 0U) {
848 valid_range_mask = 1U;
849 } else if (sid_bits >= 32U) {
850 valid_range_mask = UINT32_MAX;
851 } else {
852 valid_range_mask = (1U << sid_bits) - 1U;
853 }
854
855 for (i = 0; i < stream_count; i++) {
856 id_or |= stream_list[i];
857
858 if ((i + 1U) < stream_count)
859 mask_or |= (stream_list[i] ^ stream_list[i + 1U]);
860 }
861
862 if ((id_or | mask_or) & ~valid_range_mask)
863 return HAL_VMIDMT_INVALID_PARAM;
864
865 smr_val = (1UL << VMIDMT_SHFT(SMRn, VALID)) |
866 (mask_or << VMIDMT_SHFT(SMRn, MASK)) |
867 (id_or << VMIDMT_SHFT(SMRn, ID));
868
869 VMIDMT_OUTI(info->base_addr, SMRn, smr_index, smr_val);
870
871 rd_val = VMIDMT_INI(info->base_addr, SMRn, smr_index);
872
873 if (rd_val != smr_val)
874 return HAL_VMIDMT_READ_WRITE_MISMATCH;
875
876 configure_ctx:
877 return configure_context(info, smr_index, ctx);
878 }
879
vmidmt_hal_cfg_err(const struct hal_vmidmt_info * p,bool sec,hal_vmidmt_error_option_config err)880 enum hal_vmidmt_status vmidmt_hal_cfg_err(const struct hal_vmidmt_info *p,
881 bool sec,
882 hal_vmidmt_error_option_config err)
883 {
884 uint32_t val = 0;
885 uint32_t raw = 0;
886
887 if (err & ~ALL_ERROR_OPTIONS)
888 return HAL_VMIDMT_INVALID_PARAM;
889
890 if ((err & HAL_VMIDMT_ERROR_O_SMCFCFG_EN) &&
891 p->dev_params.stream_match_support)
892 val |= BIT(VMIDMT_SHFT(CR0, SMCFCFG));
893
894 if (err & HAL_VMIDMT_ERROR_O_USFCFG_EN)
895 val |= BIT(VMIDMT_SHFT(CR0, USFCFG));
896
897 if (err & HAL_VMIDMT_ERROR_O_GCFGFIE)
898 val |= BIT(VMIDMT_SHFT(CR0, GCFGFIE));
899
900 if (err & HAL_VMIDMT_ERROR_O_GCFGFRE)
901 val |= BIT(VMIDMT_SHFT(CR0, GCFGFRE));
902
903 if (err & HAL_VMIDMT_ERROR_O_GFIE)
904 val |= BIT(VMIDMT_SHFT(CR0, GFIE));
905
906 if (sec) {
907 VMIDMT_OUTM(p->base_addr, SCR0, CR0_ERE_MASK, val);
908 raw = VMIDMT_INM(p->base_addr, SCR0, CR0_ERE_MASK);
909 } else {
910 VMIDMT_OUTM(p->base_addr, NSCR0, CR0_ERE_MASK, val);
911 raw = VMIDMT_INM(p->base_addr, NSCR0, CR0_ERE_MASK);
912 }
913
914 if (raw != val)
915 return HAL_VMIDMT_READ_WRITE_MISMATCH;
916
917 return HAL_VMIDMT_NO_ERROR;
918 }
919
vmidmt_hal_is_error(const struct hal_vmidmt_info * p_vmidmt,bool sec)920 bool vmidmt_hal_is_error(const struct hal_vmidmt_info *p_vmidmt, bool sec)
921 {
922 if (sec)
923 return VMIDMT_IN(p_vmidmt->base_addr, SGFSR) != 0;
924
925 return VMIDMT_IN(p_vmidmt->base_addr, NSGFSR) != 0;
926 }
927
vmidmt_hal_get_error_sec(const struct hal_vmidmt_info * p,struct hal_vmidmt_error * err,uint32_t * sr,uint32_t * s0,uint32_t * s1,uint32_t * s2)928 static void vmidmt_hal_get_error_sec(const struct hal_vmidmt_info *p,
929 struct hal_vmidmt_error *err, uint32_t *sr,
930 uint32_t *s0, uint32_t *s1, uint32_t *s2)
931 {
932 *sr = VMIDMT_IN(p->base_addr, SGFSR);
933 err->u_physical_address_lower32 = VMIDMT_IN(p->base_addr, SGFAR0);
934
935 if (p->dev_params.input_addr_size)
936 err->u_physical_address_upper32 =
937 VMIDMT_IN(p->base_addr, SGFAR1);
938
939 *s0 = VMIDMT_IN(p->base_addr, SGFSYNDR0);
940 *s1 = VMIDMT_IN(p->base_addr, SGFSYNDR1);
941 *s2 = VMIDMT_IN(p->base_addr, SGFSYNDR2);
942 }
943
vmidmt_hal_get_error_nsec(const struct hal_vmidmt_info * p,struct hal_vmidmt_error * err,uint32_t * sr,uint32_t * s0,uint32_t * s1,uint32_t * s2)944 static void vmidmt_hal_get_error_nsec(const struct hal_vmidmt_info *p,
945 struct hal_vmidmt_error *err,
946 uint32_t *sr, uint32_t *s0, uint32_t *s1,
947 uint32_t *s2)
948 {
949 *sr = VMIDMT_IN(p->base_addr, NSGFSR);
950
951 err->u_physical_address_lower32 = VMIDMT_IN(p->base_addr, NSGFAR0);
952
953 if (p->dev_params.input_addr_size)
954 err->u_physical_address_upper32 =
955 VMIDMT_IN(p->base_addr, NSGFAR1);
956
957 *s0 = VMIDMT_IN(p->base_addr, NSGFSYNDR0);
958
959 *s1 = VMIDMT_IN(p->base_addr, NSGFSYNDR1);
960
961 *s2 = VMIDMT_IN(p->base_addr, NSGFSYNDR2);
962 }
963
vmidmt_hal_get_error(const struct hal_vmidmt_info * p,bool sec,struct hal_vmidmt_error * err)964 void vmidmt_hal_get_error(const struct hal_vmidmt_info *p, bool sec,
965 struct hal_vmidmt_error *err)
966 {
967 uint32_t s0, s1, s2, sr;
968
969 if (!err)
970 return;
971
972 memset(err, 0, sizeof(*err));
973
974 if (sec) {
975 vmidmt_hal_get_error_sec(p, err, &sr, &s0, &s1, &s2);
976 } else {
977 vmidmt_hal_get_error_nsec(p, err, &sr, &s0, &s1, &s2);
978 }
979
980 if (sr & VMIDMT_FMSK(GFSR, CLMULTI))
981 err->u_error_flags |= HAL_VMIDMT_ERROR_F_CLMULTI;
982
983 if (sr & VMIDMT_FMSK(GFSR, CFGMULTI))
984 err->u_error_flags |= HAL_VMIDMT_ERROR_F_CFGMULTI;
985
986 if (sr & VMIDMT_FMSK(GFSR, PF))
987 err->u_error_flags |= HAL_VMIDMT_ERROR_F_PF;
988
989 if (sr & VMIDMT_FMSK(GFSR, CAF))
990 err->u_error_flags |= HAL_VMIDMT_ERROR_F_CAF;
991
992 if (sr & VMIDMT_FMSK(GFSR, SMCF))
993 err->u_error_flags |= HAL_VMIDMT_ERROR_F_SMCF;
994
995 if (sr & VMIDMT_FMSK(GFSR, USF))
996 err->u_error_flags |= HAL_VMIDMT_ERROR_F_USF;
997
998 if (s0 & VMIDMT_FMSK(GFSYNDR0, NSATTR))
999 err->u_bus_flags |= HAL_VMIDMT_BUS_F_ERROR_NSATTR;
1000
1001 if (s0 & VMIDMT_FMSK(GFSYNDR0, NSSTATE))
1002 err->u_bus_flags |= HAL_VMIDMT_BUS_F_ERROR_NSSTATE;
1003
1004 if (s0 & VMIDMT_FMSK(GFSYNDR0, WNR))
1005 err->u_bus_flags |= HAL_VMIDMT_BUS_F_ERROR_WNR;
1006
1007 err->u_ssd_index = VMIDMT_INFC(s1, GFSYNDR1, SSD_INDEX);
1008
1009 err->u_master_id = VMIDMT_INFC(s2, GFSYNDR2, AMID);
1010
1011 err->u_avmid = VMIDMT_INFC(s2, GFSYNDR2, AVMID);
1012
1013 err->u_atid = VMIDMT_INFC(s2, GFSYNDR2, ATID);
1014
1015 err->u_abid = VMIDMT_INFC(s2, GFSYNDR2, ABID);
1016
1017 err->u_apid = VMIDMT_INFC(s2, GFSYNDR2, APID);
1018
1019 err->u_sid = VMIDMT_INFC(s1, GFSYNDR1, SID);
1020 }
1021
vmidmt_hal_clear_error(const struct hal_vmidmt_info * p,bool sec)1022 enum hal_vmidmt_status vmidmt_hal_clear_error(const struct hal_vmidmt_info *p,
1023 bool sec)
1024 {
1025 uint32_t read_back = 0;
1026
1027 if (sec) {
1028 VMIDMT_OUT(p->base_addr, SGFSRRESTORE, 0);
1029
1030 read_back = VMIDMT_IN(p->base_addr, SGFSRRESTORE);
1031 } else {
1032 VMIDMT_OUT(p->base_addr, NSGFSRRESTORE, 0);
1033
1034 read_back = VMIDMT_IN(p->base_addr, NSGFSRRESTORE);
1035 }
1036
1037 return read_back ? HAL_VMIDMT_READ_WRITE_MISMATCH : HAL_VMIDMT_NO_ERROR;
1038 }
1039