/*
 * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "mpc_sie_drv.h"

#include <stddef.h>
#include <stdbool.h>

#include "cmsis_compiler.h"

/* Values for hardware version in PIDR0 reg */
#define SIE200      0x60
#define SIE300      0x65

#define MPC_SIE_BLK_CFG_OFFSET  5U

/* Defines with numbering (eg: SIE300) are only relevant to the given SIE
 * version. Defines without the numbering are applicable to all SIE versions.
 */

/* CTRL register bit indexes */
#define MPC_SIE200_CTRL_SEC_RESP      (1UL << 4UL)  /* MPC fault triggers a
                                                     * bus error
                                                     */
#define MPC_SIE300_CTRL_GATE_REQ      (1UL << 6UL)  /* Request for gating
                                                     * incoming transfers
                                                     */
#define MPC_SIE300_CTRL_GATE_ACK      (1UL << 7UL)  /* Acknowledge for gating
                                                     * incoming transfers
                                                     */
#define MPC_SIE_CTRL_AUTOINCREMENT    (1UL << 8UL)  /* BLK_IDX auto increment */
#define MPC_SIE300_CTRL_SEC_RESP      (1UL << 16UL) /* Response type when SW
                                                     * asks to gate the transfer
                                                     */
#define MPC_SIE300_CTRL_GATE_PRESENT  (1UL << 23UL) /* Gating feature present */
#define MPC_SIE_CTRL_SEC_LOCK_DOWN    (1UL << 31UL) /* MPC Security lock down */

/* PIDR register bit masks */
#define MPC_PIDR0_SIE_VERSION_MASK    ((1UL << 8UL) - 1UL)

/* ARM MPC interrupt */
#define MPC_SIE_INT_BIT               (1UL)

/* Error code returned by the internal driver functions */
enum mpc_sie_intern_error_t {
    MPC_SIE_INTERN_ERR_NONE = MPC_SIE_ERR_NONE,
    MPC_SIE_INTERN_ERR_NOT_IN_RANGE = MPC_SIE_ERR_NOT_IN_RANGE,
    MPC_SIE_INTERN_ERR_NOT_ALIGNED = MPC_SIE_ERR_NOT_ALIGNED,
    MPC_SIE_INTERN_ERR_INVALID_RANGE = MPC_SIE_ERR_INVALID_RANGE,
    MPC_INTERN_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE =
                                   MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE,
    /* Calculated block index
     * is higher than the maximum allowed by the MPC. It should never
     * happen unless the controlled ranges of the MPC are misconfigured
     * in the driver or if the IP has not enough LUTs to cover the
     * range, due to wrong reported block size for example.
     */
    MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH = -1,

};

/* ARM MPC memory mapped register access structure */
struct mpc_sie_reg_map_t {
    volatile uint32_t ctrl;       /* (R/W) MPC Control */
    volatile uint32_t reserved[3];/* Reserved */
    volatile uint32_t blk_max;    /* (R/ ) Maximum value of block based index */
    volatile uint32_t blk_cfg;    /* (R/ ) Block configuration */
    volatile uint32_t blk_idx;    /* (R/W) Index value for accessing block
                                   *       based look up table
                                   */
    volatile uint32_t blk_lutn;   /* (R/W) Block based gating
                                   *       Look Up Table (LUT)
                                   */
    volatile uint32_t int_stat;   /* (R/ ) Interrupt state */
    volatile uint32_t int_clear;  /* ( /W) Interrupt clear */
    volatile uint32_t int_en;     /* (R/W) Interrupt enable */
    volatile uint32_t int_info1;  /* (R/ ) Interrupt information 1 */
    volatile uint32_t int_info2;  /* (R/ ) Interrupt information 2 */
    volatile uint32_t int_set;    /* ( /W) Interrupt set. Debug purpose only */
    volatile uint32_t reserved2[998]; /* Reserved */
    volatile uint32_t pidr4;      /* (R/ ) Peripheral ID 4 */
    volatile uint32_t pidr5;      /* (R/ ) Peripheral ID 5 */
    volatile uint32_t pidr6;      /* (R/ ) Peripheral ID 6 */
    volatile uint32_t pidr7;      /* (R/ ) Peripheral ID 7 */
    volatile uint32_t pidr0;      /* (R/ ) Peripheral ID 0 */
    volatile uint32_t pidr1;      /* (R/ ) Peripheral ID 1 */
    volatile uint32_t pidr2;      /* (R/ ) Peripheral ID 2 */
    volatile uint32_t pidr3;      /* (R/ ) Peripheral ID 3 */
    volatile uint32_t cidr0;      /* (R/ ) Component ID 0 */
    volatile uint32_t cidr1;      /* (R/ ) Component ID 1 */
    volatile uint32_t cidr2;      /* (R/ ) Component ID 2 */
    volatile uint32_t cidr3;      /* (R/ ) Component ID 3 */
};

