diff options
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h')
-rw-r--r-- | FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h new file mode 100644 index 000000000..9121b10a1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h @@ -0,0 +1,204 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PMP_H +#define METAL__PMP_H + +/*! + * @file metal/pmp.h + * + * @brief API for Configuring Physical Memory Protection on RISC-V Cores + * + * The Physical Memory Protection (PMP) interface on RISC-V cores + * is a form of memory protection unit which allows for a finite number + * of physical memory regions to be configured with certain access + * permissions. + * + * Additional information about the use and configuration rules for PMPs + * can be found by reading the RISC-V Privileged Architecture Specification. + */ + +#include <stddef.h> +#include <metal/machine.h> + +struct metal_pmp; + +/*! + * @brief Set of available PMP addressing modes + */ +enum metal_pmp_address_mode { + /*! @brief Disable the PMP region */ + METAL_PMP_OFF = 0, + /*! @brief Use Top-of-Range mode */ + METAL_PMP_TOR = 1, + /*! @brief Use naturally-aligned 4-byte region mode */ + METAL_PMP_NA4 = 2, + /*! @brief Use naturally-aligned power-of-two mode */ + METAL_PMP_NAPOT = 3 +}; + +/*! + * @brief Configuration for a PMP region + */ +struct metal_pmp_config { + /*! @brief Sets whether reads to the PMP region succeed */ + int R : 1; + /*! @brief Sets whether writes to the PMP region succeed */ + int W : 1; + /*! @brief Sets whether the PMP region is executable */ + int X : 1; + + /*! @brief Sets the addressing mode of the PMP region */ + enum metal_pmp_address_mode A : 2; + + int _pad : 2; + + /*! @brief Sets whether the PMP region is locked */ + enum metal_pmp_locked { + METAL_PMP_UNLOCKED = 0, + METAL_PMP_LOCKED = 1 + } L : 1; +}; + +/*! + * @brief A handle for the PMP device + */ +struct metal_pmp { + /* The minimum granularity of the PMP region. Set by metal_pmp_init */ + uintptr_t _granularity[METAL_MAX_CORES]; +}; + +/*! + * @brief Get the PMP device handle + */ +struct metal_pmp *metal_pmp_get_device(void); + +/*! + * @brief Initialize the PMP + * @param pmp The PMP device handle to be initialized + * + * The PMP initialization routine is optional and may be called as many times + * as is desired. The effect of the initialization routine is to attempt to set + * all regions to unlocked and disabled, as well as to clear the X, W, and R + * bits. Only the pmp configuration of the hart which executes the routine will + * be affected. + * + * If any regions are fused to preset values by the implementation or locked, + * those PMP regions will silently remain uninitialized. + */ +void metal_pmp_init(struct metal_pmp *pmp); + +/*! + * @brief Configure a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to configure + * @param config The desired configuration of the PMP region + * @param address The desired address of the PMP region + * @return 0 upon success + */ +int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config config, size_t address); + +/*! + * @brief Get the configuration for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @param config Variable to store the PMP region configuration + * @param address Variable to store the PMP region address + * @return 0 if the region is read successfully + */ +int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config *config, size_t *address); + +/*! + * @brief Lock a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to lock + * @return 0 if the region is successfully locked + */ +int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the address for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param address The desired address of the PMP region + * @return 0 if the address is successfully set + */ +int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address); + +/*! + * @brief Get the address of a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return The address of the PMP region, or 0 if the region could not be read + */ +size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the addressing mode of a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param mode The PMP addressing mode to set + * @return 0 if the addressing mode is successfully set + */ +int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode); + +/*! + * @brief Get the addressing mode of a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return The address mode of the PMP region + */ +enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the executable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param X The desired value of the executable bit + * @return 0 if the executable bit is successfully set + */ +int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X); + +/*! + * @brief Get the executable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the executable bit + */ +int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the writable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param W The desired value of the writable bit + * @return 0 if the writable bit is successfully set + */ +int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W); + +/*! + * @brief Get the writable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the writable bit + */ +int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the readable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param R The desired value of the readable bit + * @return 0 if the readable bit is successfully set + */ +int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R); + +/*! + * @brief Set the readable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the readable bit + */ +int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region); + +#endif |