1 /*
2 * Copyright 2019-2020 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_xrdc2.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.xrdc2"
17 #endif
18
19 /* Definitions for access policy. */
20 #define XRDC2_DXACP_WIDTH (3U)
21 #define XRDC2_DXACP_MASK ((1UL << XRDC2_DXACP_WIDTH) - 1U)
22
23 #define XRDC2_DXACP_0_7(domainId, dxacp) ((uint32_t)(dxacp) << (XRDC2_DXACP_WIDTH * (uint32_t)(domainId)))
24 #define XRDC2_DXACP_8_15(domainId, dxacp) ((uint32_t)(dxacp) << (XRDC2_DXACP_WIDTH * ((uint32_t)(domainId)-8U)))
25
26 #define XRDC2_DXACP_0_7_MASK(domainId) XRDC2_DXACP_0_7(domainId, XRDC2_DXACP_MASK)
27 #define XRDC2_DXACP_8_15_MASK(domainId) XRDC2_DXACP_8_15(domainId, XRDC2_DXACP_MASK)
28
29 /* Memory region alignment. */
30 #define XRDC2_MRGD_ADDR_ALIGN_MASK (0x00000FFFU)
31
32 /*******************************************************************************
33 * Prototypes
34 ******************************************************************************/
35 static void XRDC2_MakeDXACP(const xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT],
36 uint32_t *w0,
37 uint32_t *w1);
38
39 /*******************************************************************************
40 * Variables
41 ******************************************************************************/
42
43 /*******************************************************************************
44 * Code
45 ******************************************************************************/
46
XRDC2_MakeDXACP(const xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT],uint32_t * w0,uint32_t * w1)47 static void XRDC2_MakeDXACP(const xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT],
48 uint32_t *w0,
49 uint32_t *w1)
50 {
51 uint32_t domain = (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT;
52
53 *w0 = 0U;
54 *w1 = 0U;
55
56 #if (FSL_FEATURE_XRDC2_DOMAIN_COUNT > 8)
57 while (domain > 8U)
58 {
59 domain--;
60 *w0 <<= XRDC2_DXACP_WIDTH;
61 *w0 |= (uint32_t)policy[domain - 8U];
62 }
63 #endif
64
65 while (domain > 0U)
66 {
67 domain--;
68 *w1 <<= XRDC2_DXACP_WIDTH;
69 *w1 |= (uint32_t)policy[domain];
70 }
71 }
72
73 /*!
74 * brief Initializes the XRDC2 module.
75 *
76 * This function enables the XRDC2 clock.
77 *
78 * param base XRDC2 peripheral base address.
79 */
XRDC2_Init(XRDC2_Type * base)80 void XRDC2_Init(XRDC2_Type *base)
81 {
82 }
83
84 /*!
85 * brief De-initializes the XRDC2 module.
86 *
87 * This function disables the XRDC2 clock.
88 *
89 * param base XRDC2 peripheral base address.
90 */
XRDC2_Deinit(XRDC2_Type * base)91 void XRDC2_Deinit(XRDC2_Type *base)
92 {
93 }
94
95 /*!
96 * brief Sets the XRDC2 global valid.
97 *
98 * This function sets the XRDC2 global valid or invalid. When the XRDC2 is global
99 * invalid, all accesses from all bus masters to all slaves are allowed.
100 *
101 * param base XRDC2 peripheral base address.
102 * param valid True to valid XRDC2.
103 */
XRDC2_SetGlobalValid(XRDC2_Type * base,bool valid)104 void XRDC2_SetGlobalValid(XRDC2_Type *base, bool valid)
105 {
106 uint32_t mcr = base->MCR & ~(XRDC2_MCR_GVLDM_MASK | XRDC2_MCR_GVLDC_MASK);
107
108 if (valid)
109 {
110 mcr |= XRDC2_MCR_GVLDM_MASK;
111 base->MCR = mcr;
112
113 /* Two dummy read to ensure the configuration takes effect. */
114 (void)base->MCR;
115 (void)base->MCR;
116
117 mcr |= XRDC2_MCR_GVLDC_MASK;
118 base->MCR = mcr;
119 }
120 else
121 {
122 base->MCR = mcr;
123 }
124 }
125
126 /*!
127 * brief Gets the default master domain assignment.
128 *
129 * This function sets the assignment as follows:
130 *
131 * code
132 * config->lock = false;
133 * config->privilegeAttr = kXRDC2_MasterPrivilege;
134 * config->secureAttr = kXRDC2_MasterSecure;
135 * config->domainId = 0U;
136 * config->mask = 0U;
137 * config->match = 0U;
138 * endcode
139 *
140 * param assignment Pointer to the assignment structure.
141 */
XRDC2_GetDefaultMasterDomainAssignment(xrdc2_master_domain_assignment_t * assignment)142 void XRDC2_GetDefaultMasterDomainAssignment(xrdc2_master_domain_assignment_t *assignment)
143 {
144 assert(NULL != assignment);
145
146 assignment->lock = false;
147 assignment->privilegeAttr = kXRDC2_MasterPrivilege;
148 assignment->secureAttr = kXRDC2_MasterSecure;
149 assignment->domainId = 0U;
150 assignment->mask = 0U;
151 assignment->match = 0U;
152 }
153
154 /*!
155 * brief Sets the processor bus master domain assignment.
156 *
157 * param base XRDC2 peripheral base address.
158 * param master Which master to configure.
159 * param assignIndex Which assignment register to set.
160 * param assignment Pointer to the assignment structure.
161 */
XRDC2_SetMasterDomainAssignment(XRDC2_Type * base,xrdc2_master_t master,uint8_t assignIndex,const xrdc2_master_domain_assignment_t * assignment)162 void XRDC2_SetMasterDomainAssignment(XRDC2_Type *base,
163 xrdc2_master_t master,
164 uint8_t assignIndex,
165 const xrdc2_master_domain_assignment_t *assignment)
166 {
167 assert(NULL != assignment);
168 uint32_t w0;
169 uint32_t w1;
170
171 w0 = (((uint32_t)assignment->mask << XRDC2_MDAC_MDA_W0_MASK_SHIFT) |
172 ((uint32_t)assignment->match << XRDC2_MDAC_MDA_W0_MATCH_SHIFT));
173
174 w1 = ((uint32_t)assignment->domainId << XRDC2_MDAC_MDA_W1_DID_SHIFT) |
175 (XRDC2_MDAC_MDA_W1_PA(assignment->privilegeAttr)) | (XRDC2_MDAC_MDA_W1_SA(assignment->secureAttr)) |
176 XRDC2_MDAC_MDA_W1_VLD_MASK;
177
178 if (assignment->lock)
179 {
180 w1 |= XRDC2_MDAC_MDA_W1_DL_MASK;
181 }
182
183 base->MDACI_MDAJ[master][assignIndex].MDAC_MDA_W0 = w0;
184 base->MDACI_MDAJ[master][assignIndex].MDAC_MDA_W1 = w1;
185 }
186
187 /*!
188 * brief Gets the default memory slot access configuration.
189 *
190 * This function sets the assignment as follows:
191 *
192 * code
193 * config->lockMode = kXRDC2_AccessConfigLockDisabled;
194 * config->policy[0] = kXRDC2_AccessPolicyNone;
195 * config->policy[1] = kXRDC2_AccessPolicyNone;
196 * ...
197 * endcode
198 *
199 * param config Pointer to the configuration.
200 */
XRDC2_GetMemSlotAccessDefaultConfig(xrdc2_mem_slot_access_config_t * config)201 void XRDC2_GetMemSlotAccessDefaultConfig(xrdc2_mem_slot_access_config_t *config)
202 {
203 assert(NULL != config);
204
205 uint8_t domain;
206
207 config->lockMode = kXRDC2_AccessConfigLockDisabled;
208
209 for (domain = 0; domain < (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT; domain++)
210 {
211 config->policy[domain] = kXRDC2_AccessPolicyNone;
212 }
213 }
214
215 /*!
216 * brief Sets the memory slot access policy.
217 *
218 * param base XRDC2 peripheral base address.
219 * param config Pointer to the access policy configuration structure.
220 */
XRDC2_SetMemSlotAccessConfig(XRDC2_Type * base,xrdc2_mem_slot_t memSlot,const xrdc2_mem_slot_access_config_t * config)221 void XRDC2_SetMemSlotAccessConfig(XRDC2_Type *base,
222 xrdc2_mem_slot_t memSlot,
223 const xrdc2_mem_slot_access_config_t *config)
224 {
225 assert(NULL != config);
226
227 uint32_t w0 = 0;
228 uint32_t w1 = 0;
229
230 XRDC2_MakeDXACP(config->policy, &w0, &w1);
231
232 w1 |= XRDC2_MSC_MSAC_W1_DL2(config->lockMode);
233 w1 |= XRDC2_MSC_MSAC_W1_VLD_MASK;
234
235 base->MSCI_MSAC_WK[(uint8_t)memSlot].MSC_MSAC_W0 = w0;
236 base->MSCI_MSAC_WK[(uint8_t)memSlot].MSC_MSAC_W1 = w1;
237 }
238
239 /*!
240 * brief Sets the memory slot descriptor as valid or invalid.
241 *
242 * param base XRDC2 peripheral base address.
243 * param memSlot Which memory slot descriptor to set.
244 * param valid True to set valid, false to set invalid.
245 */
XRDC2_SetMemSlotAccessValid(XRDC2_Type * base,xrdc2_mem_slot_t memSlot,bool valid)246 void XRDC2_SetMemSlotAccessValid(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, bool valid)
247 {
248 uint32_t reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 & ~XRDC2_EAL_MASK;
249
250 if (valid)
251 {
252 base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = (reg | XRDC2_MSC_MSAC_W1_VLD_MASK);
253 }
254 else
255 {
256 base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = (reg & ~XRDC2_MSC_MSAC_W1_VLD_MASK);
257 }
258 }
259
260 /*!
261 * brief Sets the memory slot descriptor lock mode.
262 *
263 * param base XRDC2 peripheral base address.
264 * param memSlot Which memory slot descriptor to set.
265 * param lockMode The lock mode to set.
266 */
XRDC2_SetMemSlotAccessLockMode(XRDC2_Type * base,xrdc2_mem_slot_t memSlot,xrdc2_access_config_lock_t lockMode)267 void XRDC2_SetMemSlotAccessLockMode(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, xrdc2_access_config_lock_t lockMode)
268 {
269 uint32_t reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 & ~(XRDC2_EAL_MASK | XRDC2_MRC_MRGD_W6_DL2_MASK);
270
271 base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = (reg | XRDC2_MRC_MRGD_W6_DL2(lockMode));
272 }
273
274 /*!
275 * brief Sets the memory slot access policy for specific domain.
276 *
277 * param base XRDC2 peripheral base address.
278 * param memSlot The memory slot to operate.
279 * param domainId The ID of the domain whose policy will be changed.
280 * param policy The access policy to set.
281 */
XRDC2_SetMemSlotDomainAccessPolicy(XRDC2_Type * base,xrdc2_mem_slot_t memSlot,uint8_t domainId,xrdc2_access_policy_t policy)282 void XRDC2_SetMemSlotDomainAccessPolicy(XRDC2_Type *base,
283 xrdc2_mem_slot_t memSlot,
284 uint8_t domainId,
285 xrdc2_access_policy_t policy)
286 {
287 uint32_t reg;
288
289 if (domainId < 8U)
290 {
291 reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W0 & ~XRDC2_DXACP_0_7_MASK(domainId);
292 reg |= XRDC2_DXACP_0_7(domainId, policy);
293 base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W0 = reg;
294 }
295 else
296 {
297 reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 & ~XRDC2_DXACP_8_15_MASK(domainId);
298 reg |= XRDC2_DXACP_8_15(domainId, policy);
299 reg &= ~XRDC2_EAL_MASK;
300 base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = reg;
301 }
302 }
303
304 /*!
305 * brief Enable or disable the memory slot exclusive access lock.
306 *
307 * The lock must be enabled first before use. Once disabled, it could not be
308 * enabled until reset.
309 *
310 * param base XRDC2 peripheral base address.
311 * param memSlot The memory slot to operate.
312 * param enable True to enable, false to disable.
313 */
XRDC2_EnableMemSlotExclAccessLock(XRDC2_Type * base,xrdc2_mem_slot_t memSlot,bool enable)314 void XRDC2_EnableMemSlotExclAccessLock(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, bool enable)
315 {
316 if (enable)
317 {
318 base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = XRDC2_EAL_UNLOCKED;
319 }
320 else
321 {
322 base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = XRDC2_EAL_DISABLE_UNTIL_RESET;
323 }
324 }
325
326 /*!
327 * @brief Get current memory slot exclusive access lock owner.
328 *
329 * @param base XRDC2 peripheral base address.
330 * @param memSlot The memory slot to operate.
331 * @return The domain ID of the lock owner.
332 */
XRDC2_GetMemSlotExclAccessLockDomainOwner(XRDC2_Type * base,xrdc2_mem_slot_t memSlot)333 uint8_t XRDC2_GetMemSlotExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
334 {
335 return (uint8_t)((base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W0 & XRDC2_MSC_MSAC_W0_EALO_MASK) >>
336 XRDC2_MSC_MSAC_W0_EALO_SHIFT);
337 }
338
339 /*!
340 * brief Try to lock the memory slot exclusive access.
341 *
342 * param base XRDC2 peripheral base address.
343 * param memSlot The memory slot to operate.
344 * retval kStatus_Fail Failed to lock.
345 * retval kStatus_Success Locked succussfully.
346 */
XRDC2_TryLockMemSlotExclAccess(XRDC2_Type * base,xrdc2_mem_slot_t memSlot)347 status_t XRDC2_TryLockMemSlotExclAccess(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
348 {
349 status_t status;
350 uint8_t curDomainID;
351 volatile uint32_t *lockReg = &(base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1);
352
353 curDomainID = XRDC2_GetCurrentMasterDomainId(base);
354
355 *lockReg = XRDC2_EAL_LOCKED;
356
357 if (curDomainID != XRDC2_GetMemSlotExclAccessLockDomainOwner(base, memSlot))
358 {
359 status = kStatus_Fail;
360 }
361 else
362 {
363 status = kStatus_Success;
364 }
365
366 return status;
367 }
368
369 /*!
370 * brief Lock the memory slot exclusive access using blocking method.
371 *
372 * param base XRDC2 peripheral base address.
373 * param memSlot The memory slot to operate.
374 *
375 * note This function must be called when the lock is not disabled.
376 */
XRDC2_LockMemSlotExclAccess(XRDC2_Type * base,xrdc2_mem_slot_t memSlot)377 void XRDC2_LockMemSlotExclAccess(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
378 {
379 uint8_t curDomainID;
380 volatile uint32_t *lockReg = &(base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1);
381
382 curDomainID = XRDC2_GetCurrentMasterDomainId(base);
383
384 while (true)
385 {
386 *lockReg = XRDC2_EAL_LOCKED;
387
388 /* Locked and owner is current domain. */
389 if (curDomainID == XRDC2_GetMemSlotExclAccessLockDomainOwner(base, memSlot))
390 {
391 break;
392 }
393 }
394
395 return;
396 }
397
398 /*!
399 * brief Gets the default memory access configuration.
400 *
401 * This function sets the assignment as follows:
402 *
403 * code
404 * config->startAddr = 0U;
405 * config->endAddr = 0xFFFFFFFFU;
406 * config->lockMode = kXRDC2_AccessConfigLockDisabled;
407 * config->policy[0] = kXRDC2_AccessPolicyNone;
408 * config->policy[1] = kXRDC2_AccessPolicyNone;
409 * ...
410 * endcode
411 *
412 * param config Pointer to the configuration.
413 */
XRDC2_GetMemAccessDefaultConfig(xrdc2_mem_access_config_t * config)414 void XRDC2_GetMemAccessDefaultConfig(xrdc2_mem_access_config_t *config)
415 {
416 assert(NULL != config);
417
418 uint8_t domain;
419
420 config->startAddr = 0U;
421 config->endAddr = 0xFFFFFFFFU;
422 config->lockMode = kXRDC2_AccessConfigLockDisabled;
423
424 for (domain = 0; domain < (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT; domain++)
425 {
426 config->policy[domain] = kXRDC2_AccessPolicyNone;
427 }
428 }
429
430 /*!
431 * brief Sets the memory region access policy.
432 *
433 * param base XRDC2 peripheral base address.
434 * param config Pointer to the access policy configuration structure.
435 */
XRDC2_SetMemAccessConfig(XRDC2_Type * base,xrdc2_mem_t mem,const xrdc2_mem_access_config_t * config)436 void XRDC2_SetMemAccessConfig(XRDC2_Type *base, xrdc2_mem_t mem, const xrdc2_mem_access_config_t *config)
437 {
438 assert(NULL != config);
439 /* Check the memory region alignment. */
440 assert((config->startAddr & XRDC2_MRGD_ADDR_ALIGN_MASK) == 0U);
441 assert(((config->endAddr + 1U) & XRDC2_MRGD_ADDR_ALIGN_MASK) == 0U);
442
443 uint32_t w5 = 0;
444 uint32_t w6 = 0;
445
446 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
447 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
448
449 XRDC2_MakeDXACP(config->policy, &w5, &w6);
450
451 w6 |= XRDC2_MRC_MRGD_W6_DL2(config->lockMode);
452 w6 |= XRDC2_MRC_MRGD_W6_VLD_MASK;
453
454 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W0 = config->startAddr;
455 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W1 = 0U;
456 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W2 = config->endAddr;
457 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W3 = 0U;
458 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 = w5;
459 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = w6;
460 }
461
462 /*!
463 * brief Sets the memory region descriptor as valid or invalid.
464 *
465 * param base XRDC2 peripheral base address.
466 * param mem Which memory region descriptor to set.
467 * param valid True to set valid, false to set invalid.
468 */
XRDC2_SetMemAccessValid(XRDC2_Type * base,xrdc2_mem_t mem,bool valid)469 void XRDC2_SetMemAccessValid(XRDC2_Type *base, xrdc2_mem_t mem, bool valid)
470 {
471 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
472 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
473 uint32_t reg = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 & ~XRDC2_EAL_MASK;
474
475 if (valid)
476 {
477 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = (reg | XRDC2_MRC_MRGD_W6_VLD_MASK);
478 }
479 else
480 {
481 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = (reg & ~XRDC2_MRC_MRGD_W6_VLD_MASK);
482 }
483 }
484
485 /*!
486 * brief Sets the memory descriptor lock mode.
487 *
488 * param base XRDC2 peripheral base address.
489 * param mem Which memory descriptor to set.
490 * param lockMode The lock mode to set.
491 */
XRDC2_SetMemAccessLockMode(XRDC2_Type * base,xrdc2_mem_t mem,xrdc2_access_config_lock_t lockMode)492 void XRDC2_SetMemAccessLockMode(XRDC2_Type *base, xrdc2_mem_t mem, xrdc2_access_config_lock_t lockMode)
493 {
494 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
495 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
496 uint32_t reg = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 & ~(XRDC2_EAL_MASK | XRDC2_MRC_MRGD_W6_DL2_MASK);
497
498 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = (reg | XRDC2_MRC_MRGD_W6_DL2(lockMode));
499 }
500
501 /*!
502 * brief Sets the memory region access policy for specific domain.
503 *
504 * param base XRDC2 peripheral base address.
505 * param mem The memory region to operate.
506 * param domainId The ID of the domain whose policy will be changed.
507 * param policy The access policy to set.
508 */
XRDC2_SetMemDomainAccessPolicy(XRDC2_Type * base,xrdc2_mem_t mem,uint8_t domainId,xrdc2_access_policy_t policy)509 void XRDC2_SetMemDomainAccessPolicy(XRDC2_Type *base, xrdc2_mem_t mem, uint8_t domainId, xrdc2_access_policy_t policy)
510 {
511 uint32_t reg;
512 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
513 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
514
515 if (domainId < 8U)
516 {
517 reg = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 & ~XRDC2_DXACP_0_7_MASK(domainId);
518 reg |= XRDC2_DXACP_0_7(domainId, policy);
519 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 = reg;
520 }
521 else
522 {
523 reg = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 & ~XRDC2_DXACP_8_15_MASK(domainId);
524 reg |= XRDC2_DXACP_8_15(domainId, policy);
525 reg &= ~XRDC2_EAL_MASK;
526 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = reg;
527 }
528 }
529
530 /*!
531 * brief Disable the memory region exclusive access lock.
532 *
533 * Once disabled, it could not be enabled until reset.
534 *
535 * param base XRDC2 peripheral base address.
536 * param mem The memory region to operate.
537 */
XRDC2_EnableMemExclAccessLock(XRDC2_Type * base,xrdc2_mem_t mem,bool enable)538 void XRDC2_EnableMemExclAccessLock(XRDC2_Type *base, xrdc2_mem_t mem, bool enable)
539 {
540 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
541 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
542
543 if (enable)
544 {
545 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_UNLOCKED;
546 }
547 else
548 {
549 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_DISABLE_UNTIL_RESET;
550 }
551 }
552
553 /*!
554 * brief Get current memory region exclusive access lock owner.
555 *
556 * param base XRDC2 peripheral base address.
557 * param mem The memory region to operate.
558 * param The domain ID of the lock owner.
559 */
XRDC2_GetMemExclAccessLockDomainOwner(XRDC2_Type * base,xrdc2_mem_t mem)560 uint8_t XRDC2_GetMemExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_mem_t mem)
561 {
562 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
563 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
564
565 return (uint8_t)((base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 & XRDC2_MRC_MRGD_W5_EALO_MASK) >>
566 XRDC2_MRC_MRGD_W5_EALO_SHIFT);
567 }
568
569 /*!
570 * brief Try to lock the memory region exclusive access.
571 *
572 * param base XRDC2 peripheral base address.
573 * param mem The memory region to operate.
574 * retval kStatus_Fail Failed to lock.
575 * retval kStatus_Success Locked succussfully.
576 */
XRDC2_TryLockMemExclAccess(XRDC2_Type * base,xrdc2_mem_t mem)577 status_t XRDC2_TryLockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem)
578 {
579 status_t status;
580 uint8_t curDomainID;
581 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
582 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
583 volatile uint32_t *lockReg = &(base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6);
584
585 curDomainID = XRDC2_GetCurrentMasterDomainId(base);
586
587 *lockReg = XRDC2_EAL_LOCKED;
588
589 if (curDomainID != XRDC2_GetMemExclAccessLockDomainOwner(base, mem))
590 {
591 status = kStatus_Fail;
592 }
593 else
594 {
595 status = kStatus_Success;
596 }
597
598 return status;
599 }
600
601 /*!
602 * brief Lock the memory region exclusive access using blocking method.
603 *
604 * param base XRDC2 peripheral base address.
605 * param mem The memory region to operate.
606 *
607 * note This function must be called when the lock is not disabled.
608 */
XRDC2_LockMemExclAccess(XRDC2_Type * base,xrdc2_mem_t mem)609 void XRDC2_LockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem)
610 {
611 uint8_t curDomainID;
612 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
613 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
614 volatile uint32_t *lockReg = &(base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6);
615
616 curDomainID = XRDC2_GetCurrentMasterDomainId(base);
617
618 while (true)
619 {
620 *lockReg = XRDC2_EAL_LOCKED;
621
622 /* Locked and owner is current domain. */
623 if (curDomainID == XRDC2_GetMemExclAccessLockDomainOwner(base, mem))
624 {
625 break;
626 }
627 }
628
629 return;
630 }
631
632 /*!
633 * brief Unlock the memory region exclusive access.
634 *
635 * param base XRDC2 peripheral base address.
636 * param mem The memory region to operate.
637 *
638 * note This function must be called by the lock owner.
639 */
XRDC2_UnlockMemExclAccess(XRDC2_Type * base,xrdc2_mem_t mem)640 void XRDC2_UnlockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem)
641 {
642 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
643 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
644
645 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_UNLOCKED;
646 }
647
648 /*!
649 * brief Force the memory region exclusive access lock release.
650 *
651 * The master does not own the lock could call this function to force release the lock.
652 *
653 * param base XRDC2 peripheral base address.
654 * param mem The memory region to operate.
655 */
XRDC2_ForceMemExclAccessLockRelease(XRDC2_Type * base,xrdc2_mem_t mem)656 void XRDC2_ForceMemExclAccessLockRelease(XRDC2_Type *base, xrdc2_mem_t mem)
657 {
658 uint32_t mrc = XRDC2_GET_MRC((uint32_t)mem);
659 uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
660
661 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_FORCE_RELEASE_MAGIC_0;
662 base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_FORCE_RELEASE_MAGIC_1;
663 }
664
665 /*!
666 * brief Gets the default peripheral access configuration.
667 *
668 * The default configuration is set as follows:
669 * code
670 * config->lockMode = kXRDC2_AccessConfigLockWritable;
671 * config->policy[0] = kXRDC2_AccessPolicyNone;
672 * config->policy[1] = kXRDC2_AccessPolicyNone;
673 * ...
674 * config->policy[15] = kXRDC2_AccessPolicyNone;
675 * endcode
676 *
677 * param config Pointer to the configuration structure.
678 */
XRDC2_GetPeriphAccessDefaultConfig(xrdc2_periph_access_config_t * config)679 void XRDC2_GetPeriphAccessDefaultConfig(xrdc2_periph_access_config_t *config)
680 {
681 assert(NULL != config);
682
683 uint8_t domain;
684
685 config->lockMode = kXRDC2_AccessConfigLockDisabled;
686
687 for (domain = 0; domain < (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT; domain++)
688 {
689 config->policy[domain] = kXRDC2_AccessPolicyNone;
690 }
691 }
692
693 /*!
694 * brief Sets the peripheral access policy.
695 *
696 * param base XRDC2 peripheral base address.
697 * param config Pointer to the access policy configuration structure.
698 */
XRDC2_SetPeriphAccessConfig(XRDC2_Type * base,xrdc2_periph_t periph,const xrdc2_periph_access_config_t * config)699 void XRDC2_SetPeriphAccessConfig(XRDC2_Type *base, xrdc2_periph_t periph, const xrdc2_periph_access_config_t *config)
700 {
701 assert(NULL != config);
702
703 uint32_t w0 = 0;
704 uint32_t w1 = 0;
705
706 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
707 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
708
709 XRDC2_MakeDXACP(config->policy, &w0, &w1);
710
711 w1 |= XRDC2_PAC_PDAC_W1_DL2(config->lockMode);
712 w1 |= XRDC2_PAC_PDAC_W1_VLD_MASK;
713
714 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 = w0;
715 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = w1;
716 }
717
718 /*!
719 * brief Sets the peripheral descriptor as valid or invalid.
720 *
721 * param base XRDC2 peripheral base address.
722 * param periph Which peripheral descriptor to set.
723 * param valid True to set valid, false to set invalid.
724 */
XRDC2_SetPeriphAccessValid(XRDC2_Type * base,xrdc2_periph_t periph,bool valid)725 void XRDC2_SetPeriphAccessValid(XRDC2_Type *base, xrdc2_periph_t periph, bool valid)
726 {
727 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
728 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
729 uint32_t reg = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 & ~XRDC2_EAL_MASK;
730
731 if (valid)
732 {
733 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = (reg | XRDC2_PAC_PDAC_W1_VLD_MASK);
734 }
735 else
736 {
737 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = (reg & ~XRDC2_PAC_PDAC_W1_VLD_MASK);
738 }
739 }
740
741 /*!
742 * brief Sets the peripheral descriptor lock mode.
743 *
744 * param base XRDC2 peripheral base address.
745 * param periph Which peripheral descriptor to set.
746 * param lockMode The lock mode to set.
747 */
XRDC2_SetPeriphAccessLockMode(XRDC2_Type * base,xrdc2_periph_t periph,xrdc2_access_config_lock_t lockMode)748 void XRDC2_SetPeriphAccessLockMode(XRDC2_Type *base, xrdc2_periph_t periph, xrdc2_access_config_lock_t lockMode)
749 {
750 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
751 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
752 uint32_t reg = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 & ~(XRDC2_EAL_MASK | XRDC2_PAC_PDAC_W1_DL2_MASK);
753
754 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = (reg | XRDC2_PAC_PDAC_W1_DL2(lockMode));
755 }
756
757 /*!
758 * brief Sets the peripheral access policy for specific domain.
759 *
760 * param base XRDC2 peripheral base address.
761 * param periph The peripheral to operate.
762 * param domainId The ID of the domain whose policy will be changed.
763 * param policy The access policy to set.
764 */
XRDC2_SetPeriphDomainAccessPolicy(XRDC2_Type * base,xrdc2_periph_t periph,uint8_t domainId,xrdc2_access_policy_t policy)765 void XRDC2_SetPeriphDomainAccessPolicy(XRDC2_Type *base,
766 xrdc2_periph_t periph,
767 uint8_t domainId,
768 xrdc2_access_policy_t policy)
769 {
770 uint32_t reg;
771 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
772 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
773
774 if (domainId < 8U)
775 {
776 reg = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 & ~XRDC2_DXACP_0_7_MASK(domainId);
777 reg |= XRDC2_DXACP_0_7(domainId, policy);
778 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 = reg;
779 }
780 else
781 {
782 reg = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 & ~XRDC2_DXACP_8_15_MASK(domainId);
783 reg |= XRDC2_DXACP_8_15(domainId, policy);
784 reg &= ~XRDC2_EAL_MASK;
785 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = reg;
786 }
787 }
788
789 /*!
790 * brief Get current peripheral exclusive access lock owner.
791 *
792 * param base XRDC2 peripheral base address.
793 * param periph The peripheral to operate.
794 * param The domain ID of the lock owner.
795 */
XRDC2_GetPeriphExclAccessLockDomainOwner(XRDC2_Type * base,xrdc2_periph_t periph)796 uint8_t XRDC2_GetPeriphExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_periph_t periph)
797 {
798 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
799 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
800
801 return (uint8_t)((base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 & XRDC2_PAC_PDAC_W0_EALO_MASK) >>
802 XRDC2_PAC_PDAC_W0_EALO_SHIFT);
803 }
804
805 /*!
806 * brief Disable the peripheral exclusive access lock.
807 *
808 * Once disabled, it could not be enabled until reset.
809 *
810 * param base XRDC2 peripheral base address.
811 * param periph The peripheral to operate.
812 * param enable True to enable, false to disable.
813 */
XRDC2_EnablePeriphExclAccessLock(XRDC2_Type * base,xrdc2_periph_t periph,bool enable)814 void XRDC2_EnablePeriphExclAccessLock(XRDC2_Type *base, xrdc2_periph_t periph, bool enable)
815 {
816 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
817 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
818
819 if (enable)
820 {
821 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_UNLOCKED;
822 }
823 else
824 {
825 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_DISABLE_UNTIL_RESET;
826 }
827 }
828
829 /*!
830 * brief Try to lock the peripheral exclusive access.
831 *
832 * param base XRDC2 peripheral base address.
833 * param periph The peripheral to operate.
834 * retval kStatus_Fail Failed to lock.
835 * retval kStatus_Success Locked succussfully.
836 */
XRDC2_TryLockPeriphExclAccess(XRDC2_Type * base,xrdc2_periph_t periph)837 status_t XRDC2_TryLockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph)
838 {
839 status_t status;
840 uint8_t curDomainID;
841 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
842 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
843
844 volatile uint32_t *lockReg = &(base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1);
845
846 curDomainID = XRDC2_GetCurrentMasterDomainId(base);
847
848 *lockReg = XRDC2_EAL_LOCKED;
849
850 if (curDomainID != XRDC2_GetPeriphExclAccessLockDomainOwner(base, periph))
851 {
852 status = kStatus_Fail;
853 }
854 else
855 {
856 status = kStatus_Success;
857 }
858
859 return status;
860 }
861
862 /*!
863 * brief Lock the peripheral exclusive access using blocking method.
864 *
865 * param base XRDC2 peripheral base address.
866 * param periph The peripheral to operate.
867 *
868 * note This function must be called when the lock is not disabled.
869 */
XRDC2_LockPeriphExclAccess(XRDC2_Type * base,xrdc2_periph_t periph)870 void XRDC2_LockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph)
871 {
872 uint8_t curDomainID;
873 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
874 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
875
876 volatile uint32_t *lockReg = &(base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1);
877
878 curDomainID = XRDC2_GetCurrentMasterDomainId(base);
879
880 while (true)
881 {
882 *lockReg = XRDC2_EAL_LOCKED;
883
884 /* Locked and owner is current domain. */
885 if (curDomainID == XRDC2_GetPeriphExclAccessLockDomainOwner(base, periph))
886 {
887 break;
888 }
889 }
890
891 return;
892 }
893
894 /*!
895 * brief Unlock the peripheral exclusive access.
896 *
897 * param base XRDC2 peripheral base address.
898 * param periph The peripheral to operate.
899 *
900 * note This function must be called by the lock owner.
901 */
XRDC2_UnlockPeriphExclAccess(XRDC2_Type * base,xrdc2_periph_t periph)902 void XRDC2_UnlockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph)
903 {
904 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
905 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
906
907 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_UNLOCKED;
908 }
909
910 /*!
911 * brief Force the peripheral exclusive access lock release.
912 *
913 * The master does not own the lock could call this function to force release the lock.
914 *
915 * param base XRDC2 peripheral base address.
916 * param periph The peripheral to operate.
917 */
XRDC2_ForcePeriphExclAccessLockRelease(XRDC2_Type * base,xrdc2_periph_t periph)918 void XRDC2_ForcePeriphExclAccessLockRelease(XRDC2_Type *base, xrdc2_periph_t periph)
919 {
920 uint32_t pac = XRDC2_GET_PAC((uint32_t)periph);
921 uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
922
923 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_FORCE_RELEASE_MAGIC_0;
924 base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_FORCE_RELEASE_MAGIC_1;
925 }
926