/*
 * Checks if the address is controlled by the MPC and returns
 * the range index in which it is contained.
 *
 * \param[in]  dev         MPC device to initialize \ref mpc_sie_dev_t
 * \param[in]  addr        Address to check if it is controlled by MPC.
 * \param[out] addr_range  Range index in which it is contained.
 *
 * \return True if the base is controller by the range list, false otherwise.
 */
static uint32_t is_ctrl_by_range_list(
                            struct mpc_sie_dev_t* dev,
                            uint32_t addr,
                            const struct mpc_sie_memory_range_t** addr_range)
{
    uint32_t i;
    const struct mpc_sie_memory_range_t* range;

    for(i = 0; i < dev->data->nbr_of_ranges; i++) {
        range = dev->data->range_list[i];
        if(addr >= range->base && addr <= range->limit) {
            *addr_range = range;
            return 1;
        }
    }
    return 0;
}

/*
 * Gets the masks selecting the bits in the LUT of the MPC corresponding
 * to the base address (included) up to the limit address (included)
 *
 * \param[in]   mpc_dev          The MPC device.
 * \param[in]   base             Address in a range controlled by this MPC
 *                               (included), aligned on block size.
 * \param[in]   limit            Address in a range controlled by this MPC
 *                               (included), aligned on block size.
 * \param[out]  range            Memory range in which the base address and
 *                               limit are.
 * \param[out]  first_word_idx   Index of the first touched word in the LUT.
 * \param[out]  nr_words         Number of words used in the LUT. If 1, only
 *                               first_word_mask is valid and limit_word_mask
 *                               must not be used.
 * \param[out]  first_word_mask  First word mask in the LUT will be stored here.
 * \param[out]  limit_word_mask  Limit word mask in the LUT will be stored here.
 *
 * \return Returns error code as specified in \ref mpc_sie_intern_error_t
 */
