• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #ifndef HPM_PMP_DRV_H
8 #define HPM_PMP_DRV_H
9 
10 #include "hpm_common.h"
11 #include "hpm_soc_feature.h"
12 
13 /**
14  * @brief PMP Entry structure
15  */
16 typedef struct pmp_entry_struct {
17     union {
18         struct {
19             uint8_t read_access_ctrl: 1;
20             uint8_t write_access_ctrl: 1;
21             uint8_t execution_ctrl: 1;
22             uint8_t addr_matching_mode: 2;
23             uint8_t reserved: 2;
24             uint8_t lock: 1;
25         };
26         uint8_t val;
27     } pmp_cfg;
28     uint8_t reserved0[3];
29     uint32_t pmp_addr;
30 #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1))
31     union {
32         struct {
33             uint8_t entry_addr_matching_mode: 2;
34             uint8_t mem_type_attribute: 4;
35             uint8_t automic_mem_operation_ctrl: 1;
36             uint8_t reserved: 1;
37         };
38         uint8_t val;
39     } pma_cfg;
40     uint8_t reserved1[3];
41     uint32_t pma_addr;
42 #endif
43 } pmp_entry_t;
44 
45 /**
46  * @brief PMP Configuration definitions
47  */
48 #define READ_EN (1U)
49 #define READ_DIS (0U)
50 #define WRITE_EN (1U)
51 #define WRITE_DIS (0U)
52 #define EXECUTE_EN (1U)
53 #define EXECUTE_DIS (0U)
54 #define ADDR_MATCH_MODE_OFF (0U)
55 #define ADDR_MATCH_TOR (1U)
56 #define ADDR_MATCH_NAPOT (3U)
57 #define REG_LOCK (1U)
58 #define REG_UNLOCK (0U)
59 
60 /**
61  * @brief PMA Configuration definitions
62  */
63 #define MEM_TYPE_DEV_NON_BUF (0U)
64 #define MEM_TYPE_DEV_BUF (1U)
65 #define MEM_TYPE_MEM_NON_CACHE_NON_BUF (2U)
66 #define MEM_TYPE_MEM_NON_CACHE_BUF (3U)
67 #define MEM_TYPE_MEM_WT_NO_ALLOC (4U)
68 #define MEM_TYPE_MEM_WT_READ_ALLOC (5U)
69 #define MEM_TYPE_MEM_WB_NO_ALLOC (8U)
70 #define MEM_TYPE_MEM_WB_READ_ALLOC (9U)
71 #define MEM_TYPE_MEM_WB_WRITE_ALLOC (10U)
72 #define MEM_TYPE_MEM_WB_READ_WRITE_ALLOC (11U)
73 #define MEM_TYPE_EMPTY_HOLE (15U)
74 
75 #define AMO_EN (0U)
76 #define AMO_DIS (1U)
77 
78 /**
79  * @brief PMP Configuration
80  * @param r - READ Access control, valid value: READ_EN, READ_DIS
81  * @param w - Write access control, valid value: WRITE_EN, WRITE_DIS
82  * @param x - Instruction Execution control, valid value: EXECUTE_EN, EXECUTE_DIS
83  * @param m - Address matching mode, valid value:
84  *            ADDR_MATCH_MODE_OFF - Null region
85  *            ADDR_MATCH_TOR - Top of range. For pmp_addr0, any address < pmp_addr0 matches, for other regions,
86  *                             any address which meets ( pmp_addr[i-1]  <= addr < pmp_addr) matches.
87  *            ADDR_MATCH_NAPOT - Naturally aligned power-of-2 region, minimal size must be 8 bytes
88  * @param l - Write lock and permission enforcement bit for Machine mode, valid value: REG_LOCK, REG_UNLOCK
89  */
90 #define PMP_CFG(r, w, x, m, l) ((r) | ((w) << 1) | ((x) << 2) | ((m) << 3) | ((l) << 7))
91 /**
92  * @brief PMA Configuration
93  * @param m - Entry address matching mode, valid value:
94  *            ADDR_MATCH_MODE_OFF - This PMA entry is disabled
95  *            ADDR_MATCH_NAPOT - Naturally aligned power-of-2 region, the granularity is 4K bytes
96  * @param t - Memory type attributes, valid value:
97  *            MEM_TYPE_DEV_NON_BUF - Device, Non-bufferable
98  *            MEM_TYPE_DEV_BUF - Device, bufferable
99  *            MEM_TYPE_MEM_NON_CACHE_NON_BUF - Memory, Non-cacheable, Non-bufferable
100  *            MEM_TYPE_MEM_NON_CACHE_BUF - Memory, Non-cacheable, bufferable
101  *            MEM_TYPE_MEM_WT_NO_ALLOC - Memory, Write-through, No-allocate
102  *            MEM_TYPE_MEM_WT_READ_ALLOC - Memory, Write-through, read-allocate
103  *            MEM_TYPE_MEM_WB_NO_ALLOC - Memory, Write-back, No-allocate
104  *            MEM_TYPE_MEM_WB_READ_ALLOC - Memory, Write-back, Read-allocate
105  *            MEM_TYPE_MEM_WB_READ_WRITE_ALLOC - Memory, Write-back, Write-Allocate, Read-Allocate
106  *            MEM_TYPE_EMPTY_HOLE - Empty hole, nothing exists
107  *
108  * @param n - Indicate Whether Atomic Memory Operation instructions are not supported in this region, valid value:
109  *            AMO_EN - Atomic Memory Operations are supported
110  *            AMO_DIS - Atomic Memory Operations are not supported
111  */
112 #define PMA_CFG(m, t, n) ((m) | ((t) << 2) | ((n) << 6))
113 /**
114  * @brief Format Top Address Region
115  */
116 #define PMP_TOR_ADDR(addr) ((addr) >> 2)
117 /**
118  * @brief Format PMP Natural Aligned Region
119  * @param x - start address
120  * @param n - power-of-2 aligned length
121  */
122 #define PMP_NAPOT_ADDR(x, n) (((uint32_t)(x) >> 2) | (((uint32_t)(n)-1U) >> 3))
123 /**
124  * @brief Format PMA Natural Aligned Region
125  * @param x - start address
126  * @param n - power-of-2 aligned length
127  */
128 #define PMA_NAPOT_ADDR(x, n) (((uint32_t)(x) >> 2) | ((((uint32_t)(n)-1U) >> 3)))
129 
130 #ifdef __cplusplus
131 extern "C" {
132 #endif
133 /**
134  * @brief Write PMP Configuration to corresponding PMP_CFG register
135  * @param value PMP configuration
136  * @param idx  PMP entry index, valid value is 0-15
137  */
138 void write_pmp_cfg(uint32_t value, uint32_t idx);
139 
140 /**
141  * @brief Read PMP configuration
142  * @param idx PMP entry index
143  * @return PMP configuration
144  */
145 uint32_t read_pmp_cfg(uint32_t idx);
146 
147 
148 /**
149  * @brief Write PMP address to corresponding PMP_ADDR register
150  * @param value PMP address
151  * @param idx PMP address entry index, valid value is 0-15
152  */
153 void write_pmp_addr(uint32_t value, uint32_t idx);
154 
155 /**
156  * @brief Read PMP address entry
157  * @param idx PMP address entry index
158  * @return PMP address
159  */
160 uint32_t read_pmp_addr(uint32_t idx);
161 
162 #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1))
163 /**
164  * @brief Read PMA configuration
165  * @param idx PMA entry index
166  * @return PMA configuration
167  */
168 uint32_t read_pma_cfg(uint32_t idx);
169 
170 /**
171  * @brief Write PMA Configuration to corresponding PMA_CFG register
172  * @param value PMA configuration
173  * @param idx PMA entry index, valid value is 0-15
174  */
175 void write_pma_cfg(uint32_t value, uint32_t idx);
176 
177 /**
178  * @brief Write PMA address to corresponding PMA_ADDR register
179  * @param value PMA address
180  * @param idx PMA address entry index, valid value is 0-15
181  */
182 void write_pma_addr(uint32_t value, uint32_t idx);
183 
184 /**
185  * @brief Read PMA address entry
186  * @param idx PMA address entry index, valid value is 0-15
187  * @return PMA address
188  */
189 uint32_t read_pma_addr(uint32_t idx);
190 #endif /* #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1)) */
191 
192 /**
193  * @brief Configure PMP and PMA for specified PMP/PMA entry
194  *
195  * @param[in] entry PMP entry
196  * @param entry_index PMP/PMA entry index
197  * @retval status_invalid_argument  Invalid Arguments were detected
198  * @retval status_success           Configuration completed without errors
199  */
200 hpm_stat_t pmp_config_entry(const pmp_entry_t *entry, uint32_t entry_index);
201 
202 /**
203  * @brief Configure PMP and PMA based on the PMP entry list
204  * @param entry start of the PMP entry list
205  * @param num_of_entries Number of entries in the PMP entry list
206  * @retval status_invalid_argument  Invalid Arguments were detected
207  * @retval status_success           Configuration completed without errors
208  */
209 hpm_stat_t pmp_config(const pmp_entry_t *entry, uint32_t num_of_entries);
210 
211 /**
212  * @brief Disable PMP and PMA
213  */
214 void pmp_disable(void);
215 
216 #ifdef __cplusplus
217 }
218 #endif
219 
220 
221 #endif /* HPM_PMP_DRV_H */
222