xref: /rk3399_ARM-atf/drivers/qti/accesscontrol/vmidmt/vmidmt_hal.c (revision 5de3e03dbd7c2da6748e294f423c83f9582f459c)
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