/** ************************************************************************************************ * 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.c * \brief SSDK Firewall Driver * * *
Date Version *
2023/11/29 1.0.0 *
**************************************************************************************************/ #ifdef __cplusplus extern "C" { #endif /*************************************************************************************************** * Include header files **************************************************************************************************/ #include "irq.h" #include "sdrv_firewall.h" #include "sdrv_firewall_gpio.h" #include "sdrv_firewall_mac.h" #include "sdrv_firewall_mpc.h" #include "sdrv_firewall_ppc.h" #include "string.h" /*************************************************************************************************** * Global Function Declarations **************************************************************************************************/ /** * @brief Configure the firewall. * * Driver Module Initialization function.The Initialization function shall * initialize MAC/MPC/PPC/GPIO registers with the values of the structure * referenced by the parameter ConfigPtr. * * @param[in] ctrl the firewall instance. * @param[in] cfg the configuration of the MAC/MPC/PPC/GPIO module. * * @return The result of the firewall initialization function * @details - return FIREWALL_E_OK : Initializa firewall success. * - return error code : Please refer to sdrv_firewall_err_status_e. */ status_t sdrv_firewall_init(sdrv_firewall_t *ctrl, const sdrv_firewall_cfg_t *cfg) { status_t ret_val; /* #10 Check the parameters. */ if ((NULL == ctrl) || (NULL == cfg)) { ret_val = FIREWALL_E_NULL_POINTER; } /* #20 Check the status of Firewall driver. */ else if (FIREWALL_UNINIT != ctrl->init_status) { ret_val = FIREWALL_E_INIT; } /* #30 Initialize the Firewall module. */ else { /* Configure the Firewall MAC module. */ ret_val = sdrv_firewall_mac_configure(ctrl->base, cfg->mac_cfg); /* Configure the Firewall MPC module. */ if ((FIREWALL_E_OK == ret_val) && (0U < cfg->memport_num)) { ret_val = sdrv_firewall_mpc_configure( ctrl->base, cfg->mpc_cfg, cfg->memport_num); } /* else not needed */ /* Configure the Firewall PPC IP. */ if ((FIREWALL_E_OK == ret_val) && (0U < cfg->ip_num)) { ret_val = sdrv_firewall_ppc_ip_configure( ctrl->base, cfg->ppc_ip_cfg, cfg->ip_num); } /* else not needed */ /* Configure the Firewall PPC Region. */ if ((FIREWALL_E_OK == ret_val) && (0U < cfg->region_num)) { ret_val = sdrv_firewall_ppc_addr_configure( ctrl->base, cfg->ppc_region_cfg, cfg->region_num); } /* else not needed */ /* Configure the Firewall GPIO module. */ if ((FIREWALL_E_OK == ret_val) && (0U < cfg->region_num)) { ret_val = sdrv_firewall_gpio_rulespace_configure(cfg->io_cfg, cfg->core_num); } /* else not needed */ /* #40 Lock the Firewall module and change the status of the firewall * instance after initialization. */ /* Lock the Firewall PPC. */ if (FIREWALL_E_OK == ret_val) { /* Lock the MPC/PPC/GPIO configurations. */ sdrv_firewall_mpc_lock(ctrl->base); sdrv_firewall_ppc_lock(ctrl->base); sdrv_firewall_gpio_rulespace_Lock(); /* Save the configuration pointer if the firewall * initialization success. */ ctrl->config = cfg; /* Switch Firewall driver status as initialized. */ ctrl->init_status = FIREWALL_INIT; /* Initializa the spin lock. */ spin_lock_init(&ctrl->spinlock); if (ctrl->irq > 0U) { irq_attach(ctrl->irq, sdrv_firewall_irq_handler, ctrl); irq_enable(ctrl->irq); } /* else not needed */ } /* else not needed */ } return ret_val; } /** * @brief Assigns the master to the specified domain. * * Assigns the specified master to a domain. * This function should be executed after the initialization function * sdrv_firewall_init(). * * @param[in] ctrl the firewall instance. * @param[in] master_id the id of the master. * @param[in] domain_id the id of the domain. * * @return The result of this function. * @details - return FIREWALL_E_OK, Assigned the master to the domain success. * - return FIREWALL_E_UNINIT: The firewall is uninitialized. * - return FIREWALL_E_MAC_MASTER_ID: The master id is unvalid. * - return FIREWALL_E_MAC_DOMAIN_ID: The domain id is unvalid. * - return FIREWALL_E_MAC_LOCKED: The domain assignment of the master * is locked. */ status_t sdrv_firewall_assign_domain(sdrv_firewall_t *ctrl, uint8_t master_id, uint8_t domain_id) { status_t ret_val; /* #10 Check the status of Firewall driver. */ if (NULL == ctrl) { ret_val = FIREWALL_E_NULL_POINTER; } else if (FIREWALL_INIT != ctrl->init_status) { ret_val = FIREWALL_E_UNINIT; } else { /* #20 Assign the master to the specified domain. */ ret_val = sdrv_firewall_mac_assign_domain(ctrl->base, master_id, domain_id); } return ret_val; } /** * @brief Lock the domain assignment of the master. * * This function lock the domain assignment of the master, should be called * after the initialization function sdrv_firewall_init() or domain assignment * function sdrv_firewall_assign_domain(). * * @param[in] ctrl the firewall instance. * * @return The result of this function. * @details - return FIREWALL_E_OK : Lock domain assignment success. * - return FIREWALL_E_INIT : The firewall is uninitialized. * - return FIREWALL_E_NULL_POINTER : The pointer to the MAC * configuration is NULL. */ status_t sdrv_firewall_lock_domain_assignment(sdrv_firewall_t *ctrl) { status_t ret_val = FIREWALL_E_OK; /* #10 Check the status of Firewall driver. */ if (NULL == ctrl) { ret_val = FIREWALL_E_NULL_POINTER; } else if (FIREWALL_INIT != ctrl->init_status) { ret_val = FIREWALL_E_UNINIT; } else { /* #20 Lock the domain assignment of the master. */ sdrv_firewall_mac_lock_domain_assignment(ctrl->base); } return ret_val; } /** * @brief Set callback function for firewall. * * @param[in] ctrl the firewall instance. * @param[in] callback the callback function. * @param[in] userdata the param of callback function. * * @return The result of this function. * @details - return FIREWALL_E_OK : Set callback function success. * - return FIREWALL_E_NULL_POINTER : The pointer to the MAC * configuration is NULL. * - return FIREWALL_E_UNINIT : The firewall is uninitialized. */ status_t sdrv_firewall_set_callback(sdrv_firewall_t *ctrl, sdrv_firewall_callback_t callback, void *userdata) { status_t ret_val = FIREWALL_E_OK; /* #10 Check the parameters. */ if (NULL == ctrl) { ret_val = FIREWALL_E_NULL_POINTER; } /* #20 Check the status of Firewall driver. */ else if (FIREWALL_INIT != ctrl->init_status) { ret_val = FIREWALL_E_UNINIT; } /* #30 Store the callback function and user's data. */ else { ctrl->callback = callback; ctrl->userdata = userdata; } return ret_val; } /** * @brief Handle firewall interrupt. * * This function clear MAC/PPC/MPC Interruption, return interrupt state. * * @param [in] irq the irq number of the firewall. * @param [in] ctrl sdrv firewall controller. * * @return The result of this function. * @details - return 0 : Handle firewall interrupt success. * - return 1 : The pointer to the MAC configuration is NULL. * - return 2 : The firewall is uninitialized. */ int sdrv_firewall_irq_handler(uint32_t irq, void *ctrl) { int ret_val = 0U; sdrv_firewall_t *firewall_ctrl = (sdrv_firewall_t *)ctrl; sdrv_ppc_irqsta_t ppc_irq_sta; sdrv_mpc_irqsta_t mpc_irq_sta = {0U}; irq_state_t ulcpsr; /* #10 Check the parameters. */ if (NULL == ctrl) { ret_val = 1U; } /* #20 Check the status of Firewall driver. */ else if (FIREWALL_INIT != firewall_ctrl->init_status) { ret_val = 2U; sdrv_firewall_ppc_clear_interrupt(FIREWALL_APB_MAC_BASE); sdrv_firewall_mpc_clear_interrupt(FIREWALL_APB_MAC_BASE); } /* #30 Check the status of MPC and PPC module. */ else { ppc_irq_sta = sdrv_firewall_ppc_irq_handler(firewall_ctrl->base); ret_val = sdrv_firewall_mpc_irq_handler(firewall_ctrl->base, firewall_ctrl->config->mpc_cfg, firewall_ctrl->config->memport_num, &mpc_irq_sta); /* #40 Enter critical region. */ ulcpsr = spin_lock_irqsave(&firewall_ctrl->spinlock); /* #50 Save the illegal access information if the firewall to a global * variable. */ firewall_ctrl->error_info.ppc_errinfo[ppc_irq_sta.ppc_apbmux_ip_id] = ppc_irq_sta; firewall_ctrl->error_info.mpc_errinfo[mpc_irq_sta.mpc_memport_id] = mpc_irq_sta; /* Exit critical region. */ spin_unlock_irqrestore(&firewall_ctrl->spinlock, ulcpsr); /* #40 Motify the user. */ if ((NULL != firewall_ctrl->callback) && ((0U != ppc_irq_sta.ppc_intr_sta) || (0U != mpc_irq_sta.mpc_intr_sta))) { firewall_ctrl->callback(firewall_ctrl, firewall_ctrl->userdata); } } /* #50 Clear the interrupt of the MAC module. */ sdrv_firewall_mac_clear_interrupt(FIREWALL_APB_MAC_BASE); return ret_val; } /** * @brief Get firewall illegal access infomation. * * Should enable the macro FIREWALL_INTERRUPT_EN. * * @param[in] ctrl the firewall instance. * @param[in] firewall_err_info Pointer to the buffer used by system to get the * information. * * @return The result of this function. * @details - return FIREWALL_E_OK : Set callback function success. * - return FIREWALL_E_NULL_POINTER : The pointer to the MAC * configuration is NULL. * - return FIREWALL_E_UNINIT : The firewall is uninitialized. */ status_t sdrv_firewall_get_error_info(sdrv_firewall_t *ctrl, sdrv_firewall_err_t *firewall_err_info) { status_t ret_val = FIREWALL_E_OK; uint8_t port_num; uint16_t ip_num; irq_state_t ulcpsr; /* #10 Check the status of Firewall driver. */ if (FIREWALL_INIT != FIREWALL_INIT) { ret_val = FIREWALL_E_UNINIT; } /* #20 Check the parameters. */ else if (NULL == firewall_err_info) { ret_val = FIREWALL_E_NULL_POINTER; } else { /* #30 Enter critical region. */ ulcpsr = spin_lock_irqsave(&ctrl->spinlock); /* #40 Get the illegal access information of the firewall from the * global variable. Clear the illegal access information of the firewall * in a global variable. */ for (ip_num = 0U; ip_num < FIREWALL_PPC_APBMUX_MAXNUM; ++ip_num) { firewall_err_info->ppc_errinfo[ip_num] = ctrl->error_info.ppc_errinfo[ip_num]; ctrl->error_info.ppc_errinfo[ip_num].ppc_apbmux_ip_id = 0U; ctrl->error_info.ppc_errinfo[ip_num].ppc_intr_sta = 0U; } for (port_num = 0U; port_num < FIREWALL_MPC_MEMPORT_MAXNUM; ++port_num) { firewall_err_info->mpc_errinfo[port_num] = ctrl->error_info.mpc_errinfo[port_num]; ctrl->error_info.mpc_errinfo[port_num].mpc_memport_id = 0U; ctrl->error_info.mpc_errinfo[port_num].mpc_intr_sta = 0U; } /* Exit critical region. */ spin_unlock_irqrestore(&ctrl->spinlock, ulcpsr); } return ret_val; } #ifdef __cplusplus } #endif /* End of file */