static enum mpc_sie_intern_error_t get_lut_masks(
                                 struct mpc_sie_dev_t* dev,
                                 const uint32_t base, const uint32_t limit,
                                 const struct mpc_sie_memory_range_t** range,
                                 uint32_t *first_word_idx,
                                 uint32_t *nr_words,
                                 uint32_t *first_word_mask,
                                 uint32_t *limit_word_mask)
{
    const struct mpc_sie_memory_range_t* base_range;
    uint32_t block_size;
    uint32_t base_block_idx;
    uint32_t base_word_idx;
    uint32_t blk_max;
    const struct mpc_sie_memory_range_t* limit_range;
    uint32_t limit_block_idx;
    uint32_t limit_word_idx;
    uint32_t mask;
    uint32_t norm_base;
    uint32_t norm_limit;
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    /*
     * Check that the addresses are within the controlled regions
     * of this MPC
     */
    if(!is_ctrl_by_range_list(dev, base, &base_range) ||
       !is_ctrl_by_range_list(dev, limit, &limit_range)) {
        return MPC_SIE_INTERN_ERR_NOT_IN_RANGE;
    }

    /* Base and limit should be part of the same range */
    if(base_range != limit_range) {
        return MPC_SIE_INTERN_ERR_INVALID_RANGE;
    }
    *range = base_range;

    block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET));

    /* Base and limit+1 addresses must be aligned on the MPC block size */
    if(base % block_size || (limit+1) % block_size) {
        return MPC_SIE_INTERN_ERR_NOT_ALIGNED;
    }

    /*
     * Get a normalized address that is an offset from the beginning
     * of the lowest range controlled by the MPC
     */
    norm_base  = (base - base_range->base) + base_range->range_offset;
    norm_limit = (limit - base_range->base) + base_range->range_offset;

    /*
     * Calculate block index and to which 32 bits word it belongs
     */
    limit_block_idx = norm_limit/block_size;
    limit_word_idx = limit_block_idx/32;

    base_block_idx = norm_base/block_size;
    base_word_idx = base_block_idx/32;

    if(base_block_idx > limit_block_idx) {
        return MPC_SIE_INTERN_ERR_INVALID_RANGE;
    }

    /* Transmit the information to the caller */
    *nr_words = limit_word_idx - base_word_idx + 1;
    *first_word_idx = base_word_idx;

    /* Limit to the highest block that can be configured */
    blk_max = p_mpc->blk_max;

    if((limit_word_idx > blk_max) || (base_word_idx > blk_max)) {
        return MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH;
    }

    /*
     * Create the mask for the first word to only select the limit N bits
     */
    *first_word_mask = ~((1 << (base_block_idx % 32)) - 1);

    /*
     * Create the mask for the limit word to select only the first M bits.
     */
    *limit_word_mask = (1 << ((limit_block_idx+1) % 32)) - 1;
    /*
     * If limit_word_mask is 0, it means that the limit touched block index is
     * the limit in its word, so the limit word mask has all its bits selected
     */
    if(*limit_word_mask == 0) {
        *limit_word_mask = 0xFFFFFFFF;
    }

    /*
     * If the blocks to configure are all packed in one word, only
     * touch this word.
     * Code using the computed masks should test if this mask
     * is non-zero, and if so, only use this one instead of the limit_word_mask
     * and first_word_mask.
     * As the only bits that are the same in both masks are the 1 that we want
     * to select, just use XOR to extract them.
     */
    if(base_word_idx == limit_word_idx) {
        mask = ~(*first_word_mask ^ *limit_word_mask);
        *first_word_mask = mask;
        *limit_word_mask = mask;
    }

    return MPC_SIE_INTERN_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_init(struct mpc_sie_dev_t* dev,
                            const struct mpc_sie_memory_range_t** range_list,
                            uint8_t nbr_of_ranges)
{
    if((range_list == NULL) || (nbr_of_ranges == 0)) {
        return MPC_SIE_INVALID_ARG;
    }

    dev->data->sie_version = get_sie_version(dev);

    if ((dev->data->sie_version != SIE200) &&
        (dev->data->sie_version != SIE300)) {
        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
    }

    dev->data->range_list = range_list;
    dev->data->nbr_of_ranges = nbr_of_ranges;
    dev->data->is_initialized = true;

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t* dev,
                                            uint32_t* blk_size)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    if(blk_size == 0) {
        return MPC_SIE_INVALID_ARG;
    }

    /* Calculate the block size in byte according to the manual */
    *blk_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET));

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t* dev,
                                           const uint32_t base,
                                           const uint32_t limit,
                                           enum mpc_sie_sec_attr_t attr)
{
    enum mpc_sie_intern_error_t error;
    uint32_t first_word_idx;
    uint32_t first_word_mask;
    uint32_t i;
    uint32_t limit_word_mask;
    uint32_t limit_word_idx;
    uint32_t nr_words;
    const struct mpc_sie_memory_range_t* range;
    uint32_t word_value;
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    /* Get the bitmasks used to select the bits in the LUT */
    error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words,
                          &first_word_mask, &limit_word_mask);

    limit_word_idx = first_word_idx + nr_words - 1;

    if(error != MPC_SIE_INTERN_ERR_NONE) {
        /* Map internal error code lower than 0 to a generic errpr */
        if(error < 0) {
            return MPC_SIE_ERR_INVALID_RANGE;
        }
        return (enum mpc_sie_error_t)error;
    }

    /*
     * The memory range should allow accesses in with the wanted security
     * attribute if it requires special attribute for successful accesses
     */
    if(range->attr != attr) {
        return MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE;
    }

    /*
     * Starts changing actual configuration so issue DMB to ensure every
     * transaction has completed by now
     */
    __DMB();

    /* Set the block index to the first word that will be updated */
    p_mpc->blk_idx = first_word_idx;

    /* If only one word needs to be touched in the LUT */
    if(nr_words == 1) {
        word_value = p_mpc->blk_lutn;
        if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
            word_value |= first_word_mask;
        } else {
            word_value &= ~first_word_mask;
        }

        /*
         * Set the index again because full word read or write could have
         * incremented it
         */
        p_mpc->blk_idx = first_word_idx;
        p_mpc->blk_lutn = word_value;

        /* Commit the configuration change */
        __DSB();
        __ISB();

        return MPC_SIE_ERR_NONE;
    }

    /* First word */
    word_value = p_mpc->blk_lutn;
    if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
        word_value |= first_word_mask;
    } else {
        word_value &= ~first_word_mask;
    }
    /*
     * Set the index again because full word read or write could have
     * incremented it
     */
    p_mpc->blk_idx = first_word_idx;
    /* Partially configure the first word */
    p_mpc->blk_lutn = word_value;

    /* Fully configure the intermediate words if there are any */
    for(i=first_word_idx+1; i<limit_word_idx; i++) {
        p_mpc->blk_idx = i;
        if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
            p_mpc->blk_lutn = 0xFFFFFFFF;
        } else {
            p_mpc->blk_lutn = 0x00000000;
        }
    }

    /* Partially configure the limit word */
    p_mpc->blk_idx = limit_word_idx;
    word_value = p_mpc->blk_lutn;
    if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
        word_value |= limit_word_mask;
    } else {
        word_value &= ~limit_word_mask;
    }
    p_mpc->blk_idx = limit_word_idx;
    p_mpc->blk_lutn = word_value;

    /* Commit the configuration change */
    __DSB();
    __ISB();

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_get_region_config(
                                               struct mpc_sie_dev_t* dev,
                                               uint32_t base, uint32_t limit,
                                               enum mpc_sie_sec_attr_t* attr)
{
    enum mpc_sie_sec_attr_t attr_prev;
    uint32_t block_size;
    uint32_t block_size_mask;
    enum mpc_sie_intern_error_t error;
    uint32_t first_word_idx;
    uint32_t first_word_mask;
    uint32_t i;
    uint32_t limit_word_idx;
    uint32_t limit_word_mask;
    uint32_t nr_words;
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
    const struct mpc_sie_memory_range_t* range;
    uint32_t word_value;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    if(attr == 0) {
        return MPC_SIE_INVALID_ARG;
    }

