/** ************************************************************************************************ * SEMIDRIVE Copyright Statement * Copyright (c) SEMIDRIVE. All rights reserved * * This software and all rights therein are owned by SEMIDRIVE, and are * protected by copyright law and other relevant laws, regulations and * protection. Without SEMIDRIVE's prior written consent and/or related rights, * please do not use this software or any potion thereof in any form or by any * means. You may not reproduce, modify or distribute this software except in * compliance with the License. Unless required by applicable law or agreed to * in writing, software distributed under the License is distributed on * an 'AS IS' basis, WITHOUT WARRANTIES OF ANY KIND, either express or implied. * **************************************************************************************************/ /** ************************************************************************************************ * \file sdrv_firewall_ppc.c * \brief SSDK Firewall PPC Driver * * *
Date Version *
2023/11/29 1.0.0 *
**************************************************************************************************/ #ifdef __cplusplus extern "C" { #endif /*************************************************************************************************** * Include header files **************************************************************************************************/ #include #include "string.h" #include "sdrv_firewall_ppc.h" /*************************************************************************************************** * Private Macro definition **************************************************************************************************/ /** \brief The size of the apbmux ppc register. */ #define FIREWALL_PPC_APBMUX_SIZE ((uint32_t)0x800U) /** \brief The offset address of the ppc permission0 register. */ #define FIREWALL_PPC_DOM_PER0_0 ((uint32_t)0x00U) /** \brief The size of the ppc permission0 register. */ #define FIREWALL_PPC_DOM_PER0_SIZE ((uint32_t)0x0CU) /** \brief The offset address of the ppc permission0 register for differet * peripherals or apb regions. */ #define FIREWALL_PPC_DOM_PER0_X(n) \ ((((uint32_t)(n))) * FIREWALL_PPC_DOM_PER0_SIZE) /** \brief The address of the ppc permission0 register for differet peripherals * or apb regions. */ #define FIREWALL_PPC_DOMPER0_ADDR(base, apbmuxId, ipId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_DOM_PER0_X(ipId)) /** \brief The offset address of the ppc permission1 register. */ #define FIREWALL_PPC_DOM_PER1_0 ((uint32_t)0x04U) /** \brief The size of the ppc permission1 register. */ #define FIREWALL_PPC_DOM_PER1_SIZE ((uint32_t)0x0CU) /** \brief The offset address of the ppc permission1 register for differet * peripherals or apb regions. */ #define FIREWALL_PPC_DOM_PER1_X(n) \ (FIREWALL_PPC_DOM_PER1_0 + ((((uint32_t)(n))) * FIREWALL_PPC_DOM_PER1_SIZE)) /** \brief The address of the ppc permission1 register for differet peripherals * or apb regions. */ #define FIREWALL_PPC_DOMPER1_ADDR(base, apbmuxId, ipId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_DOM_PER1_X(ipId)) /** \brief The offset address of the ppc permission lock register. */ #define FIREWALL_PPC_DOM_PER_LOCK_0 ((uint32_t)0x08U) /** \brief The size of the ppc permission lock register. */ #define FIREWALL_PPC_DOM_PER_LOCK_SIZE ((uint32_t)0x0CU) /** \brief The offset address of the ppc permission lock register for differet * peripherals or apb regions. */ #define FIREWALL_PPC_DOM_PER_LOCK_X(n) \ (FIREWALL_PPC_DOM_PER_LOCK_0 + \ ((((uint32_t)(n)) * FIREWALL_PPC_DOM_PER_LOCK_SIZE))) /** \brief The address of the ppc permission lock register for differet * peripherals or apb regions. */ #define FIREWALL_PPC_DOM_PER_LOCK_ADDR(base, apbmuxId, ipId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_DOM_PER_LOCK_X(ipId)) /** \brief The offset address of the start address register. */ #define FIREWALL_PPC_RGN_START_ADDR_0 ((uint32_t)0x640U) /** \brief The size of the start address register. */ #define FIREWALL_PPC_RGN_START_ADDR_SIZE ((uint32_t)0x08U) /** \brief The offset bit of the start address of the apb region. */ #define FIREWALL_PPC_RGN_START_ADDR_BIT (0U) /** \brief The width of the start address of the apb region. */ #define FIREWALL_PPC_RGN_START_ADDR_WIDTH (30U) /** \brief The offset address of the start address register for different apb * regions. */ #define FIREWALL_PPC_RGN_START_ADDR_X(n) \ (FIREWALL_PPC_RGN_START_ADDR_0 + \ (((uint32_t)(n)) * FIREWALL_PPC_RGN_START_ADDR_SIZE)) /** \brief The address of the start address register for different apb regions. */ #define FIREWALL_PPC_RGN_START_REG_ADDR(base, apbmuxId, regionId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_RGN_START_ADDR_X(regionId)) /** \brief The offset address of the end address register. */ #define FIREWALL_PPC_RGN_END_ADDR_0 ((uint32_t)0x644U) /** \brief The size of the end address register. */ #define FIREWALL_PPC_RGN_END_ADDR_SIZE ((uint32_t)0x08U) /** \brief The offset bit of the end address of the apb region. */ #define FIREWALL_PPC_RGN_END_ADDR_BIT (0U) /** \brief The width of the end address of the apb region. */ #define FIREWALL_PPC_RGN_END_ADDR_WIDTH (30U) /** \brief The bit mask of locking the address configuration of the apb region. */ #define FIREWALL_PPC_RGN_END_ADDR_LOCK (1UL << 31U) /** \brief The offset address of the end address register for different apb * regions. */ #define FIREWALL_PPC_RGN_END_ADDR_X(n) \ (FIREWALL_PPC_RGN_END_ADDR_0 + \ (((uint32_t)(n)) * FIREWALL_PPC_RGN_END_ADDR_SIZE)) /** \brief The address of the end address register for different apb regions. */ #define FIREWALL_PPC_RGN_END_REG_ADDR(base, apbmuxId, regionId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_RGN_END_ADDR_X(regionId)) /** \brief The offset address of the interrupt status register. */ #define FIREWALL_PPC_FUNC_INT_STA_OFFSET ((uint32_t)0x6f0U) /** \brief The bit mask of the register error interrupt. */ #define FIREWALL_PPC_FUNC_INT_STA_REG_RES_ERR (1UL << 1) /** \brief The bit mask of the peripheral error interrupt. */ #define FIREWALL_PPC_FUNC_INT_STA_PER_RES_ERR (1UL) /** \brief The address of the interrupt status register for different apbmuxs. */ #define FIREWALL_PPC_FUNC_INT_STA_ADDR(base, apbmuxId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_FUNC_INT_STA_OFFSET) /** \brief The offset address of the interrupt enable register. */ #define FIREWALL_PPC_FUNC_INT_STA_EN_OFFSET ((uint32_t)0x6f4U) /** \brief The bit mask of enabling the register error interrupt. */ #define FIREWALL_PPC_FUNC_INT_STA_EN_REG_RES_ERR (1UL << 1) /** \brief The bit mask of enabling the peripheral error interrupt. */ #define FIREWALL_PPC_FUNC_INT_STA_EN_PER_RES_ERR (1UL) /** \brief The address of the interrupt enable register for different apbmuxs. */ #define FIREWALL_PPC_FUNC_INT_STA_EN_ADDR(base, apbmuxId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_FUNC_INT_STA_EN_OFFSET) /** \brief The offset address of the interrupt signal register. */ #define FIREWALL_PPC_FUNC_INT_SIG_EN_OFFSET ((uint32_t)0x6f8U) /** \brief The bit mask of enabling the register error interrupt signal. */ #define FIREWALL_PPC_FUNC_INT_SIG_EN_REG_RES_ERR (1UL << 1) /** \brief The bit mask of enabling the peripheral error interrupt signal. */ #define FIREWALL_PPC_FUNC_INT_SIG_EN_PER_RES_ERR (1UL) /** \brief The address of the interrupt signal register for different apbmuxs. */ #define FIREWALL_PPC_FUNC_INT_SIG_EN_ADDR(base, apbmuxId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_FUNC_INT_SIG_EN_OFFSET) /** \brief The offset address of the response error disable register. */ #define FIREWALL_PPC_PESP_ERR_DIS_OFFSET ((uint32_t)0x6fcU) /** \brief The bit mask of locking the response error disable register. */ #define FIREWALL_PPC_PESP_ERR_LOCK (1UL << 31U) /** \brief The bit mask of enabling the response error disable feature. */ #define FIREWALL_PPC_PESP_ERR_DIS_ENABLE (1UL) /** \brief The address of the response error disable register. */ #define FIREWALL_PPC_PESP_ERR_DIS_ADDR(base, apbmuxId) \ ((uint32_t)(base) + FIREWALL_PPC_APBMUX_OFFSET + \ (FIREWALL_PPC_APBMUX_SIZE * ((uint32_t)(apbmuxId))) + \ FIREWALL_PPC_PESP_ERR_DIS_OFFSET) /** \brief The offset bit of privilege mode permission for domain0. */ #define FIREWALL_PPC_DOM0_PRIVILEGED_BIT (4U) /** \brief The offset bit of user mode permission for domain0. */ #define FIREWALL_PPC_DOM0_USER_BIT (6U) /** \brief The offset bit of privilege mode permission for domain1. */ #define FIREWALL_PPC_DOM1_PRIVILEGED_BIT (12U) /** \brief The offset bit of user mode permission for domain1. */ #define FIREWALL_PPC_DOM1_USER_BIT (14U) /** \brief The offset bit of privilege mode permission for domain2. */ #define FIREWALL_PPC_DOM2_PRIVILEGED_BIT (20U) /** \brief The offset bit of user mode permission for domain2. */ #define FIREWALL_PPC_DOM2_USER_BIT (22U) /** \brief The offset bit of privilege mode permission for domain3. */ #define FIREWALL_PPC_DOM3_PRIVILEGED_BIT (28U) /** \brief The offset bit of user mode permission for domain3. */ #define FIREWALL_PPC_DOM3_USER_BIT (30U) /** \brief The offset bit of privilege mode permission for domain4. */ #define FIREWALL_PPC_DOM4_PRIVILEGED_BIT (4U) /** \brief The offset bit of user mode permission for domain4. */ #define FIREWALL_PPC_DOM4_USER_BIT (6U) /** \brief The offset bit of privilege mode permission for domain5. */ #define FIREWALL_PPC_DOM5_PRIVILEGED_BIT (12U) /** \brief The offset bit of user mode permission for domain5. */ #define FIREWALL_PPC_DOM5_USER_BIT (14U) /** \brief The offset bit of privilege mode permission for domain6. */ #define FIREWALL_PPC_DOM6_PRIVILEGED_BIT (20U) /** \brief The offset bit of user mode permission for domain6. */ #define FIREWALL_PPC_DOM6_USER_BIT (22U) /** \brief The offset bit of privilege mode permission for domain7. */ #define FIREWALL_PPC_DOM7_PRIVILEGED_BIT (28U) /** \brief The offset bit of user mode permission for domain7. */ #define FIREWALL_PPC_DOM7_USER_BIT (30U) /** \brief The bit mask of locking permission configurations. */ #define FIREWALL_PPC_PERMISSION_LOCK (0xFFUL) /** \brief The bit offset of enabling the configuration of permissions. */ #define FIREWALL_PPC_RGN_EN_BIT (30U) /** \brief The width of enabling the configuration of permissions. */ #define FIREWALL_PPC_RGN_EN_WIDTH (1U) /** \brief The value of enabling the configuration of permissions. */ #define FIREWALL_PPC_RGN_EN_VALUE (1U) /** \brief The maximum number of regions in one apbmux. */ #define FIREWALL_PPC_APBMUXREGION_MAXNUM (16U) /** \brief The maximum number of regions in PPC module. */ #define FIREWALL_PPC_REGION_MAXNUM \ (FIREWALL_PPC_APBMUXREGION_MAXNUM * FIREWALL_PPC_APBMUX_MAXNUM) /** \brief Support 30 bits address. */ #define FIREWALL_PPC_ADDR(addr) ((uint32_t)(addr)&0x3FFFFFFFU) /*************************************************************************************************** * Private Function Declarations **************************************************************************************************/ #if (1U == FIREWALL_INTERRUPT_EN) static void sdrv_firewall_ppc_interrupt_enable(uint32_t base); #endif /** #if (1U == FIREWALL_INTERRUPT_EN) */ #if (1U != FIREWALL_RESPONSE_ERROR_EN) static void sdrv_firewall_ppc_err_response_disable(uint32_t base); #endif /** #if (1U != FIREWALL_RESPONSE_ERROR_EN) */ /*************************************************************************************************** * Global Function Declarations **************************************************************************************************/ /** * @brief Configure the permission of peripherals in PPC module. * * This function configure the permission of peripherals in PPC module. * The permissions of peripherals in PPC module will be locked after * configuring. This function controls the features of interrupt and error * response according to the macro configuration. * * @param[in] base the address of the MAC module. * @param[in] ppc_cfg The configuration of the apbmux IP permission. * @param[in] ip_num The number of ip. * * @return The result of the PPC initialization function * @details - return FIREWALL_E_OK : Configurate PPC ip permission success. * - return FIREWALL_E_NULL_POINTER : The pointer is a NULL_PTR. * - return FIREWALL_E_PPC_IP_NUM : The number of peripherals is * unvalid. */ status_t sdrv_firewall_ppc_ip_configure(uint32_t base, const sdrv_ppc_ip_config_t *ppc_cfg, uint16_t ip_num) { status_t ret_val = FIREWALL_E_OK; uint32_t temp_val; uint16_t num; if (NULL == ppc_cfg) { ret_val = FIREWALL_E_NULL_POINTER; } else if (FIREWALL_PPC_IP_MAXNUM < ip_num) { ret_val = FIREWALL_E_PPC_IP_NUM; } else { for (num = 0; num < ip_num; num++) { /* DOM0 all permissions is open */ temp_val = (uint32_t)FIREWALL_PERMISSION_RW << FIREWALL_PPC_DOM0_PRIVILEGED_BIT; temp_val |= (uint32_t)FIREWALL_PERMISSION_RW << FIREWALL_PPC_DOM0_USER_BIT; /* DOM1 all permission is close */ temp_val |= (uint32_t)FIREWALL_PERMISSION_NONE << FIREWALL_PPC_DOM1_PRIVILEGED_BIT; temp_val |= (uint32_t)FIREWALL_PERMISSION_NONE << FIREWALL_PPC_DOM1_USER_BIT; /* DOM2 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain2_privileged_permission << FIREWALL_PPC_DOM2_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain2_user_permission << FIREWALL_PPC_DOM2_USER_BIT; /* DOM3 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain3_privileged_permission << FIREWALL_PPC_DOM3_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain3_user_permission << FIREWALL_PPC_DOM3_USER_BIT; /* DOM0 ~ DOM3 permission set */ writel(temp_val, FIREWALL_PPC_DOMPER0_ADDR( base, (uint32_t)ppc_cfg[num].ppc_apbmux_id, (uint32_t)ppc_cfg[num].ppc_apbmux_ip_id)); /* DOM4 permission */ temp_val = (uint32_t)ppc_cfg[num].domain4_privileged_permission << FIREWALL_PPC_DOM4_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain4_user_permission << FIREWALL_PPC_DOM4_USER_BIT; /* DOM5 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain5_privileged_permission << FIREWALL_PPC_DOM5_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain5_user_permission << FIREWALL_PPC_DOM5_USER_BIT; /* DOM6 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain6_permission << FIREWALL_PPC_DOM6_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain6_permission << FIREWALL_PPC_DOM6_USER_BIT; /* DOM7 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain7_privileged_permission << FIREWALL_PPC_DOM7_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain7_user_permission << FIREWALL_PPC_DOM7_USER_BIT; /* DOM4 ~ DOM7 permission set */ writel(temp_val, FIREWALL_PPC_DOMPER1_ADDR( base, (uint32_t)ppc_cfg[num].ppc_apbmux_id, (uint32_t)ppc_cfg[num].ppc_apbmux_ip_id)); } } #if (1U == FIREWALL_INTERRUPT_EN) /* #30 Turn on inturrupt when illegal access. */ sdrv_firewall_ppc_interrupt_enable(base); #endif /** #if (1U == FIREWALL_INTERRUPT_EN) */ #if (1U != FIREWALL_RESPONSE_ERROR_EN) /* #40 Disable respone error when illegal access. */ sdrv_firewall_ppc_err_response_disable(base); #endif /** #if (1U != FIREWALL_RESPONSE_ERROR_EN) */ return ret_val; } /** * @brief Configure the permission of peripherals' regions in PPC module. * * This function configure the permission of peripherals' regions in PPC module. * The permissions of regions will be locked after configuring. * This function controls the features of interrupt and error response according * to the macro configuration. * * @param[in] base the address of the MAC module. * @param[in] ppc_cfg The configuration of the apbmux addr permission. * @param[in] region_num The number of address region. * * @return The result of the PPC initialization function * @details - return FIREWALL_E_OK : Configurate PPC ip permission success. * - return FIREWALL_E_NULL_POINTER : The pointer is a NULL_PTR. * - return FIREWALL_E_PPC_REGION_NUM : The number of peripherals' * regions is unvalid. */ status_t sdrv_firewall_ppc_addr_configure( uint32_t base, const sdrv_ppc_region_config_t *ppc_cfg, uint16_t region_num) { status_t ret_val = FIREWALL_E_OK; uint16_t num = 0U; uint16_t region_maxnum = 0U; uint32_t temp_val; if (NULL == ppc_cfg) { ret_val = FIREWALL_E_NULL_POINTER; } else if (FIREWALL_PPC_REGION_MAXNUM < region_num) { ret_val = FIREWALL_E_PPC_REGION_NUM; } else { for (num = 0; num < region_num; num++) { region_maxnum = sdrv_firewall_ppc_get_apbmux_ip_maxnum( (uint8_t)ppc_cfg[num].ppc_apbmux_id); /* DOM0 all permissions is open */ temp_val = (uint32_t)FIREWALL_PERMISSION_RW << FIREWALL_PPC_DOM0_PRIVILEGED_BIT; temp_val |= (uint32_t)FIREWALL_PERMISSION_RW << FIREWALL_PPC_DOM0_USER_BIT; /* DOM1 all permission is close */ temp_val |= (uint32_t)FIREWALL_PERMISSION_NONE << FIREWALL_PPC_DOM1_PRIVILEGED_BIT; temp_val |= (uint32_t)FIREWALL_PERMISSION_NONE << FIREWALL_PPC_DOM1_USER_BIT; /* DOM2 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain2_privileged_permission << FIREWALL_PPC_DOM2_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain2_user_permission << FIREWALL_PPC_DOM2_USER_BIT; /* DOM3 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain3_privileged_permission << FIREWALL_PPC_DOM3_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain3_user_permission << FIREWALL_PPC_DOM3_USER_BIT; /* DOM0 ~ DOM3 permission set */ writel(temp_val, FIREWALL_PPC_DOMPER0_ADDR( base, (uint32_t)ppc_cfg[num].ppc_apbmux_id, (uint32_t)ppc_cfg[num].ppc_region_index + (uint32_t)region_maxnum)); /* DOM4 permission */ temp_val = (uint32_t)ppc_cfg[num].domain4_privileged_permission << FIREWALL_PPC_DOM4_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain4_user_permission << FIREWALL_PPC_DOM4_USER_BIT; /* DOM5 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain5_privileged_permission << FIREWALL_PPC_DOM5_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain5_user_permission << FIREWALL_PPC_DOM5_USER_BIT; /* DOM6 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain6_permission << FIREWALL_PPC_DOM6_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain6_permission << FIREWALL_PPC_DOM6_USER_BIT; /* DOM7 permission */ temp_val |= (uint32_t)ppc_cfg[num].domain7_privileged_permission << FIREWALL_PPC_DOM7_PRIVILEGED_BIT; temp_val |= (uint32_t)ppc_cfg[num].domain7_user_permission << FIREWALL_PPC_DOM7_USER_BIT; /* DOM4 ~ DOM7 permission set */ writel(temp_val, FIREWALL_PPC_DOMPER1_ADDR( base, (uint32_t)ppc_cfg[num].ppc_apbmux_id, (uint32_t)ppc_cfg[num].ppc_region_index + (uint32_t)region_maxnum)); /* Configure address range */ RMWREG32( base + FIREWALL_PPC_APBMUX_OFFSET + (FIREWALL_PPC_APBMUX_SIZE * (ppc_cfg[num].ppc_apbmux_id)) + FIREWALL_PPC_RGN_START_ADDR_X( ppc_cfg[num].ppc_region_index), FIREWALL_PPC_RGN_START_ADDR_BIT, FIREWALL_PPC_RGN_START_ADDR_WIDTH, FIREWALL_PPC_ADDR(ppc_cfg[num].ppc_start_addr)); RMWREG32( base + FIREWALL_PPC_APBMUX_OFFSET + (FIREWALL_PPC_APBMUX_SIZE * (ppc_cfg[num].ppc_apbmux_id)) + FIREWALL_PPC_RGN_END_ADDR_X(ppc_cfg[num].ppc_region_index), FIREWALL_PPC_RGN_END_ADDR_BIT, FIREWALL_PPC_RGN_END_ADDR_WIDTH, FIREWALL_PPC_ADDR(ppc_cfg[num].ppc_end_addr)); /* Enable the region's configuration. */ RMWREG32( base + FIREWALL_PPC_APBMUX_OFFSET + (FIREWALL_PPC_APBMUX_SIZE * (ppc_cfg[num].ppc_apbmux_id)) + FIREWALL_PPC_RGN_END_ADDR_X(ppc_cfg[num].ppc_region_index), FIREWALL_PPC_RGN_EN_BIT, FIREWALL_PPC_RGN_EN_WIDTH, FIREWALL_PPC_RGN_EN_VALUE); } } #if (1U == FIREWALL_INTERRUPT_EN) /* #30 Turn on inturrupt when illegal access. */ sdrv_firewall_ppc_interrupt_enable(base); #endif /** #if (1U == FIREWALL_INTERRUPT_EN) */ #if (1U != FIREWALL_RESPONSE_ERROR_EN) /* #40 Disable respone error when illegal access. */ sdrv_firewall_ppc_err_response_disable(base); #endif /** #if (1U != FIREWALL_RESPONSE_ERROR_EN) */ return ret_val; } /** * @brief Locks the configurations of the PPC module. * * This function locks the permissions of all peripherals and * apb regions in the PPC module. * * @param[in] base the address of the MAC module. */ void sdrv_firewall_ppc_lock(uint32_t base) { uint32_t ip_num; uint8_t apbmux_num; uint16_t ip_maxnum; uint8_t region_num; uint32_t temp_val; /* #10 Lock the configuarions of the PPC module. */ for (apbmux_num = 0; apbmux_num < FIREWALL_PPC_APBMUX_MAXNUM; apbmux_num++) { ip_maxnum = sdrv_firewall_ppc_get_apbmux_ip_maxnum(apbmux_num); /* Lock permissions of all peripherals. */ for (ip_num = 0; ip_num < ip_maxnum; ip_num++) { writel((uint32_t)FIREWALL_PPC_PERMISSION_LOCK, FIREWALL_PPC_DOM_PER_LOCK_ADDR(base, apbmux_num, ip_num)); } /* Lock permissions of all apb regions. * Lock address range of all apb regions. */ for (region_num = 0; region_num < 16; region_num++) { temp_val = readl( FIREWALL_PPC_RGN_END_REG_ADDR(base, apbmux_num, region_num)); writel(temp_val | (uint32_t)FIREWALL_PPC_RGN_END_ADDR_LOCK, FIREWALL_PPC_RGN_END_REG_ADDR(base, apbmux_num, region_num)); writel((uint32_t)FIREWALL_PPC_PERMISSION_LOCK, FIREWALL_PPC_DOM_PER_LOCK_ADDR( base, apbmux_num, (uint32_t)ip_maxnum + (uint32_t)region_num)); } } } /** * @brief Get the interrupt status of the PPC module. * * This function get the illegal access error information of the PPC module. * The function exits as soon as it gets an illegal access message. * This function should be called by the firewall interrupt handler * sdrv_firewall_irq_handler(). * * @param[in] base the address of the MAC module. * * @return The illegal access error status of the PPC module. */ sdrv_ppc_irqsta_t sdrv_firewall_ppc_irq_handler(uint32_t base) { sdrv_ppc_irqsta_t irq_sta = {0U}; uint8_t apbmux_num; uint32_t sta_enable; uint32_t sig_enable; for (apbmux_num = 0; apbmux_num < FIREWALL_PPC_APBMUX_MAXNUM; ++apbmux_num) { /* Get the interrupt status of the apbmux. */ irq_sta.ppc_intr_sta = (readl(FIREWALL_PPC_FUNC_INT_STA_ADDR(base, apbmux_num)) & (FIREWALL_PPC_FUNC_INT_STA_REG_RES_ERR | FIREWALL_PPC_FUNC_INT_STA_PER_RES_ERR)); if (0U < irq_sta.ppc_intr_sta) { /* Clear the interrupt status of the apbmux. */ writel((uint32_t)irq_sta.ppc_intr_sta, FIREWALL_PPC_FUNC_INT_STA_ADDR(base, apbmux_num)); sta_enable = readl(FIREWALL_PPC_FUNC_INT_STA_EN_ADDR(base, apbmux_num)); sig_enable = readl(FIREWALL_PPC_FUNC_INT_SIG_EN_ADDR(base, apbmux_num)); if (0U == ((uint32_t)irq_sta.ppc_intr_sta & sta_enable & sig_enable)) { irq_sta.ppc_intr_sta = 0U; } else { irq_sta.ppc_apbmux_ip_id = apbmux_num; } break; } /* else not needed */ } return irq_sta; } /** * @brief Clear the interrupt status of the PPC module. * * This function clear the interrupt status of the PPC module. * * @param[in] base the base address of the MAC module. */ void sdrv_firewall_ppc_clear_interrupt(uint32_t base) { uint8_t apbmux_num; /* #10 Clear the interrupt of all apbmuxs. */ for (apbmux_num = 0U; apbmux_num < FIREWALL_PPC_APBMUX_MAXNUM; ++apbmux_num) { /* Disable the interrupt of the apbmux. */ writel(FIREWALL_REG_VALUE_MIN, FIREWALL_PPC_FUNC_INT_STA_EN_ADDR(base, apbmux_num)); /* Disable the interrupt signal of the apbmux. */ writel(FIREWALL_REG_VALUE_MIN, FIREWALL_PPC_FUNC_INT_SIG_EN_ADDR(base, apbmux_num)); /* Clear the interrupt status of the apbmux. */ writel(FIREWALL_REG_VALUE_MAX, FIREWALL_PPC_FUNC_INT_STA_ADDR(base, apbmux_num)); } } /*************************************************************************************************** * Private Function Declarations **************************************************************************************************/ #if (1U == FIREWALL_INTERRUPT_EN) /** * @brief Enable the interrupt of illegal accessing for the PPC module. * * This function should be called if FIREWALL_INTERRUPT_EN is enable. * * @param[in] base the address of the MAC module. */ static void sdrv_firewall_ppc_interrupt_enable(uint32_t base) { uint8_t apbmux_num; /* #10 Turn on inturrupt when illegal access. */ for (apbmux_num = 0; apbmux_num < FIREWALL_PPC_APBMUX_MAXNUM; ++apbmux_num) { writel(FIREWALL_PPC_FUNC_INT_STA_EN_PER_RES_ERR | FIREWALL_PPC_FUNC_INT_STA_EN_REG_RES_ERR, FIREWALL_PPC_FUNC_INT_STA_EN_ADDR(base, apbmux_num)); writel(FIREWALL_PPC_FUNC_INT_SIG_EN_PER_RES_ERR | FIREWALL_PPC_FUNC_INT_SIG_EN_REG_RES_ERR, FIREWALL_PPC_FUNC_INT_SIG_EN_ADDR(base, apbmux_num)); } } #endif /** #if (1U == FIREWALL_INTERRUPT_EN) */ #if (1U != FIREWALL_RESPONSE_ERROR_EN) /** * @brief Disable the error response feature in the PPC module. * * This function disable the error response to bus of illegal accessing to * peripherals in the PPC module. * This function should be called if FIREWALL_RESPONSE_ERROR_EN is disable. * * @param[in] base the address of the MAC module. */ static void sdrv_firewall_ppc_err_response_disable(uint32_t base) { uint8_t apbmux_num; /* #10 Disable respone error when illegal access, and lock this * configuarion. */ for (apbmux_num = 0; apbmux_num < FIREWALL_PPC_APBMUX_MAXNUM; ++apbmux_num) { /* Disable respone error. */ writel((uint32_t)FIREWALL_PPC_PESP_ERR_DIS_ENABLE, FIREWALL_PPC_PESP_ERR_DIS_ADDR(base, apbmux_num)); /* lock the configuarion. */ writel((uint32_t)FIREWALL_PPC_PESP_ERR_DIS_ENABLE | (uint32_t)FIREWALL_PPC_PESP_ERR_LOCK, FIREWALL_PPC_PESP_ERR_DIS_ADDR(base, apbmux_num)); } } #endif /** #if (1U != FIREWALL_RESPONSE_ERROR_EN) */ #ifdef __cplusplus } #endif /* End of file */