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