    /*
     * Initialize the security attribute to mixed in case of early
     * termination of this function. A caller that does not check the
     * returned error will act as if it does not know anything about the
     * region queried, which is the safest bet
     */
    *attr = MPC_SIE_SEC_ATTR_MIXED;

    /*
     * If the base and limit are not aligned, align them and make sure
     * that the resulting region fully includes the original region
     */
    block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET));

    block_size_mask = block_size - 1;
    base &= ~(block_size_mask);
    limit &= ~(block_size_mask);
    limit += block_size - 1; /* Round to the upper block address,
                              * and then remove one to get the preceding
                              * address.
                              */

    /* Get the bitmasks used to select the bits in the LUT */
    error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words,
                          &first_word_mask, &limit_word_mask);

    limit_word_idx = first_word_idx+nr_words - 1;

    if(error != MPC_SIE_INTERN_ERR_NONE) {
        /* Map internal error code lower than 0 to generic error */
        if(error < 0) {
            return MPC_SIE_ERR_INVALID_RANGE;
        }
        return (enum mpc_sie_error_t)error;
    }

    /* Set the block index to the first word that will be updated */
    p_mpc->blk_idx = first_word_idx;

    /* If only one word needs to be touched in the LUT */
    if(nr_words == 1) {
        word_value = p_mpc->blk_lutn;
        word_value &= first_word_mask;
        if(word_value == 0) {
            *attr = MPC_SIE_SEC_ATTR_SECURE;
        /*
         * If there are differences between the mask and the word value,
         * it means that the security attributes of blocks are mixed
         */
        } else if(word_value ^ first_word_mask) {
            *attr = MPC_SIE_SEC_ATTR_MIXED;
        } else {
            *attr = MPC_SIE_SEC_ATTR_NONSECURE;
        }
        return MPC_SIE_ERR_NONE;
    }

    /* Get the partial configuration of the first word */
    word_value = p_mpc->blk_lutn & first_word_mask;
    if(word_value == 0x00000000) {
        *attr = MPC_SIE_SEC_ATTR_SECURE;
    } else if(word_value ^ first_word_mask) {
        *attr = MPC_SIE_SEC_ATTR_MIXED;
        /*
         * Bail out as the security attribute will be the same regardless
         * of the configuration of other blocks
         */
        return MPC_SIE_ERR_NONE;
    } else {
        *attr = MPC_SIE_SEC_ATTR_NONSECURE;
    }
    /*
     * Store the current found attribute, to check that all the blocks indeed
     * have the same security attribute.
     */
    attr_prev = *attr;

    /* Get the configuration of the intermediate words if there are any */
    for(i=first_word_idx+1; i<limit_word_idx; i++) {
        p_mpc->blk_idx = i;
        word_value = p_mpc->blk_lutn;
        if(word_value == 0x00000000) {
            *attr = MPC_SIE_SEC_ATTR_SECURE;
        } else if(word_value == 0xFFFFFFFF) {
            *attr = MPC_SIE_SEC_ATTR_NONSECURE;
        } else {
            *attr = MPC_SIE_SEC_ATTR_MIXED;
            return MPC_SIE_ERR_NONE;
        }

        /* If the attribute is different than the one found before, bail out */
        if(*attr != attr_prev) {
            *attr = MPC_SIE_SEC_ATTR_MIXED;
            return MPC_SIE_ERR_NONE;
        }
        attr_prev = *attr;
    }

    /* Get the partial configuration of the limit word */
    p_mpc->blk_idx = limit_word_idx;
    word_value = p_mpc->blk_lutn & limit_word_mask;
    if(word_value == 0x00000000) {
        *attr = MPC_SIE_SEC_ATTR_SECURE;
    } else if(word_value ^ first_word_mask) {
        *attr = MPC_SIE_SEC_ATTR_MIXED;
        return MPC_SIE_ERR_NONE;
    } else {
        *attr = MPC_SIE_SEC_ATTR_NONSECURE;
    }

    if(*attr != attr_prev) {
        *attr = MPC_SIE_SEC_ATTR_MIXED;
        return MPC_SIE_ERR_NONE;
    }

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t* dev,
                                      uint32_t* ctrl_val)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    if(ctrl_val == 0) {
        return MPC_SIE_INVALID_ARG;
    }

    *ctrl_val = p_mpc->ctrl;

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t* dev,
                                      uint32_t mpc_ctrl)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    p_mpc->ctrl = mpc_ctrl;

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t* dev,
                                          enum mpc_sie_sec_resp_t* sec_rep)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
    bool gating_present = false;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    if(sec_rep == NULL) {
        return MPC_SIE_INVALID_ARG;
    }

    if (dev->data->sie_version == SIE200) {
        if(p_mpc->ctrl & MPC_SIE200_CTRL_SEC_RESP) {
            *sec_rep = MPC_SIE_RESP_BUS_ERROR;
        } else {
            *sec_rep = MPC_SIE_RESP_RAZ_WI;
        }

    } else if (dev->data->sie_version == SIE300) {
        mpc_sie_is_gating_present(dev, &gating_present);
        if (!gating_present) {
            return MPC_SIE_ERR_GATING_NOT_PRESENT;
        }

        if(p_mpc->ctrl & MPC_SIE300_CTRL_SEC_RESP) {
            /* MPC returns a BUS ERROR response */
            *sec_rep = MPC_SIE_RESP_BUS_ERROR;
        } else {
            /* MPC sets the ready signals LOW, which stalls any transactions */
            *sec_rep = MPC_SIE_RESP_WAIT_GATING_DISABLED;
        }
    } else {
        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
    }

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t  mpc_sie_set_sec_resp(struct mpc_sie_dev_t* dev,
                                           enum mpc_sie_sec_resp_t sec_rep)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
    bool gating_present = false;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    if (dev->data->sie_version == SIE200) {
        if (sec_rep == MPC_SIE_RESP_BUS_ERROR) {
            p_mpc->ctrl |= MPC_SIE200_CTRL_SEC_RESP;
        } else if (sec_rep == MPC_SIE_RESP_RAZ_WI) {
            p_mpc->ctrl &= ~MPC_SIE200_CTRL_SEC_RESP;
        } else {
            return MPC_SIE_INVALID_ARG;
        }

    } else if (dev->data->sie_version == SIE300) {
        mpc_sie_is_gating_present(dev, &gating_present);
        if (!gating_present) {
            return MPC_SIE_ERR_GATING_NOT_PRESENT;
        }

        if (sec_rep == MPC_SIE_RESP_BUS_ERROR) {
            p_mpc->ctrl |= MPC_SIE300_CTRL_SEC_RESP;
        } else if (sec_rep == MPC_SIE_RESP_WAIT_GATING_DISABLED) {
            p_mpc->ctrl &= ~MPC_SIE300_CTRL_SEC_RESP;
        } else {
            return MPC_SIE_INVALID_ARG;
        }

    } else {
        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
    }

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    p_mpc->int_en |= MPC_SIE_INT_BIT;

    return MPC_SIE_ERR_NONE;
}

