Files
E3/e3_176_ref/drivers/source/firewall/sdrv_firewall_ppc.c
2025-10-21 19:40:27 +08:00

696 lines
31 KiB
C

/** ************************************************************************************************
* 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
*
* <table>
* <tr><th>Date <th>Version
* <tr><td>2023/11/29 <td>1.0.0
* </table>
**************************************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************************************
* Include header files
**************************************************************************************************/
#include <reg.h>
#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 */