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