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