void mpc_sie_irq_disable(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    p_mpc->int_en &= ~MPC_SIE_INT_BIT;
}

void mpc_sie_clear_irq(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    p_mpc->int_clear = MPC_SIE_INT_BIT;
}

uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    return (p_mpc->int_stat & MPC_SIE_INT_BIT);
}

enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    p_mpc->ctrl |= (MPC_SIE_CTRL_AUTOINCREMENT
                    | MPC_SIE_CTRL_SEC_LOCK_DOWN);

    return MPC_SIE_ERR_NONE;
}

enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t* dev,
                                               bool* gating_present)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    if(dev->data->is_initialized != true) {
        return MPC_SIE_NOT_INIT;
    }

    if (dev->data->sie_version != SIE300) {
        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
    }

    *gating_present = (bool)(p_mpc->ctrl & MPC_SIE300_CTRL_GATE_PRESENT);

    return MPC_SIE_ERR_NONE;
}

uint32_t get_sie_version(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    return p_mpc->pidr0 & MPC_PIDR0_SIE_VERSION_MASK;
}

bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    return (bool)(p_mpc->ctrl & MPC_SIE300_CTRL_GATE_ACK);
}

void mpc_sie_request_gating(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    p_mpc->ctrl |= MPC_SIE300_CTRL_GATE_REQ;
}

void mpc_sie_release_gating(struct mpc_sie_dev_t* dev)
{
    struct mpc_sie_reg_map_t* p_mpc =
                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;

    p_mpc->ctrl &= ~MPC_SIE300_CTRL_GATE_REQ;
}
