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