PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_mpu.c

129 lines
4.2 KiB
C

/**
* @file fc7xxx_driver_mpu.c
* @author Flagchip085
* @brief FC7xxx MPU driver type definition and API
* @version 0.1.0
* @date 2024-01-12
*
* @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd.
*
* @details The MPU only checks the CPU master access to CTCM and DTCM memory. When access denied, it will cause MemManage Interrupt.
*/
/* ********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240
******************************************************************************** */
#include "fc7xxx_driver_mpu.h"
void MPU_Disable(void)
{
__DMB(); /* make sure outstanding transfers are done */
MPU_HWA_Fault_Disable();
MPU_HWA_Set_CR(0U); /* disable mpu and clear its control register*/
}
void MPU_Enable(MPU_EnableOptionType eOption)
{
uint32_t u32Option;
switch (eOption)
{
case MPU_EN_HARDFAULT_NMI:
u32Option = CORTEX_MPU_CTRL_HFNMIENA_MASK;
break;
case MPU_EN_PRIVILEGED_DEFAULT:
u32Option = CORTEX_MPU_CTRL_RPRIVDEFENA_MASK;
break;
case MPU_EN_HFNMI_PRIVDEF:
u32Option = (CORTEX_MPU_CTRL_HFNMIENA_MASK | CORTEX_MPU_CTRL_RPRIVDEFENA_MASK);
break;
case MPU_EN_HFNMI_PRIVDEF_NONE:
u32Option = 0U;
break;
default:
u32Option = 0U;
break;
}
MPU_HWA_Set_CR(CORTEX_MPU_CTRL_ENABLE_MASK | (((uint32_t)u32Option) & MPU_EN_MASK_U32));
MPU_HWA_Fault_Enable(); /* mpu fault MemManage INT enable */
__DSB();
__ISB();
}
MPU_StatusType MPU_RegionDisable(MPU_RegionNumberType eRegion)
{
MPU_HWA_Set_NR((uint8_t)eRegion);
MPU_HWA_Set_BAR(0x00U);
MPU_HWA_Set_ASR(0x00U);
return MPU_STATUS_SUCCESS;
}
MPU_StatusType MPU_RegionEnable(MPU_RegionNumberType eRegion, const MPU_RegionConfigurationType *pConfig)
{
MPU_StatusType eRet = MPU_STATUS_SUCCESS;
uint32_t u32Srd;
uint32_t u32Asr;
if ((NULL == pConfig) ||
((uint32_t)eRegion > (uint32_t)MPU_REGION_NUMBER_15) ||
(0U != (pConfig->u32BaseAddr & MPU_RBAR_VALID_REGION_MASK_U32)) ||
((uint32_t)pConfig->eRegionSize < (uint32_t)MPU_REGION_SIZE_32B) ||
((uint32_t)pConfig->eRegionSize > (uint32_t)MPU_REGION_SIZE_4GB))
{
eRet = MPU_STATUS_ERROR;
}
else
{
/* use bit shift is surely safe */
u32Srd = (((((uint32_t)pConfig->eSubRegionDis_0) << 0) |
(((uint32_t)pConfig->eSubRegionDis_1) << 1) |
(((uint32_t)pConfig->eSubRegionDis_2) << 2) |
(((uint32_t)pConfig->eSubRegionDis_3) << 3) |
(((uint32_t)pConfig->eSubRegionDis_4) << 4) |
(((uint32_t)pConfig->eSubRegionDis_5) << 5) |
(((uint32_t)pConfig->eSubRegionDis_6) << 6) |
(((uint32_t)pConfig->eSubRegionDis_7) << 7)) & 0xFFU);
u32Asr = CORTEX_MPU_RASR_XN(pConfig->eExecuteNever) |
CORTEX_MPU_RASR_AP(pConfig->eAccessPermission) |
CORTEX_MPU_RASR_TEX(pConfig->eTypeExtLevel) |
CORTEX_MPU_RASR_S(pConfig->eShareable) |
CORTEX_MPU_RASR_C(pConfig->eCacheable) |
CORTEX_MPU_RASR_B(pConfig->eBufferable) |
CORTEX_MPU_RASR_SRD(u32Srd) |
CORTEX_MPU_RASR_SIZE(pConfig->eRegionSize) |
CORTEX_MPU_RASR_ENABLE_MASK;
MPU_HWA_Set_NR((uint8_t)eRegion);
MPU_HWA_Set_BAR(pConfig->u32BaseAddr & MPU_RBAR_BASEADDR_MASK_U32); /* ignore VALID and REGION bits */
MPU_HWA_Set_ASR(u32Asr);
}
return eRet;
}
MPU_StatusType MPU_CheckExist(void)
{
uint32_t u32RegVal = MPU_HWA_Get_Type();
MPU_StatusType eRet = MPU_STATUS_SUCCESS;
if (0U == u32RegVal)
{
eRet = MPU_STATUS_ERROR;
}
return eRet;
}