Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:02

0001 /*
0002  * Copyright 2019-2020 NXP
0003  * All rights reserved.
0004  *
0005  * SPDX-License-Identifier: BSD-3-Clause
0006  */
0007 
0008 #include "fsl_xrdc2.h"
0009 
0010 /*******************************************************************************
0011  * Definitions
0012  ******************************************************************************/
0013 
0014 /* Component ID definition, used by tools. */
0015 #ifndef FSL_COMPONENT_ID
0016 #define FSL_COMPONENT_ID "platform.drivers.xrdc2"
0017 #endif
0018 
0019 /* Definitions for access policy. */
0020 #define XRDC2_DXACP_WIDTH (3U)
0021 #define XRDC2_DXACP_MASK  ((1UL << XRDC2_DXACP_WIDTH) - 1U)
0022 
0023 #define XRDC2_DXACP_0_7(domainId, dxacp)  ((uint32_t)(dxacp) << (XRDC2_DXACP_WIDTH * (uint32_t)(domainId)))
0024 #define XRDC2_DXACP_8_15(domainId, dxacp) ((uint32_t)(dxacp) << (XRDC2_DXACP_WIDTH * ((uint32_t)(domainId)-8U)))
0025 
0026 #define XRDC2_DXACP_0_7_MASK(domainId)  XRDC2_DXACP_0_7(domainId, XRDC2_DXACP_MASK)
0027 #define XRDC2_DXACP_8_15_MASK(domainId) XRDC2_DXACP_8_15(domainId, XRDC2_DXACP_MASK)
0028 
0029 /* Memory region alignment. */
0030 #define XRDC2_MRGD_ADDR_ALIGN_MASK (0x00000FFFU)
0031 
0032 /*******************************************************************************
0033  * Prototypes
0034  ******************************************************************************/
0035 static void XRDC2_MakeDXACP(const xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT],
0036                             uint32_t *w0,
0037                             uint32_t *w1);
0038 
0039 /*******************************************************************************
0040  * Variables
0041  ******************************************************************************/
0042 
0043 /*******************************************************************************
0044  * Code
0045  ******************************************************************************/
0046 
0047 static void XRDC2_MakeDXACP(const xrdc2_access_policy_t policy[FSL_FEATURE_XRDC2_DOMAIN_COUNT],
0048                             uint32_t *w0,
0049                             uint32_t *w1)
0050 {
0051     uint32_t domain = (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT;
0052 
0053     *w0 = 0U;
0054     *w1 = 0U;
0055 
0056 #if (FSL_FEATURE_XRDC2_DOMAIN_COUNT > 8)
0057     while (domain > 8U)
0058     {
0059         domain--;
0060         *w0 <<= XRDC2_DXACP_WIDTH;
0061         *w0 |= (uint32_t)policy[domain - 8U];
0062     }
0063 #endif
0064 
0065     while (domain > 0U)
0066     {
0067         domain--;
0068         *w1 <<= XRDC2_DXACP_WIDTH;
0069         *w1 |= (uint32_t)policy[domain];
0070     }
0071 }
0072 
0073 /*!
0074  * brief Initializes the XRDC2 module.
0075  *
0076  * This function enables the XRDC2 clock.
0077  *
0078  * param base XRDC2 peripheral base address.
0079  */
0080 void XRDC2_Init(XRDC2_Type *base)
0081 {
0082 }
0083 
0084 /*!
0085  * brief De-initializes the XRDC2 module.
0086  *
0087  * This function disables the XRDC2 clock.
0088  *
0089  * param base XRDC2 peripheral base address.
0090  */
0091 void XRDC2_Deinit(XRDC2_Type *base)
0092 {
0093 }
0094 
0095 /*!
0096  * brief Sets the XRDC2 global valid.
0097  *
0098  * This function sets the XRDC2 global valid or invalid. When the XRDC2 is global
0099  * invalid, all accesses from all bus masters to all slaves are allowed.
0100  *
0101  * param base XRDC2 peripheral base address.
0102  * param valid True to valid XRDC2.
0103  */
0104 void XRDC2_SetGlobalValid(XRDC2_Type *base, bool valid)
0105 {
0106     uint32_t mcr = base->MCR & ~(XRDC2_MCR_GVLDM_MASK | XRDC2_MCR_GVLDC_MASK);
0107 
0108     if (valid)
0109     {
0110         mcr |= XRDC2_MCR_GVLDM_MASK;
0111         base->MCR = mcr;
0112 
0113         /* Two dummy read to ensure the configuration takes effect. */
0114         (void)base->MCR;
0115         (void)base->MCR;
0116 
0117         mcr |= XRDC2_MCR_GVLDC_MASK;
0118         base->MCR = mcr;
0119     }
0120     else
0121     {
0122         base->MCR = mcr;
0123     }
0124 }
0125 
0126 /*!
0127  * brief Gets the default master domain assignment.
0128  *
0129  * This function sets the assignment as follows:
0130  *
0131  * code
0132  *  config->lock = false;
0133  *  config->privilegeAttr = kXRDC2_MasterPrivilege;
0134  *  config->secureAttr = kXRDC2_MasterSecure;
0135  *  config->domainId = 0U;
0136  *  config->mask = 0U;
0137  *  config->match = 0U;
0138  * endcode
0139  *
0140  * param assignment Pointer to the assignment structure.
0141  */
0142 void XRDC2_GetDefaultMasterDomainAssignment(xrdc2_master_domain_assignment_t *assignment)
0143 {
0144     assert(NULL != assignment);
0145 
0146     assignment->lock          = false;
0147     assignment->privilegeAttr = kXRDC2_MasterPrivilege;
0148     assignment->secureAttr    = kXRDC2_MasterSecure;
0149     assignment->domainId      = 0U;
0150     assignment->mask          = 0U;
0151     assignment->match         = 0U;
0152 }
0153 
0154 /*!
0155  * brief Sets the processor bus master domain assignment.
0156  *
0157  * param base XRDC2 peripheral base address.
0158  * param master Which master to configure.
0159  * param assignIndex Which assignment register to set.
0160  * param assignment Pointer to the assignment structure.
0161  */
0162 void XRDC2_SetMasterDomainAssignment(XRDC2_Type *base,
0163                                      xrdc2_master_t master,
0164                                      uint8_t assignIndex,
0165                                      const xrdc2_master_domain_assignment_t *assignment)
0166 {
0167     assert(NULL != assignment);
0168     uint32_t w0;
0169     uint32_t w1;
0170 
0171     w0 = (((uint32_t)assignment->mask << XRDC2_MDAC_MDA_W0_MASK_SHIFT) |
0172           ((uint32_t)assignment->match << XRDC2_MDAC_MDA_W0_MATCH_SHIFT));
0173 
0174     w1 = ((uint32_t)assignment->domainId << XRDC2_MDAC_MDA_W1_DID_SHIFT) |
0175          (XRDC2_MDAC_MDA_W1_PA(assignment->privilegeAttr)) | (XRDC2_MDAC_MDA_W1_SA(assignment->secureAttr)) |
0176          XRDC2_MDAC_MDA_W1_VLD_MASK;
0177 
0178     if (assignment->lock)
0179     {
0180         w1 |= XRDC2_MDAC_MDA_W1_DL_MASK;
0181     }
0182 
0183     base->MDACI_MDAJ[master][assignIndex].MDAC_MDA_W0 = w0;
0184     base->MDACI_MDAJ[master][assignIndex].MDAC_MDA_W1 = w1;
0185 }
0186 
0187 /*!
0188  * brief Gets the default memory slot access configuration.
0189  *
0190  * This function sets the assignment as follows:
0191  *
0192  * code
0193  *  config->lockMode = kXRDC2_AccessConfigLockDisabled;
0194  *  config->policy[0] = kXRDC2_AccessPolicyNone;
0195  *  config->policy[1] = kXRDC2_AccessPolicyNone;
0196  *  ...
0197  * endcode
0198  *
0199  * param config Pointer to the configuration.
0200  */
0201 void XRDC2_GetMemSlotAccessDefaultConfig(xrdc2_mem_slot_access_config_t *config)
0202 {
0203     assert(NULL != config);
0204 
0205     uint8_t domain;
0206 
0207     config->lockMode = kXRDC2_AccessConfigLockDisabled;
0208 
0209     for (domain = 0; domain < (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT; domain++)
0210     {
0211         config->policy[domain] = kXRDC2_AccessPolicyNone;
0212     }
0213 }
0214 
0215 /*!
0216  * brief Sets the memory slot access policy.
0217  *
0218  * param base XRDC2 peripheral base address.
0219  * param config Pointer to the access policy configuration structure.
0220  */
0221 void XRDC2_SetMemSlotAccessConfig(XRDC2_Type *base,
0222                                   xrdc2_mem_slot_t memSlot,
0223                                   const xrdc2_mem_slot_access_config_t *config)
0224 {
0225     assert(NULL != config);
0226 
0227     uint32_t w0 = 0;
0228     uint32_t w1 = 0;
0229 
0230     XRDC2_MakeDXACP(config->policy, &w0, &w1);
0231 
0232     w1 |= XRDC2_MSC_MSAC_W1_DL2(config->lockMode);
0233     w1 |= XRDC2_MSC_MSAC_W1_VLD_MASK;
0234 
0235     base->MSCI_MSAC_WK[(uint8_t)memSlot].MSC_MSAC_W0 = w0;
0236     base->MSCI_MSAC_WK[(uint8_t)memSlot].MSC_MSAC_W1 = w1;
0237 }
0238 
0239 /*!
0240  * brief Sets the memory slot descriptor as valid or invalid.
0241  *
0242  * param base XRDC2 peripheral base address.
0243  * param memSlot Which memory slot descriptor to set.
0244  * param valid True to set valid, false to set invalid.
0245  */
0246 void XRDC2_SetMemSlotAccessValid(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, bool valid)
0247 {
0248     uint32_t reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 & ~XRDC2_EAL_MASK;
0249 
0250     if (valid)
0251     {
0252         base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = (reg | XRDC2_MSC_MSAC_W1_VLD_MASK);
0253     }
0254     else
0255     {
0256         base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = (reg & ~XRDC2_MSC_MSAC_W1_VLD_MASK);
0257     }
0258 }
0259 
0260 /*!
0261  * brief Sets the memory slot descriptor lock mode.
0262  *
0263  * param base XRDC2 peripheral base address.
0264  * param memSlot Which memory slot descriptor to set.
0265  * param lockMode The lock mode to set.
0266  */
0267 void XRDC2_SetMemSlotAccessLockMode(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, xrdc2_access_config_lock_t lockMode)
0268 {
0269     uint32_t reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 & ~(XRDC2_EAL_MASK | XRDC2_MRC_MRGD_W6_DL2_MASK);
0270 
0271     base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = (reg | XRDC2_MRC_MRGD_W6_DL2(lockMode));
0272 }
0273 
0274 /*!
0275  * brief Sets the memory slot access policy for specific domain.
0276  *
0277  * param base XRDC2 peripheral base address.
0278  * param memSlot The memory slot to operate.
0279  * param domainId The ID of the domain whose policy will be changed.
0280  * param policy The access policy to set.
0281  */
0282 void XRDC2_SetMemSlotDomainAccessPolicy(XRDC2_Type *base,
0283                                         xrdc2_mem_slot_t memSlot,
0284                                         uint8_t domainId,
0285                                         xrdc2_access_policy_t policy)
0286 {
0287     uint32_t reg;
0288 
0289     if (domainId < 8U)
0290     {
0291         reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W0 & ~XRDC2_DXACP_0_7_MASK(domainId);
0292         reg |= XRDC2_DXACP_0_7(domainId, policy);
0293         base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W0 = reg;
0294     }
0295     else
0296     {
0297         reg = base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 & ~XRDC2_DXACP_8_15_MASK(domainId);
0298         reg |= XRDC2_DXACP_8_15(domainId, policy);
0299         reg &= ~XRDC2_EAL_MASK;
0300         base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = reg;
0301     }
0302 }
0303 
0304 /*!
0305  * brief Enable or disable the memory slot exclusive access lock.
0306  *
0307  * The lock must be enabled first before use. Once disabled, it could not be
0308  * enabled until reset.
0309  *
0310  * param base XRDC2 peripheral base address.
0311  * param memSlot The memory slot to operate.
0312  * param enable True to enable, false to disable.
0313  */
0314 void XRDC2_EnableMemSlotExclAccessLock(XRDC2_Type *base, xrdc2_mem_slot_t memSlot, bool enable)
0315 {
0316     if (enable)
0317     {
0318         base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = XRDC2_EAL_UNLOCKED;
0319     }
0320     else
0321     {
0322         base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1 = XRDC2_EAL_DISABLE_UNTIL_RESET;
0323     }
0324 }
0325 
0326 /*!
0327  * @brief Get current memory slot exclusive access lock owner.
0328  *
0329  * @param base XRDC2 peripheral base address.
0330  * @param memSlot The memory slot to operate.
0331  * @return The domain ID of the lock owner.
0332  */
0333 uint8_t XRDC2_GetMemSlotExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
0334 {
0335     return (uint8_t)((base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W0 & XRDC2_MSC_MSAC_W0_EALO_MASK) >>
0336                      XRDC2_MSC_MSAC_W0_EALO_SHIFT);
0337 }
0338 
0339 /*!
0340  * brief Try to lock the memory slot exclusive access.
0341  *
0342  * param base XRDC2 peripheral base address.
0343  * param memSlot The memory slot to operate.
0344  * retval kStatus_Fail Failed to lock.
0345  * retval kStatus_Success Locked succussfully.
0346  */
0347 status_t XRDC2_TryLockMemSlotExclAccess(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
0348 {
0349     status_t status;
0350     uint8_t curDomainID;
0351     volatile uint32_t *lockReg = &(base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1);
0352 
0353     curDomainID = XRDC2_GetCurrentMasterDomainId(base);
0354 
0355     *lockReg = XRDC2_EAL_LOCKED;
0356 
0357     if (curDomainID != XRDC2_GetMemSlotExclAccessLockDomainOwner(base, memSlot))
0358     {
0359         status = kStatus_Fail;
0360     }
0361     else
0362     {
0363         status = kStatus_Success;
0364     }
0365 
0366     return status;
0367 }
0368 
0369 /*!
0370  * brief Lock the memory slot exclusive access using blocking method.
0371  *
0372  * param base XRDC2 peripheral base address.
0373  * param memSlot The memory slot to operate.
0374  *
0375  * note This function must be called when the lock is not disabled.
0376  */
0377 void XRDC2_LockMemSlotExclAccess(XRDC2_Type *base, xrdc2_mem_slot_t memSlot)
0378 {
0379     uint8_t curDomainID;
0380     volatile uint32_t *lockReg = &(base->MSCI_MSAC_WK[(uint32_t)memSlot].MSC_MSAC_W1);
0381 
0382     curDomainID = XRDC2_GetCurrentMasterDomainId(base);
0383 
0384     while (true)
0385     {
0386         *lockReg = XRDC2_EAL_LOCKED;
0387 
0388         /* Locked and owner is current domain. */
0389         if (curDomainID == XRDC2_GetMemSlotExclAccessLockDomainOwner(base, memSlot))
0390         {
0391             break;
0392         }
0393     }
0394 
0395     return;
0396 }
0397 
0398 /*!
0399  * brief Gets the default memory access configuration.
0400  *
0401  * This function sets the assignment as follows:
0402  *
0403  * code
0404  *  config->startAddr = 0U;
0405  *  config->endAddr = 0xFFFFFFFFU;
0406  *  config->lockMode = kXRDC2_AccessConfigLockDisabled;
0407  *  config->policy[0] = kXRDC2_AccessPolicyNone;
0408  *  config->policy[1] = kXRDC2_AccessPolicyNone;
0409  *  ...
0410  * endcode
0411  *
0412  * param config Pointer to the configuration.
0413  */
0414 void XRDC2_GetMemAccessDefaultConfig(xrdc2_mem_access_config_t *config)
0415 {
0416     assert(NULL != config);
0417 
0418     uint8_t domain;
0419 
0420     config->startAddr = 0U;
0421     config->endAddr   = 0xFFFFFFFFU;
0422     config->lockMode  = kXRDC2_AccessConfigLockDisabled;
0423 
0424     for (domain = 0; domain < (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT; domain++)
0425     {
0426         config->policy[domain] = kXRDC2_AccessPolicyNone;
0427     }
0428 }
0429 
0430 /*!
0431  * brief Sets the memory region access policy.
0432  *
0433  * param base XRDC2 peripheral base address.
0434  * param config Pointer to the access policy configuration structure.
0435  */
0436 void XRDC2_SetMemAccessConfig(XRDC2_Type *base, xrdc2_mem_t mem, const xrdc2_mem_access_config_t *config)
0437 {
0438     assert(NULL != config);
0439     /* Check the memory region alignment. */
0440     assert((config->startAddr & XRDC2_MRGD_ADDR_ALIGN_MASK) == 0U);
0441     assert(((config->endAddr + 1U) & XRDC2_MRGD_ADDR_ALIGN_MASK) == 0U);
0442 
0443     uint32_t w5 = 0;
0444     uint32_t w6 = 0;
0445 
0446     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0447     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0448 
0449     XRDC2_MakeDXACP(config->policy, &w5, &w6);
0450 
0451     w6 |= XRDC2_MRC_MRGD_W6_DL2(config->lockMode);
0452     w6 |= XRDC2_MRC_MRGD_W6_VLD_MASK;
0453 
0454     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W0 = config->startAddr;
0455     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W1 = 0U;
0456     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W2 = config->endAddr;
0457     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W3 = 0U;
0458     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 = w5;
0459     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = w6;
0460 }
0461 
0462 /*!
0463  * brief Sets the memory region descriptor as valid or invalid.
0464  *
0465  * param base XRDC2 peripheral base address.
0466  * param mem Which memory region descriptor to set.
0467  * param valid True to set valid, false to set invalid.
0468  */
0469 void XRDC2_SetMemAccessValid(XRDC2_Type *base, xrdc2_mem_t mem, bool valid)
0470 {
0471     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0472     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0473     uint32_t reg  = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 & ~XRDC2_EAL_MASK;
0474 
0475     if (valid)
0476     {
0477         base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = (reg | XRDC2_MRC_MRGD_W6_VLD_MASK);
0478     }
0479     else
0480     {
0481         base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = (reg & ~XRDC2_MRC_MRGD_W6_VLD_MASK);
0482     }
0483 }
0484 
0485 /*!
0486  * brief Sets the memory descriptor lock mode.
0487  *
0488  * param base XRDC2 peripheral base address.
0489  * param mem Which memory descriptor to set.
0490  * param lockMode The lock mode to set.
0491  */
0492 void XRDC2_SetMemAccessLockMode(XRDC2_Type *base, xrdc2_mem_t mem, xrdc2_access_config_lock_t lockMode)
0493 {
0494     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0495     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0496     uint32_t reg  = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 & ~(XRDC2_EAL_MASK | XRDC2_MRC_MRGD_W6_DL2_MASK);
0497 
0498     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = (reg | XRDC2_MRC_MRGD_W6_DL2(lockMode));
0499 }
0500 
0501 /*!
0502  * brief Sets the memory region access policy for specific domain.
0503  *
0504  * param base XRDC2 peripheral base address.
0505  * param mem The memory region to operate.
0506  * param domainId The ID of the domain whose policy will be changed.
0507  * param policy The access policy to set.
0508  */
0509 void XRDC2_SetMemDomainAccessPolicy(XRDC2_Type *base, xrdc2_mem_t mem, uint8_t domainId, xrdc2_access_policy_t policy)
0510 {
0511     uint32_t reg;
0512     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0513     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0514 
0515     if (domainId < 8U)
0516     {
0517         reg = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 & ~XRDC2_DXACP_0_7_MASK(domainId);
0518         reg |= XRDC2_DXACP_0_7(domainId, policy);
0519         base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 = reg;
0520     }
0521     else
0522     {
0523         reg = base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 & ~XRDC2_DXACP_8_15_MASK(domainId);
0524         reg |= XRDC2_DXACP_8_15(domainId, policy);
0525         reg &= ~XRDC2_EAL_MASK;
0526         base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = reg;
0527     }
0528 }
0529 
0530 /*!
0531  * brief Disable the memory region exclusive access lock.
0532  *
0533  * Once disabled, it could not be enabled until reset.
0534  *
0535  * param base XRDC2 peripheral base address.
0536  * param mem The memory region to operate.
0537  */
0538 void XRDC2_EnableMemExclAccessLock(XRDC2_Type *base, xrdc2_mem_t mem, bool enable)
0539 {
0540     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0541     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0542 
0543     if (enable)
0544     {
0545         base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_UNLOCKED;
0546     }
0547     else
0548     {
0549         base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_DISABLE_UNTIL_RESET;
0550     }
0551 }
0552 
0553 /*!
0554  * brief Get current memory region exclusive access lock owner.
0555  *
0556  * param base XRDC2 peripheral base address.
0557  * param mem The memory region to operate.
0558  * param The domain ID of the lock owner.
0559  */
0560 uint8_t XRDC2_GetMemExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_mem_t mem)
0561 {
0562     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0563     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0564 
0565     return (uint8_t)((base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W5 & XRDC2_MRC_MRGD_W5_EALO_MASK) >>
0566                      XRDC2_MRC_MRGD_W5_EALO_SHIFT);
0567 }
0568 
0569 /*!
0570  * brief Try to lock the memory region exclusive access.
0571  *
0572  * param base XRDC2 peripheral base address.
0573  * param mem The memory region to operate.
0574  * retval kStatus_Fail Failed to lock.
0575  * retval kStatus_Success Locked succussfully.
0576  */
0577 status_t XRDC2_TryLockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem)
0578 {
0579     status_t status;
0580     uint8_t curDomainID;
0581     uint32_t mrc               = XRDC2_GET_MRC((uint32_t)mem);
0582     uint32_t mrgd              = XRDC2_GET_MRGD((uint32_t)mem);
0583     volatile uint32_t *lockReg = &(base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6);
0584 
0585     curDomainID = XRDC2_GetCurrentMasterDomainId(base);
0586 
0587     *lockReg = XRDC2_EAL_LOCKED;
0588 
0589     if (curDomainID != XRDC2_GetMemExclAccessLockDomainOwner(base, mem))
0590     {
0591         status = kStatus_Fail;
0592     }
0593     else
0594     {
0595         status = kStatus_Success;
0596     }
0597 
0598     return status;
0599 }
0600 
0601 /*!
0602  * brief Lock the memory region exclusive access using blocking method.
0603  *
0604  * param base XRDC2 peripheral base address.
0605  * param mem The memory region to operate.
0606  *
0607  * note This function must be called when the lock is not disabled.
0608  */
0609 void XRDC2_LockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem)
0610 {
0611     uint8_t curDomainID;
0612     uint32_t mrc               = XRDC2_GET_MRC((uint32_t)mem);
0613     uint32_t mrgd              = XRDC2_GET_MRGD((uint32_t)mem);
0614     volatile uint32_t *lockReg = &(base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6);
0615 
0616     curDomainID = XRDC2_GetCurrentMasterDomainId(base);
0617 
0618     while (true)
0619     {
0620         *lockReg = XRDC2_EAL_LOCKED;
0621 
0622         /* Locked and owner is current domain. */
0623         if (curDomainID == XRDC2_GetMemExclAccessLockDomainOwner(base, mem))
0624         {
0625             break;
0626         }
0627     }
0628 
0629     return;
0630 }
0631 
0632 /*!
0633  * brief Unlock the memory region exclusive access.
0634  *
0635  * param base XRDC2 peripheral base address.
0636  * param mem The memory region to operate.
0637  *
0638  * note This function must be called by the lock owner.
0639  */
0640 void XRDC2_UnlockMemExclAccess(XRDC2_Type *base, xrdc2_mem_t mem)
0641 {
0642     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0643     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0644 
0645     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_UNLOCKED;
0646 }
0647 
0648 /*!
0649  * brief Force the memory region exclusive access lock release.
0650  *
0651  * The master does not own the lock could call this function to force release the lock.
0652  *
0653  * param base XRDC2 peripheral base address.
0654  * param mem The memory region to operate.
0655  */
0656 void XRDC2_ForceMemExclAccessLockRelease(XRDC2_Type *base, xrdc2_mem_t mem)
0657 {
0658     uint32_t mrc  = XRDC2_GET_MRC((uint32_t)mem);
0659     uint32_t mrgd = XRDC2_GET_MRGD((uint32_t)mem);
0660 
0661     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_FORCE_RELEASE_MAGIC_0;
0662     base->MRCI_MRGDJ[mrc][mrgd].MRC_MRGD_W6 = XRDC2_EAL_FORCE_RELEASE_MAGIC_1;
0663 }
0664 
0665 /*!
0666  * brief Gets the default peripheral access configuration.
0667  *
0668  * The default configuration is set as follows:
0669  * code
0670  * config->lockMode          = kXRDC2_AccessConfigLockWritable;
0671  * config->policy[0]         = kXRDC2_AccessPolicyNone;
0672  * config->policy[1]         = kXRDC2_AccessPolicyNone;
0673  * ...
0674  * config->policy[15]        = kXRDC2_AccessPolicyNone;
0675  * endcode
0676  *
0677  * param config Pointer to the configuration structure.
0678  */
0679 void XRDC2_GetPeriphAccessDefaultConfig(xrdc2_periph_access_config_t *config)
0680 {
0681     assert(NULL != config);
0682 
0683     uint8_t domain;
0684 
0685     config->lockMode = kXRDC2_AccessConfigLockDisabled;
0686 
0687     for (domain = 0; domain < (uint32_t)FSL_FEATURE_XRDC2_DOMAIN_COUNT; domain++)
0688     {
0689         config->policy[domain] = kXRDC2_AccessPolicyNone;
0690     }
0691 }
0692 
0693 /*!
0694  * brief Sets the peripheral access policy.
0695  *
0696  * param base XRDC2 peripheral base address.
0697  * param config Pointer to the access policy configuration structure.
0698  */
0699 void XRDC2_SetPeriphAccessConfig(XRDC2_Type *base, xrdc2_periph_t periph, const xrdc2_periph_access_config_t *config)
0700 {
0701     assert(NULL != config);
0702 
0703     uint32_t w0 = 0;
0704     uint32_t w1 = 0;
0705 
0706     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0707     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0708 
0709     XRDC2_MakeDXACP(config->policy, &w0, &w1);
0710 
0711     w1 |= XRDC2_PAC_PDAC_W1_DL2(config->lockMode);
0712     w1 |= XRDC2_PAC_PDAC_W1_VLD_MASK;
0713 
0714     base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 = w0;
0715     base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = w1;
0716 }
0717 
0718 /*!
0719  * brief Sets the peripheral descriptor as valid or invalid.
0720  *
0721  * param base XRDC2 peripheral base address.
0722  * param periph Which peripheral descriptor to set.
0723  * param valid True to set valid, false to set invalid.
0724  */
0725 void XRDC2_SetPeriphAccessValid(XRDC2_Type *base, xrdc2_periph_t periph, bool valid)
0726 {
0727     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0728     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0729     uint32_t reg  = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 & ~XRDC2_EAL_MASK;
0730 
0731     if (valid)
0732     {
0733         base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = (reg | XRDC2_PAC_PDAC_W1_VLD_MASK);
0734     }
0735     else
0736     {
0737         base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = (reg & ~XRDC2_PAC_PDAC_W1_VLD_MASK);
0738     }
0739 }
0740 
0741 /*!
0742  * brief Sets the peripheral descriptor lock mode.
0743  *
0744  * param base XRDC2 peripheral base address.
0745  * param periph Which peripheral descriptor to set.
0746  * param lockMode The lock mode to set.
0747  */
0748 void XRDC2_SetPeriphAccessLockMode(XRDC2_Type *base, xrdc2_periph_t periph, xrdc2_access_config_lock_t lockMode)
0749 {
0750     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0751     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0752     uint32_t reg  = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 & ~(XRDC2_EAL_MASK | XRDC2_PAC_PDAC_W1_DL2_MASK);
0753 
0754     base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = (reg | XRDC2_PAC_PDAC_W1_DL2(lockMode));
0755 }
0756 
0757 /*!
0758  * brief Sets the peripheral access policy for specific domain.
0759  *
0760  * param base XRDC2 peripheral base address.
0761  * param periph The peripheral to operate.
0762  * param domainId The ID of the domain whose policy will be changed.
0763  * param policy The access policy to set.
0764  */
0765 void XRDC2_SetPeriphDomainAccessPolicy(XRDC2_Type *base,
0766                                        xrdc2_periph_t periph,
0767                                        uint8_t domainId,
0768                                        xrdc2_access_policy_t policy)
0769 {
0770     uint32_t reg;
0771     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0772     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0773 
0774     if (domainId < 8U)
0775     {
0776         reg = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 & ~XRDC2_DXACP_0_7_MASK(domainId);
0777         reg |= XRDC2_DXACP_0_7(domainId, policy);
0778         base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 = reg;
0779     }
0780     else
0781     {
0782         reg = base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 & ~XRDC2_DXACP_8_15_MASK(domainId);
0783         reg |= XRDC2_DXACP_8_15(domainId, policy);
0784         reg &= ~XRDC2_EAL_MASK;
0785         base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = reg;
0786     }
0787 }
0788 
0789 /*!
0790  * brief Get current peripheral exclusive access lock owner.
0791  *
0792  * param base XRDC2 peripheral base address.
0793  * param periph The peripheral to operate.
0794  * param The domain ID of the lock owner.
0795  */
0796 uint8_t XRDC2_GetPeriphExclAccessLockDomainOwner(XRDC2_Type *base, xrdc2_periph_t periph)
0797 {
0798     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0799     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0800 
0801     return (uint8_t)((base->PACI_PDACJ[pac][pdac].PAC_PDAC_W0 & XRDC2_PAC_PDAC_W0_EALO_MASK) >>
0802                      XRDC2_PAC_PDAC_W0_EALO_SHIFT);
0803 }
0804 
0805 /*!
0806  * brief Disable the peripheral exclusive access lock.
0807  *
0808  * Once disabled, it could not be enabled until reset.
0809  *
0810  * param base XRDC2 peripheral base address.
0811  * param periph The peripheral to operate.
0812  * param enable True to enable, false to disable.
0813  */
0814 void XRDC2_EnablePeriphExclAccessLock(XRDC2_Type *base, xrdc2_periph_t periph, bool enable)
0815 {
0816     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0817     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0818 
0819     if (enable)
0820     {
0821         base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_UNLOCKED;
0822     }
0823     else
0824     {
0825         base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_DISABLE_UNTIL_RESET;
0826     }
0827 }
0828 
0829 /*!
0830  * brief Try to lock the peripheral exclusive access.
0831  *
0832  * param base XRDC2 peripheral base address.
0833  * param periph The peripheral to operate.
0834  * retval kStatus_Fail Failed to lock.
0835  * retval kStatus_Success Locked succussfully.
0836  */
0837 status_t XRDC2_TryLockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph)
0838 {
0839     status_t status;
0840     uint8_t curDomainID;
0841     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0842     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0843 
0844     volatile uint32_t *lockReg = &(base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1);
0845 
0846     curDomainID = XRDC2_GetCurrentMasterDomainId(base);
0847 
0848     *lockReg = XRDC2_EAL_LOCKED;
0849 
0850     if (curDomainID != XRDC2_GetPeriphExclAccessLockDomainOwner(base, periph))
0851     {
0852         status = kStatus_Fail;
0853     }
0854     else
0855     {
0856         status = kStatus_Success;
0857     }
0858 
0859     return status;
0860 }
0861 
0862 /*!
0863  * brief Lock the peripheral exclusive access using blocking method.
0864  *
0865  * param base XRDC2 peripheral base address.
0866  * param periph The peripheral to operate.
0867  *
0868  * note This function must be called when the lock is not disabled.
0869  */
0870 void XRDC2_LockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph)
0871 {
0872     uint8_t curDomainID;
0873     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0874     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0875 
0876     volatile uint32_t *lockReg = &(base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1);
0877 
0878     curDomainID = XRDC2_GetCurrentMasterDomainId(base);
0879 
0880     while (true)
0881     {
0882         *lockReg = XRDC2_EAL_LOCKED;
0883 
0884         /* Locked and owner is current domain. */
0885         if (curDomainID == XRDC2_GetPeriphExclAccessLockDomainOwner(base, periph))
0886         {
0887             break;
0888         }
0889     }
0890 
0891     return;
0892 }
0893 
0894 /*!
0895  * brief Unlock the peripheral exclusive access.
0896  *
0897  * param base XRDC2 peripheral base address.
0898  * param periph The peripheral to operate.
0899  *
0900  * note This function must be called by the lock owner.
0901  */
0902 void XRDC2_UnlockPeriphExclAccess(XRDC2_Type *base, xrdc2_periph_t periph)
0903 {
0904     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0905     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0906 
0907     base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_UNLOCKED;
0908 }
0909 
0910 /*!
0911  * brief Force the peripheral exclusive access lock release.
0912  *
0913  * The master does not own the lock could call this function to force release the lock.
0914  *
0915  * param base XRDC2 peripheral base address.
0916  * param periph The peripheral to operate.
0917  */
0918 void XRDC2_ForcePeriphExclAccessLockRelease(XRDC2_Type *base, xrdc2_periph_t periph)
0919 {
0920     uint32_t pac  = XRDC2_GET_PAC((uint32_t)periph);
0921     uint32_t pdac = XRDC2_GET_PDAC((uint32_t)periph);
0922 
0923     base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_FORCE_RELEASE_MAGIC_0;
0924     base->PACI_PDACJ[pac][pdac].PAC_PDAC_W1 = XRDC2_EAL_FORCE_RELEASE_MAGIC_1;
0925 }