pmp.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* Copyright 2018 SiFive, Inc */
  2. /* SPDX-License-Identifier: Apache-2.0 */
  3. #ifndef METAL__PMP_H
  4. #define METAL__PMP_H
  5. /*!
  6. * @file metal/pmp.h
  7. *
  8. * @brief API for Configuring Physical Memory Protection on RISC-V Cores
  9. *
  10. * The Physical Memory Protection (PMP) interface on RISC-V cores
  11. * is a form of memory protection unit which allows for a finite number
  12. * of physical memory regions to be configured with certain access
  13. * permissions.
  14. *
  15. * Additional information about the use and configuration rules for PMPs
  16. * can be found by reading the RISC-V Privileged Architecture Specification.
  17. */
  18. #include <stddef.h>
  19. #include <metal/machine.h>
  20. struct metal_pmp;
  21. /*!
  22. * @brief Set of available PMP addressing modes
  23. */
  24. enum metal_pmp_address_mode {
  25. /*! @brief Disable the PMP region */
  26. METAL_PMP_OFF = 0,
  27. /*! @brief Use Top-of-Range mode */
  28. METAL_PMP_TOR = 1,
  29. /*! @brief Use naturally-aligned 4-byte region mode */
  30. METAL_PMP_NA4 = 2,
  31. /*! @brief Use naturally-aligned power-of-two mode */
  32. METAL_PMP_NAPOT = 3
  33. };
  34. /*!
  35. * @brief Configuration for a PMP region
  36. */
  37. struct metal_pmp_config {
  38. /*! @brief Sets whether reads to the PMP region succeed */
  39. unsigned int R : 1;
  40. /*! @brief Sets whether writes to the PMP region succeed */
  41. unsigned int W : 1;
  42. /*! @brief Sets whether the PMP region is executable */
  43. unsigned int X : 1;
  44. /*! @brief Sets the addressing mode of the PMP region */
  45. enum metal_pmp_address_mode A : 2;
  46. int _pad : 2;
  47. /*! @brief Sets whether the PMP region is locked */
  48. enum metal_pmp_locked {
  49. METAL_PMP_UNLOCKED = 0,
  50. METAL_PMP_LOCKED = 1
  51. } L : 1;
  52. };
  53. /*!
  54. * @brief A handle for the PMP device
  55. */
  56. struct metal_pmp {
  57. /* The minimum granularity of the PMP region. Set by metal_pmp_init */
  58. uintptr_t _granularity[METAL_MAX_CORES];
  59. };
  60. /*!
  61. * @brief Get the PMP device handle
  62. */
  63. struct metal_pmp *metal_pmp_get_device(void);
  64. /*!
  65. * @brief Get the number of pmp regions for the hartid
  66. */
  67. int metal_pmp_num_regions(int hartid);
  68. /*!
  69. * @brief Initialize the PMP
  70. * @param pmp The PMP device handle to be initialized
  71. *
  72. * The PMP initialization routine is optional and may be called as many times
  73. * as is desired. The effect of the initialization routine is to attempt to set
  74. * all regions to unlocked and disabled, as well as to clear the X, W, and R
  75. * bits. Only the pmp configuration of the hart which executes the routine will
  76. * be affected.
  77. *
  78. * If any regions are fused to preset values by the implementation or locked,
  79. * those PMP regions will silently remain uninitialized.
  80. */
  81. void metal_pmp_init(struct metal_pmp *pmp);
  82. /*!
  83. * @brief Configure a PMP region
  84. * @param pmp The PMP device handle
  85. * @param region The PMP region to configure
  86. * @param config The desired configuration of the PMP region
  87. * @param address The desired address of the PMP region
  88. * @return 0 upon success
  89. */
  90. int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config config, size_t address);
  91. /*!
  92. * @brief Get the configuration for a PMP region
  93. * @param pmp The PMP device handle
  94. * @param region The PMP region to read
  95. * @param config Variable to store the PMP region configuration
  96. * @param address Variable to store the PMP region address
  97. * @return 0 if the region is read successfully
  98. */
  99. int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config *config, size_t *address);
  100. /*!
  101. * @brief Lock a PMP region
  102. * @param pmp The PMP device handle
  103. * @param region The PMP region to lock
  104. * @return 0 if the region is successfully locked
  105. */
  106. int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region);
  107. /*!
  108. * @brief Set the address for a PMP region
  109. * @param pmp The PMP device handle
  110. * @param region The PMP region to set
  111. * @param address The desired address of the PMP region
  112. * @return 0 if the address is successfully set
  113. */
  114. int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address);
  115. /*!
  116. * @brief Get the address of a PMP region
  117. * @param pmp The PMP device handle
  118. * @param region The PMP region to read
  119. * @return The address of the PMP region, or 0 if the region could not be read
  120. */
  121. size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region);
  122. /*!
  123. * @brief Set the addressing mode of a PMP region
  124. * @param pmp The PMP device handle
  125. * @param region The PMP region to set
  126. * @param mode The PMP addressing mode to set
  127. * @return 0 if the addressing mode is successfully set
  128. */
  129. int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode);
  130. /*!
  131. * @brief Get the addressing mode of a PMP region
  132. * @param pmp The PMP device handle
  133. * @param region The PMP region to read
  134. * @return The address mode of the PMP region
  135. */
  136. enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region);
  137. /*!
  138. * @brief Set the executable bit for a PMP region
  139. * @param pmp The PMP device handle
  140. * @param region The PMP region to set
  141. * @param X The desired value of the executable bit
  142. * @return 0 if the executable bit is successfully set
  143. */
  144. int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X);
  145. /*!
  146. * @brief Get the executable bit for a PMP region
  147. * @param pmp The PMP device handle
  148. * @param region The PMP region to read
  149. * @return the value of the executable bit
  150. */
  151. int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region);
  152. /*!
  153. * @brief Set the writable bit for a PMP region
  154. * @param pmp The PMP device handle
  155. * @param region The PMP region to set
  156. * @param W The desired value of the writable bit
  157. * @return 0 if the writable bit is successfully set
  158. */
  159. int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W);
  160. /*!
  161. * @brief Get the writable bit for a PMP region
  162. * @param pmp The PMP device handle
  163. * @param region The PMP region to read
  164. * @return the value of the writable bit
  165. */
  166. int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region);
  167. /*!
  168. * @brief Set the readable bit for a PMP region
  169. * @param pmp The PMP device handle
  170. * @param region The PMP region to set
  171. * @param R The desired value of the readable bit
  172. * @return 0 if the readable bit is successfully set
  173. */
  174. int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R);
  175. /*!
  176. * @brief Set the readable bit for a PMP region
  177. * @param pmp The PMP device handle
  178. * @param region The PMP region to read
  179. * @return the value of the readable bit
  180. */
  181. int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region);
  182. #endif