1 // Copyright 2020 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #pragma once
16
17 #include <stdbool.h>
18 #include "soc/memprot_defs.h"
19 #include "hal/memprot_types.h"
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 /**
26 * ========================================================================================
27 * === IRAM0 common
28 * ========================================================================================
29 */
memprot_ll_iram0_clear_intr(void)30 static inline void memprot_ll_iram0_clear_intr(void)
31 {
32 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_CLR);
33 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_CLR);
34 }
35
memprot_ll_iram0_get_intr_source_num(void)36 static inline uint32_t memprot_ll_iram0_get_intr_source_num(void)
37 {
38 return ETS_PMS_PRO_IRAM0_ILG_INTR_SOURCE;
39 }
40
memprot_ll_iram0_intr_ena(bool enable)41 static inline void memprot_ll_iram0_intr_ena(bool enable)
42 {
43 if (enable) {
44 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_EN);
45 } else {
46 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_EN);
47 }
48 }
49
memprot_ll_iram0_get_conf_reg(void)50 static inline uint32_t memprot_ll_iram0_get_conf_reg(void)
51 {
52 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_4_REG);
53 }
54
memprot_ll_iram0_get_fault_reg(void)55 static inline uint32_t memprot_ll_iram0_get_fault_reg(void)
56 {
57 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_5_REG);
58 }
59
memprot_ll_iram0_get_fault_op_type(uint32_t * op_type,uint32_t * op_subtype)60 static inline void memprot_ll_iram0_get_fault_op_type(uint32_t *op_type, uint32_t *op_subtype)
61 {
62 uint32_t status_bits = memprot_ll_iram0_get_fault_reg();
63 *op_type = (uint32_t)status_bits & IRAM0_INTR_ST_OP_RW_BIT;
64 *op_subtype = (uint32_t)status_bits & IRAM0_INTR_ST_OP_TYPE_BIT;
65 }
66
memprot_ll_iram0_is_assoc_intr(void)67 static inline bool memprot_ll_iram0_is_assoc_intr(void)
68 {
69 return DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_INTR) > 0;
70 }
71
memprot_ll_iram0_get_intr_ena_bit(void)72 static inline uint32_t memprot_ll_iram0_get_intr_ena_bit(void)
73 {
74 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_EN);
75 }
76
memprot_ll_iram0_get_intr_on_bit(void)77 static inline uint32_t memprot_ll_iram0_get_intr_on_bit(void)
78 {
79 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_INTR);
80 }
81
memprot_ll_iram0_get_intr_clr_bit(void)82 static inline uint32_t memprot_ll_iram0_get_intr_clr_bit(void)
83 {
84 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_CLR);
85 }
86
87 //resets automatically on CPU restart
memprot_ll_iram0_set_lock(void)88 static inline void memprot_ll_iram0_set_lock(void)
89 {
90 DPORT_WRITE_PERI_REG( DPORT_PMS_PRO_IRAM0_0_REG, DPORT_PMS_PRO_IRAM0_LOCK);
91 }
92
memprot_ll_iram0_get_lock_reg(void)93 static inline uint32_t memprot_ll_iram0_get_lock_reg(void)
94 {
95 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_0_REG);
96 }
97
memprot_ll_iram0_get_lock_bit(void)98 static inline uint32_t memprot_ll_iram0_get_lock_bit(void)
99 {
100 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_0_REG, DPORT_PMS_PRO_IRAM0_LOCK);
101 }
102
103 /**
104 * ========================================================================================
105 * === IRAM0 SRAM
106 * ========================================================================================
107 */
memprot_ll_iram0_sram_get_fault_address(void)108 static inline intptr_t memprot_ll_iram0_sram_get_fault_address(void)
109 {
110 uint32_t status_bits = memprot_ll_iram0_get_fault_reg();
111 return (intptr_t)((status_bits & IRAM0_INTR_ST_FAULTADDR_M) | IRAM0_SRAM_INTR_ST_FAULTADDR_HI);
112 }
113
memprot_ll_iram0_sram_is_intr_mine(void)114 static inline bool memprot_ll_iram0_sram_is_intr_mine(void)
115 {
116 if (memprot_ll_iram0_is_assoc_intr()) {
117 uint32_t faulting_address = (uint32_t)memprot_ll_iram0_sram_get_fault_address();
118 return faulting_address >= IRAM0_SRAM_ADDRESS_LOW && faulting_address <= IRAM0_SRAM_ADDRESS_HIGH;
119 }
120 return false;
121 }
122
123 //block 0-3
memprot_ll_iram0_sram_set_uni_block_perm(uint32_t block,bool write_perm,bool read_perm,bool exec_perm)124 static inline bool memprot_ll_iram0_sram_set_uni_block_perm(uint32_t block, bool write_perm, bool read_perm, bool exec_perm)
125 {
126 uint32_t write_bit, read_bit, exec_bit;
127
128 switch (block) {
129 case IRAM0_SRAM_UNI_BLOCK_0:
130 write_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_W;
131 read_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_R;
132 exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_F;
133 break;
134 case IRAM0_SRAM_UNI_BLOCK_1:
135 write_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_W;
136 read_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_R;
137 exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_F;
138 break;
139 case IRAM0_SRAM_UNI_BLOCK_2:
140 write_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_W;
141 read_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_R;
142 exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_F;
143 break;
144 case IRAM0_SRAM_UNI_BLOCK_3:
145 write_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_W;
146 read_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_R;
147 exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_F;
148 break;
149 default:
150 return false;
151 }
152
153 if (write_perm) {
154 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_1_REG, write_bit);
155 } else {
156 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_1_REG, write_bit);
157 }
158
159 if (read_perm) {
160 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_1_REG, read_bit);
161 } else {
162 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_1_REG, read_bit);
163 }
164
165 if (exec_perm) {
166 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_1_REG, exec_bit);
167 } else {
168 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_1_REG, exec_bit);
169 }
170
171 return true;
172 }
173
memprot_ll_iram0_sram_get_uni_block_read_bit(uint32_t block,uint32_t * read_bit)174 static inline bool memprot_ll_iram0_sram_get_uni_block_read_bit(uint32_t block, uint32_t *read_bit)
175 {
176 switch (block) {
177 case IRAM0_SRAM_UNI_BLOCK_0:
178 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_0_R);
179 break;
180 case IRAM0_SRAM_UNI_BLOCK_1:
181 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_1_R);
182 break;
183 case IRAM0_SRAM_UNI_BLOCK_2:
184 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_2_R);
185 break;
186 case IRAM0_SRAM_UNI_BLOCK_3:
187 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_3_R);
188 break;
189 default:
190 return false;
191 }
192
193 return true;
194 }
195
memprot_ll_iram0_sram_get_uni_block_write_bit(uint32_t block,uint32_t * write_bit)196 static inline bool memprot_ll_iram0_sram_get_uni_block_write_bit(uint32_t block, uint32_t *write_bit)
197 {
198 switch (block) {
199 case IRAM0_SRAM_UNI_BLOCK_0:
200 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_0_W);
201 break;
202 case IRAM0_SRAM_UNI_BLOCK_1:
203 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_1_W);
204 break;
205 case IRAM0_SRAM_UNI_BLOCK_2:
206 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_2_W);
207 break;
208 case IRAM0_SRAM_UNI_BLOCK_3:
209 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_3_W);
210 break;
211 default:
212 return false;
213 }
214
215 return true;
216 }
217
memprot_ll_iram0_sram_get_uni_block_exec_bit(uint32_t block,uint32_t * exec_bit)218 static inline bool memprot_ll_iram0_sram_get_uni_block_exec_bit(uint32_t block, uint32_t *exec_bit)
219 {
220 switch (block) {
221 case IRAM0_SRAM_UNI_BLOCK_0:
222 *exec_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_0_F);
223 break;
224 case IRAM0_SRAM_UNI_BLOCK_1:
225 *exec_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_1_F);
226 break;
227 case IRAM0_SRAM_UNI_BLOCK_2:
228 *exec_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_2_F);
229 break;
230 case IRAM0_SRAM_UNI_BLOCK_3:
231 *exec_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_3_F);
232 break;
233 default:
234 return false;
235 }
236
237 return true;
238 }
239
memprot_ll_iram0_sram_get_uni_block_sgnf_bits(uint32_t block,uint32_t * write_bit,uint32_t * read_bit,uint32_t * exec_bit)240 static inline bool memprot_ll_iram0_sram_get_uni_block_sgnf_bits(uint32_t block, uint32_t *write_bit, uint32_t *read_bit, uint32_t *exec_bit)
241 {
242 switch (block) {
243 case IRAM0_SRAM_UNI_BLOCK_0:
244 *write_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_W;
245 *read_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_R;
246 *exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_F;
247 break;
248 case IRAM0_SRAM_UNI_BLOCK_1:
249 *write_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_W;
250 *read_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_R;
251 *exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_F;
252 break;
253 case IRAM0_SRAM_UNI_BLOCK_2:
254 *write_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_W;
255 *read_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_R;
256 *exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_F;
257 break;
258 case IRAM0_SRAM_UNI_BLOCK_3:
259 *write_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_W;
260 *read_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_R;
261 *exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_F;
262 break;
263 default:
264 return false;
265 }
266
267 return true;
268 }
269
memprot_ll_iram0_sram_get_perm_uni_reg(void)270 static inline uint32_t memprot_ll_iram0_sram_get_perm_uni_reg(void)
271 {
272 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_1_REG);
273 }
274
memprot_ll_iram0_sram_get_perm_split_reg(void)275 static inline uint32_t memprot_ll_iram0_sram_get_perm_split_reg(void)
276 {
277 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_2_REG);
278 }
279
memprot_ll_iram0_sram_set_prot(uint32_t * split_addr,bool lw,bool lr,bool lx,bool hw,bool hr,bool hx)280 static inline memprot_ll_err_t memprot_ll_iram0_sram_set_prot(uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx)
281 {
282 uint32_t addr = (uint32_t)split_addr;
283
284 //sanity check: split address required above unified mgmt region & 32bit aligned
285 if (addr > IRAM0_SRAM_SPL_BLOCK_HIGH) {
286 return MEMP_LL_ERR_SPLIT_ADDR_INVALID;
287 }
288 if (addr % 0x4 != 0) {
289 return MEMP_LL_ERR_SPLIT_ADDR_UNALIGNED;
290 }
291
292 //find possible split.address in low region blocks
293 int uni_blocks_low = -1;
294 if (addr >= IRAM0_SRAM_UNI_BLOCK_0_LOW) {
295 uni_blocks_low++;
296 }
297 if (addr >= IRAM0_SRAM_UNI_BLOCK_1_LOW) {
298 uni_blocks_low++;
299 }
300 if (addr >= IRAM0_SRAM_UNI_BLOCK_2_LOW) {
301 uni_blocks_low++;
302 }
303 if (addr >= IRAM0_SRAM_UNI_BLOCK_3_LOW) {
304 uni_blocks_low++;
305 }
306
307 //unified mgmt settings per block (bits W/R/X: [11:9] bl3, [8:6] bl2, [5:3] bl1, [2:0] bl0)
308 uint32_t write_bit, read_bit, exec_bit;
309 uint32_t uni_block_perm = 0;
310
311 for (int x = 0; x < IRAM0_SRAM_TOTAL_UNI_BLOCKS; x++) {
312 if (!memprot_ll_iram0_sram_get_uni_block_sgnf_bits(x, &write_bit, &read_bit, &exec_bit)) {
313 return MEMP_LL_ERR_UNI_BLOCK_INVALID;
314 }
315 if (x <= uni_blocks_low) {
316 if (lw) {
317 uni_block_perm |= write_bit;
318 }
319 if (lr) {
320 uni_block_perm |= read_bit;
321 }
322 if (lx) {
323 uni_block_perm |= exec_bit;
324 }
325 } else {
326 if (hw) {
327 uni_block_perm |= write_bit;
328 }
329 if (hr) {
330 uni_block_perm |= read_bit;
331 }
332 if (hx) {
333 uni_block_perm |= exec_bit;
334 }
335 }
336 }
337
338 //if splt.ddr not set yet, do required normalization to make the addr writeble into splt.mgmt cfg register
339 uint32_t reg_split_addr = 0;
340
341 if (addr >= IRAM0_SRAM_SPL_BLOCK_LOW) {
342 reg_split_addr = IRAM0_SRAM_ADDR_TO_CONF_REG(addr); //cfg reg - [16:0]
343 }
344
345 //prepare high & low permission mask (bits: [22:20] high range, [19:17] low range)
346 uint32_t permission_mask = 0;
347 if (lw) {
348 permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_L_W;
349 }
350 if (lr) {
351 permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_L_R;
352 }
353 if (lx) {
354 permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_L_F;
355 }
356 if (hw) {
357 permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_H_W;
358 }
359 if (hr) {
360 permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_H_R;
361 }
362 if (hx) {
363 permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_H_F;
364 }
365
366 //write IRAM SRAM uni & splt cfg. registers
367 DPORT_WRITE_PERI_REG(DPORT_PMS_PRO_IRAM0_1_REG, uni_block_perm);
368 DPORT_WRITE_PERI_REG(DPORT_PMS_PRO_IRAM0_2_REG, (uint32_t)(reg_split_addr | permission_mask));
369
370 return MEMP_LL_OK;
371 }
372
memprot_ll_iram0_sram_get_split_sgnf_bits(bool * lw,bool * lr,bool * lx,bool * hw,bool * hr,bool * hx)373 static inline void memprot_ll_iram0_sram_get_split_sgnf_bits(bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx)
374 {
375 *lw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_W);
376 *lr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_R);
377 *lx = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_F);
378 *hw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_W);
379 *hr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_R);
380 *hx = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_F);
381 }
382
memprot_ll_iram0_sram_set_read_perm(bool lr,bool hr)383 static inline void memprot_ll_iram0_sram_set_read_perm(bool lr, bool hr)
384 {
385 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_R, lr ? 1 : 0);
386 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_R, hr ? 1 : 0);
387 }
388
memprot_ll_iram0_sram_set_write_perm(bool lw,bool hw)389 static inline void memprot_ll_iram0_sram_set_write_perm(bool lw, bool hw)
390 {
391 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_W, lw ? 1 : 0);
392 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_W, hw ? 1 : 0);
393 }
394
memprot_ll_iram0_sram_set_exec_perm(bool lx,bool hx)395 static inline void memprot_ll_iram0_sram_set_exec_perm(bool lx, bool hx)
396 {
397 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_F, lx ? 1 : 0);
398 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_F, hx ? 1 : 0);
399 }
400
401
402 /**
403 * ========================================================================================
404 * === IRAM0 RTC FAST
405 * ========================================================================================
406 */
memprot_ll_iram0_rtcfast_get_fault_address(void)407 static inline intptr_t memprot_ll_iram0_rtcfast_get_fault_address(void)
408 {
409 uint32_t status_bits = memprot_ll_iram0_get_fault_reg();
410 return (intptr_t)((status_bits & IRAM0_INTR_ST_FAULTADDR_M) | IRAM0_RTCFAST_INTR_ST_FAULTADDR_HI);
411 }
412
memprot_ll_iram0_rtcfast_is_intr_mine(void)413 static inline bool memprot_ll_iram0_rtcfast_is_intr_mine(void)
414 {
415 if (memprot_ll_iram0_is_assoc_intr()) {
416 uint32_t faulting_address = (uint32_t)memprot_ll_iram0_rtcfast_get_fault_address();
417 return faulting_address >= IRAM0_RTCFAST_ADDRESS_LOW && faulting_address <= IRAM0_RTCFAST_ADDRESS_HIGH;
418 }
419 return false;
420 }
421
memprot_ll_iram0_rtcfast_get_perm_split_reg(void)422 static inline uint32_t memprot_ll_iram0_rtcfast_get_perm_split_reg(void)
423 {
424 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_3_REG);
425 }
426
memprot_ll_iram0_rtcfast_set_prot(uint32_t * split_addr,bool lw,bool lr,bool lx,bool hw,bool hr,bool hx)427 static inline memprot_ll_err_t memprot_ll_iram0_rtcfast_set_prot(uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx)
428 {
429 uint32_t addr = (uint32_t)split_addr;
430
431 //32bit aligned
432 if (addr < IRAM0_RTCFAST_ADDRESS_LOW || addr > IRAM0_RTCFAST_ADDRESS_HIGH) {
433 return MEMP_LL_ERR_SPLIT_ADDR_INVALID;
434 }
435 if (addr % 0x4 != 0) {
436 return MEMP_LL_ERR_SPLIT_ADDR_UNALIGNED;
437 }
438
439 //conf reg [10:0]
440 uint32_t reg_split_addr = IRAM0_RTCFAST_ADDR_TO_CONF_REG(addr);
441
442 //prepare high & low permission mask (bits: [16:14] high range, [13:11] low range)
443 uint32_t permission_mask = 0;
444 if (lw) {
445 permission_mask |= DPORT_PMS_PRO_IRAM0_RTCFAST_L_W;
446 }
447 if (lr) {
448 permission_mask |= DPORT_PMS_PRO_IRAM0_RTCFAST_L_R;
449 }
450 if (lx) {
451 permission_mask |= DPORT_PMS_PRO_IRAM0_RTCFAST_L_F;
452 }
453 if (hw) {
454 permission_mask |= DPORT_PMS_PRO_IRAM0_RTCFAST_H_W;
455 }
456 if (hr) {
457 permission_mask |= DPORT_PMS_PRO_IRAM0_RTCFAST_H_R;
458 }
459 if (hx) {
460 permission_mask |= DPORT_PMS_PRO_IRAM0_RTCFAST_H_F;
461 }
462
463 //write IRAM0 RTCFAST cfg register
464 DPORT_WRITE_PERI_REG(DPORT_PMS_PRO_IRAM0_3_REG, reg_split_addr | permission_mask);
465
466 return MEMP_LL_OK;
467 }
468
memprot_ll_iram0_rtcfast_get_split_sgnf_bits(bool * lw,bool * lr,bool * lx,bool * hw,bool * hr,bool * hx)469 static inline void memprot_ll_iram0_rtcfast_get_split_sgnf_bits(bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx)
470 {
471 *lw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_L_W);
472 *lr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_L_R);
473 *lx = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_L_F);
474 *hw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_H_W);
475 *hr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_H_R);
476 *hx = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_H_F);
477 }
478
memprot_ll_iram0_rtcfast_set_read_perm(bool lr,bool hr)479 static inline void memprot_ll_iram0_rtcfast_set_read_perm(bool lr, bool hr)
480 {
481 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_L_R, lr ? 1 : 0);
482 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_H_R, hr ? 1 : 0);
483 }
484
memprot_ll_iram0_rtcfast_set_write_perm(bool lw,bool hw)485 static inline void memprot_ll_iram0_rtcfast_set_write_perm(bool lw, bool hw)
486 {
487 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_L_W, lw ? 1 : 0);
488 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_H_W, hw ? 1 : 0);
489 }
490
memprot_ll_iram0_rtcfast_set_exec_perm(bool lx,bool hx)491 static inline void memprot_ll_iram0_rtcfast_set_exec_perm(bool lx, bool hx)
492 {
493 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_L_F, lx ? 1 : 0);
494 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_IRAM0_3_REG, DPORT_PMS_PRO_IRAM0_RTCFAST_H_F, hx ? 1 : 0);
495 }
496
497
498 /**
499 * ========================================================================================
500 * === DRAM0 common
501 * ========================================================================================
502 */
memprot_ll_dram0_get_intr_source_num(void)503 static inline uint32_t memprot_ll_dram0_get_intr_source_num(void)
504 {
505 return ETS_PMS_PRO_DRAM0_ILG_INTR_SOURCE;
506 }
507
memprot_ll_dram0_intr_ena(bool enable)508 static inline void memprot_ll_dram0_intr_ena(bool enable)
509 {
510 if (enable) {
511 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_EN);
512 } else {
513 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_EN);
514 }
515 }
516
memprot_ll_dram0_is_assoc_intr(void)517 static inline bool memprot_ll_dram0_is_assoc_intr(void)
518 {
519 return DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_INTR) > 0;
520 }
521
memprot_ll_dram0_clear_intr(void)522 static inline void memprot_ll_dram0_clear_intr(void)
523 {
524 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_CLR);
525 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_CLR);
526 }
527
memprot_ll_dram0_get_intr_ena_bit(void)528 static inline uint32_t memprot_ll_dram0_get_intr_ena_bit(void)
529 {
530 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_EN);
531 }
532
memprot_ll_dram0_get_intr_on_bit(void)533 static inline uint32_t memprot_ll_dram0_get_intr_on_bit(void)
534 {
535 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_INTR);
536 }
537
memprot_ll_dram0_get_intr_clr_bit(void)538 static inline uint32_t memprot_ll_dram0_get_intr_clr_bit(void)
539 {
540 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_CLR);
541 }
542
543 //lock resets automatically on CPU restart
memprot_ll_dram0_set_lock(void)544 static inline void memprot_ll_dram0_set_lock(void)
545 {
546 DPORT_WRITE_PERI_REG(DPORT_PMS_PRO_DRAM0_0_REG, DPORT_PMS_PRO_DRAM0_LOCK);
547 }
548
memprot_ll_dram0_get_lock_reg(void)549 static inline uint32_t memprot_ll_dram0_get_lock_reg(void)
550 {
551 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_0_REG);
552 }
553
memprot_ll_dram0_get_lock_bit(void)554 static inline uint32_t memprot_ll_dram0_get_lock_bit(void)
555 {
556 return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_0_REG, DPORT_PMS_PRO_DRAM0_LOCK);
557 }
558
memprot_ll_dram0_get_conf_reg(void)559 static inline uint32_t memprot_ll_dram0_get_conf_reg(void)
560 {
561 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_3_REG);
562 }
563
memprot_ll_dram0_get_fault_reg(void)564 static inline uint32_t memprot_ll_dram0_get_fault_reg(void)
565 {
566 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_4_REG);
567 }
568
memprot_ll_dram0_get_fault_op_type(uint32_t * op_type,uint32_t * op_subtype)569 static inline void memprot_ll_dram0_get_fault_op_type(uint32_t *op_type, uint32_t *op_subtype)
570 {
571 uint32_t status_bits = memprot_ll_dram0_get_fault_reg();
572 *op_type = status_bits & DRAM0_INTR_ST_OP_RW_BIT;
573 *op_subtype = status_bits & DRAM0_INTR_ST_OP_ATOMIC_BIT;
574 }
575
576 /**
577 * ========================================================================================
578 * === DRAM0 SRAM
579 * ========================================================================================
580 */
memprot_ll_dram0_sram_get_fault_address(void)581 static inline intptr_t memprot_ll_dram0_sram_get_fault_address(void)
582 {
583 uint32_t status_bits = memprot_ll_dram0_get_fault_reg();
584 return (intptr_t)(((status_bits & DRAM0_INTR_ST_FAULTADDR_M) >> DRAM0_INTR_ST_FAULTADDR_S) | DRAM0_SRAM_INTR_ST_FAULTADDR_HI);
585 }
586
memprot_ll_dram0_sram_is_intr_mine(void)587 static inline bool memprot_ll_dram0_sram_is_intr_mine(void)
588 {
589 if (memprot_ll_dram0_is_assoc_intr()) {
590 uint32_t faulting_address = (uint32_t)memprot_ll_dram0_sram_get_fault_address();
591 return faulting_address >= DRAM0_SRAM_ADDRESS_LOW && faulting_address <= DRAM0_SRAM_ADDRESS_HIGH;
592 }
593 return false;
594 }
595
memprot_ll_dram0_sram_get_uni_block_sgnf_bits(uint32_t block,uint32_t * write_bit,uint32_t * read_bit)596 static inline bool memprot_ll_dram0_sram_get_uni_block_sgnf_bits(uint32_t block, uint32_t *write_bit, uint32_t *read_bit)
597 {
598 switch (block) {
599 case DRAM0_SRAM_UNI_BLOCK_0:
600 *write_bit = DPORT_PMS_PRO_DRAM0_SRAM_0_W;
601 *read_bit = DPORT_PMS_PRO_DRAM0_SRAM_0_R;
602 break;
603 case DRAM0_SRAM_UNI_BLOCK_1:
604 *write_bit = DPORT_PMS_PRO_DRAM0_SRAM_1_W;
605 *read_bit = DPORT_PMS_PRO_DRAM0_SRAM_1_R;
606 break;
607 case DRAM0_SRAM_UNI_BLOCK_2:
608 *write_bit = DPORT_PMS_PRO_DRAM0_SRAM_2_W;
609 *read_bit = DPORT_PMS_PRO_DRAM0_SRAM_2_R;
610 break;
611 case DRAM0_SRAM_UNI_BLOCK_3:
612 *write_bit = DPORT_PMS_PRO_DRAM0_SRAM_3_W;
613 *read_bit = DPORT_PMS_PRO_DRAM0_SRAM_3_R;
614 break;
615 default:
616 return false;
617 }
618
619 return true;
620 }
621
memprot_ll_dram0_sram_set_uni_block_perm(uint32_t block,bool write_perm,bool read_perm)622 static inline memprot_ll_err_t memprot_ll_dram0_sram_set_uni_block_perm(uint32_t block, bool write_perm, bool read_perm)
623 {
624 //get block-specific WR flags offset within the conf.register
625 uint32_t write_bit_offset, read_bit_offset;
626 if (!memprot_ll_dram0_sram_get_uni_block_sgnf_bits(block, &write_bit_offset, &read_bit_offset)) {
627 return MEMP_LL_ERR_UNI_BLOCK_INVALID;
628 }
629
630 //set/reset required flags
631 if (write_perm) {
632 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_1_REG, write_bit_offset);
633 } else {
634 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_1_REG, write_bit_offset);
635 }
636
637 if (read_perm) {
638 DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_1_REG, read_bit_offset);
639 } else {
640 DPORT_CLEAR_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_1_REG, read_bit_offset);
641 }
642
643 return MEMP_LL_OK;
644 }
645
memprot_ll_dram0_sram_get_uni_block_read_bit(uint32_t block,uint32_t * read_bit)646 static inline bool memprot_ll_dram0_sram_get_uni_block_read_bit(uint32_t block, uint32_t *read_bit)
647 {
648 switch (block) {
649 case DRAM0_SRAM_UNI_BLOCK_0:
650 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_0_R);
651 break;
652 case DRAM0_SRAM_UNI_BLOCK_1:
653 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_1_R);
654 break;
655 case DRAM0_SRAM_UNI_BLOCK_2:
656 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_2_R);
657 break;
658 case DRAM0_SRAM_UNI_BLOCK_3:
659 *read_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_3_R);
660 break;
661 default:
662 return false;
663 }
664
665 return true;
666 }
667
memprot_ll_dram0_sram_get_uni_block_write_bit(uint32_t block,uint32_t * write_bit)668 static inline bool memprot_ll_dram0_sram_get_uni_block_write_bit(uint32_t block, uint32_t *write_bit)
669 {
670 switch (block) {
671 case DRAM0_SRAM_UNI_BLOCK_0:
672 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_0_W);
673 break;
674 case DRAM0_SRAM_UNI_BLOCK_1:
675 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_1_W);
676 break;
677 case DRAM0_SRAM_UNI_BLOCK_2:
678 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_2_W);
679 break;
680 case DRAM0_SRAM_UNI_BLOCK_3:
681 *write_bit = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_3_W);
682 break;
683 default:
684 return false;
685 }
686
687 return true;
688 }
689
690 //DRAM0 has both unified blocks and split address configured in 1 register
memprot_ll_dram0_sram_get_perm_reg(void)691 static inline uint32_t memprot_ll_dram0_sram_get_perm_reg(void)
692 {
693 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_1_REG);
694 }
695
memprot_ll_dram0_sram_set_prot(uint32_t * split_addr,bool lw,bool lr,bool hw,bool hr)696 static inline memprot_ll_err_t memprot_ll_dram0_sram_set_prot(uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr)
697 {
698 uint32_t addr = (uint32_t)split_addr;
699
700 //low boundary check provided by LD script. see comment in memprot_ll_iram0_sram_set_prot()
701 if (addr > DRAM0_SRAM_SPL_BLOCK_HIGH) {
702 return MEMP_LL_ERR_SPLIT_ADDR_INVALID;
703 }
704 if (addr % 0x4 != 0) {
705 return MEMP_LL_ERR_SPLIT_ADDR_UNALIGNED;
706 }
707
708 //set low region
709 int uni_blocks_low = -1;
710 if (addr >= DRAM0_SRAM_UNI_BLOCK_0_LOW) {
711 uni_blocks_low++;
712 }
713 if (addr >= DRAM0_SRAM_UNI_BLOCK_1_LOW) {
714 uni_blocks_low++;
715 }
716 if (addr >= DRAM0_SRAM_UNI_BLOCK_2_LOW) {
717 uni_blocks_low++;
718 }
719 if (addr >= DRAM0_SRAM_UNI_BLOCK_3_LOW) {
720 uni_blocks_low++;
721 }
722
723 //set unified mgmt region
724 uint32_t write_bit, read_bit, uni_block_perm = 0;
725 for (int x = 0; x < DRAM0_SRAM_TOTAL_UNI_BLOCKS; x++) {
726 if (!memprot_ll_dram0_sram_get_uni_block_sgnf_bits(x, &write_bit, &read_bit)) {
727 return MEMP_LL_ERR_UNI_BLOCK_INVALID;
728 }
729 if (x <= uni_blocks_low) {
730 if (lw) {
731 uni_block_perm |= write_bit;
732 }
733 if (lr) {
734 uni_block_perm |= read_bit;
735 }
736 } else {
737 if (hw) {
738 uni_block_perm |= write_bit;
739 }
740 if (hr) {
741 uni_block_perm |= read_bit;
742 }
743 }
744 }
745
746 //conf reg [24:8]
747 uint32_t reg_split_addr = DRAM0_SRAM_ADDR_TO_CONF_REG(addr);
748
749 //prepare high & low permission mask
750 uint32_t permission_mask = 0;
751 if (lw) {
752 permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_L_W;
753 }
754 if (lr) {
755 permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_L_R;
756 }
757 if (hw) {
758 permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_H_W;
759 }
760 if (hr) {
761 permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_H_R;
762 }
763
764 //write DRAM0 SRAM cfg register
765 DPORT_WRITE_PERI_REG(DPORT_PMS_PRO_DRAM0_1_REG, reg_split_addr | permission_mask | uni_block_perm);
766
767 return MEMP_LL_OK;
768 }
769
memprot_ll_dram0_sram_get_split_sgnf_bits(bool * lw,bool * lr,bool * hw,bool * hr)770 static inline void memprot_ll_dram0_sram_get_split_sgnf_bits(bool *lw, bool *lr, bool *hw, bool *hr)
771 {
772 *lw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_L_W);
773 *lr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_L_R);
774 *hw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_H_W);
775 *hr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_H_R);
776 }
777
memprot_ll_dram0_sram_set_read_perm(bool lr,bool hr)778 static inline void memprot_ll_dram0_sram_set_read_perm(bool lr, bool hr)
779 {
780 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_L_R, lr ? 1 : 0);
781 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_H_R, hr ? 1 : 0);
782 }
783
memprot_ll_dram0_sram_set_write_perm(bool lw,bool hw)784 static inline void memprot_ll_dram0_sram_set_write_perm(bool lw, bool hw)
785 {
786 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_L_W, lw ? 1 : 0);
787 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_H_W, hw ? 1 : 0);
788 }
789
790
791 /**
792 * ========================================================================================
793 * === DRAM0 RTC FAST
794 * ========================================================================================
795 */
memprot_ll_dram0_rtcfast_get_fault_address(void)796 static inline intptr_t memprot_ll_dram0_rtcfast_get_fault_address(void)
797 {
798 uint32_t status_bits = memprot_ll_dram0_get_fault_reg();
799 return (intptr_t)(((status_bits & DRAM0_INTR_ST_FAULTADDR_M) >> DRAM0_INTR_ST_FAULTADDR_S) | DRAM0_RTCFAST_INTR_ST_FAULTADDR_HI);
800 }
801
memprot_ll_dram0_rtcfast_is_intr_mine(void)802 static inline bool memprot_ll_dram0_rtcfast_is_intr_mine(void)
803 {
804 if (memprot_ll_dram0_is_assoc_intr()) {
805 uint32_t faulting_address = (uint32_t)memprot_ll_dram0_rtcfast_get_fault_address();
806 return faulting_address >= DRAM0_RTCFAST_ADDRESS_LOW && faulting_address <= DRAM0_RTCFAST_ADDRESS_HIGH;
807 }
808 return false;
809 }
810
memprot_ll_dram0_rtcfast_set_prot(uint32_t * split_addr,bool lw,bool lr,bool hw,bool hr)811 static inline memprot_ll_err_t memprot_ll_dram0_rtcfast_set_prot(uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr)
812 {
813 uint32_t addr = (uint32_t)split_addr;
814
815 //addr: 32bit aligned, inside corresponding range
816 if (addr < DRAM0_RTCFAST_ADDRESS_LOW || addr > DRAM0_RTCFAST_ADDRESS_HIGH) {
817 return MEMP_LL_ERR_SPLIT_ADDR_INVALID;
818 }
819 if (addr % 0x4 != 0) {
820 return MEMP_LL_ERR_SPLIT_ADDR_UNALIGNED;
821 }
822
823 //conf reg [10:0]
824 uint32_t reg_split_addr = DRAM0_RTCFAST_ADDR_TO_CONF_REG(addr);
825
826 //prepare high & low permission mask
827 uint32_t permission_mask = 0;
828 if (lw) {
829 permission_mask |= DPORT_PMS_PRO_DRAM0_RTCFAST_L_W;
830 }
831 if (lr) {
832 permission_mask |= DPORT_PMS_PRO_DRAM0_RTCFAST_L_R;
833 }
834 if (hw) {
835 permission_mask |= DPORT_PMS_PRO_DRAM0_RTCFAST_H_W;
836 }
837 if (hr) {
838 permission_mask |= DPORT_PMS_PRO_DRAM0_RTCFAST_H_R;
839 }
840
841 //write DRAM0 RTC FAST cfg register
842 DPORT_WRITE_PERI_REG(DPORT_PMS_PRO_DRAM0_2_REG, reg_split_addr | permission_mask);
843
844 return MEMP_LL_OK;
845 }
846
memprot_ll_dram0_rtcfast_get_split_sgnf_bits(bool * lw,bool * lr,bool * hw,bool * hr)847 static inline void memprot_ll_dram0_rtcfast_get_split_sgnf_bits(bool *lw, bool *lr, bool *hw, bool *hr)
848 {
849 *lw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_L_W);
850 *lr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_L_R);
851 *hw = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_H_W);
852 *hr = DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_H_R);
853 }
854
memprot_ll_dram0_rtcfast_get_perm_split_reg(void)855 static inline uint32_t memprot_ll_dram0_rtcfast_get_perm_split_reg(void)
856 {
857 return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_2_REG);
858 }
859
memprot_ll_dram0_rtcfast_set_read_perm(bool lr,bool hr)860 static inline void memprot_ll_dram0_rtcfast_set_read_perm(bool lr, bool hr)
861 {
862 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_L_R, lr ? 1 : 0);
863 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_H_R, hr ? 1 : 0);
864 }
865
memprot_ll_dram0_rtcfast_set_write_perm(bool lw,bool hw)866 static inline void memprot_ll_dram0_rtcfast_set_write_perm(bool lw, bool hw)
867 {
868 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_L_W, lw ? 1 : 0);
869 DPORT_REG_SET_FIELD(DPORT_PMS_PRO_DRAM0_2_REG, DPORT_PMS_PRO_DRAM0_RTCFAST_H_W, hw ? 1 : 0);
870 }
871
872 #ifdef __cplusplus
873 }
874 #endif
875