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