aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/arm/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/arm/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h')
-rw-r--r--platform/ext/target/arm/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h354
1 files changed, 354 insertions, 0 deletions
diff --git a/platform/ext/target/arm/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h b/platform/ext/target/arm/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h
new file mode 100644
index 0000000000..927d0a80d5
--- /dev/null
+++ b/platform/ext/target/arm/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2016-2019 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.
+ */
+
+/**
+ * \file mpc_sie_drv.h
+ * \brief Generic driver for ARM SIE Memory Protection
+ * Controllers (MPC).
+ */
+
+#ifndef __MPC_SIE__DRV_H__
+#define __MPC_SIE__DRV_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Error code returned by the driver functions */
+enum mpc_sie_error_t {
+ MPC_SIE_ERR_NONE, /*!< No error */
+ MPC_SIE_INVALID_ARG, /*!< MPC invalid input arguments */
+ MPC_SIE_NOT_INIT, /*!< MPC not initialized */
+ MPC_SIE_ERR_NOT_IN_RANGE, /*!< Address does not belong to a range
+ * controlled by the MPC */
+ MPC_SIE_ERR_NOT_ALIGNED, /*!< Address is not aligned on the block size
+ * of this MPC
+ */
+ MPC_SIE_ERR_INVALID_RANGE, /*!< The given address range to configure
+ * is invalid. This could be because:
+ * - The base and limit swapped
+ * - The base and limit addresses
+ * are in different ranges
+ */
+ MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, /*!< The given range cannot be
+ * accessed with the wanted
+ * security attributes
+ */
+ MPC_SIE_UNSUPPORTED_HARDWARE_VERSION, /*!< MPC hardware version read from
+ * PIDR0 is not supported
+ */
+ MPC_SIE_ERR_GATING_NOT_PRESENT /*!< MPC gating not present in HW */
+};
+
+/* Security attribute used in various place of the API */
+enum mpc_sie_sec_attr_t {
+ MPC_SIE_SEC_ATTR_SECURE, /*!< Secure attribute */
+ MPC_SIE_SEC_ATTR_NONSECURE, /*!< Non-secure attribute */
+ /*!< Used when getting the configuration of a memory range and some blocks
+ * are secure whereas some other are non secure
+ */
+ MPC_SIE_SEC_ATTR_MIXED,
+};
+
+/* What can happen when trying to do an illegal memory access */
+enum mpc_sie_sec_resp_t {
+ MPC_SIE_RESP_RAZ_WI, /*!< Read As Zero, Write Ignored */
+ MPC_SIE_RESP_BUS_ERROR, /*!< Bus error */
+ MPC_SIE_RESP_WAIT_GATING_DISABLED /*!< Wait until gating is disabled */
+};
+
+/* Description of a memory range controlled by the MPC */
+struct mpc_sie_memory_range_t {
+ const uint32_t base; /*!< Base address (included in the range) */
+ const uint32_t limit; /*!< Limit address (included in the range) */
+ const uint32_t range_offset; /*!< Offset of current range area to the 0
+ * point of the whole area (the sum of the
+ * sizes of the previous memory ranges
+ * covered by the same MPC)
+ */
+ const enum mpc_sie_sec_attr_t attr; /*!< Optional security attribute
+ * needed to be matched when
+ * accessing this range.
+ * For example, the non-secure
+ * alias of a memory region can not
+ * be accessed using secure access,
+ * and configuring the MPC to
+ * secure using that range will not
+ * be permitted by the driver.
+ */
+};
+
+/* ARM MPC SIE device configuration structure */
+struct mpc_sie_dev_cfg_t {
+ const uint32_t base; /*!< MPC base address */
+};
+
+/* ARM MPC SIE device data structure */
+struct mpc_sie_dev_data_t {
+ /*!< Array of pointers to memory ranges controlled by the MPC */
+ const struct mpc_sie_memory_range_t** range_list;
+ uint8_t nbr_of_ranges; /*!< Number of memory ranges in the list */
+ bool is_initialized; /*!< Indicates if the MPC driver
+ * is initialized and enabled
+ */
+ uint32_t sie_version; /*!< SIE version */
+};
+
+/* ARM MPC SIE device structure */
+struct mpc_sie_dev_t {
+ const struct mpc_sie_dev_cfg_t* const cfg; /*!< MPC configuration */
+ struct mpc_sie_dev_data_t* const data; /*!< MPC data */
+};
+
+/**
+ * \brief Initializes a MPC device.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[in] range_list List of memory ranges controller by the MPC
+ * (\ref mpc_sie_memory_range_t). This list can not
+ * freed after the initializations.
+ * \param[in] nbr_of_ranges Number of memory ranges
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+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);
+
+/**
+ * \brief Gets MPC block size. All regions must be aligned on this block
+ * size (base address and limit+1 address).
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[out] blk_size MPC block size
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t* dev,
+ uint32_t* blk_size);
+
+/**
+ * \brief Configures a memory region (base and limit included).
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[in] base Base address of the region to poll. This bound is
+ * included. It does not need to be aligned in any way.
+ *
+ * \param[in] limit Limit address of the region to poll. This bound is
+ * included. (limit+1) does not need to be aligned
+ * in any way.
+ * \param[in] attr Security attribute of the region. If the region has mixed
+ * secure/non-secure, a special value is returned
+ * (\ref mpc_sie_sec_attr_t).
+ *
+ * In case base and limit+1 addresses are not aligned on
+ * the block size, the enclosing region with base and
+ * limit+1 aligned on block size will be queried.
+ * In case of early termination of the function (error), the
+ * security attribute will be set to MPC_SIE_ATTR_MIXED.
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+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);
+
+/**
+ * \brief Gets a memory region configuration(base and limit included).
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[in] base Base address of the region to get the configuration.
+ * \param[in] limit Limit address of the region to get the configuration.
+ * \param[out] attr Security attribute of the region
+ * \ref mpc_sie_sec_attr_t
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+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);
+
+/**
+ * \brief Gets the MPC control value.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[out] ctrl_val Current MPC control value.
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t* dev,
+ uint32_t* ctrl_val);
+
+/**
+ * \brief Sets the MPC control value.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[in] mpc_ctrl New MPC control value
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t* dev,
+ uint32_t mpc_ctrl);
+
+/**
+ * \brief Gets the configured secure response.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[out] sec_rep Configured secure response (\ref mpc_sie_sec_resp_t).
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t* dev,
+ enum mpc_sie_sec_resp_t* sec_rep);
+
+/**
+ * \brief Sets the response type when SW asks to gate the incoming transfers.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[in] sec_rep Secure response to configure (\ref mpc_sie_sec_resp_t).
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_set_sec_resp(struct mpc_sie_dev_t* dev,
+ enum mpc_sie_sec_resp_t sec_rep);
+
+/**
+ * \brief Enables MPC interrupt.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Disables MPC interrupt
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_irq_disable(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Clears MPC interrupt.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_clear_irq(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Returns the MPC interrupt state.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns 1 if the interrupt is active, 0 otherwise.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Locks down the MPC configuration.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Returns if gating is present in hardware.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ * \param[out] gating_present Returns if gating is present in hardware.
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t* dev,
+ bool* gating_present);
+
+/**
+ * \brief Returns the value of Peripheral ID 0 register.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns the value of Peripheral ID 0 register.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t get_sie_version(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Reads bit indicating acknowledge for gating incoming transfers.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \return True if acknowledge is set.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Sets bit to request for gating incoming transfers.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_request_gating(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Clears bit to request for gating incoming transfers.
+ *
+ * \param[in] dev MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_release_gating(struct mpc_sie_dev_t* dev);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MPC_SIE_DRV_H__ */