• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 // Copyright (C) 2022 Beken Corporation
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 
16 
17 #include <stdio.h>
18 #include "platform.h"
19 #include <os/os.h>
20 #include "pmp.h"
21 
22 
23 #define SYS_DELAY_TIME_10US        (170UL)
24 
25 /* bk7256   */
26 #define MEM_MAPPING_MAX               0xFFFFFFF0
27 #define ADDR_MAPPING_MAX              0x80000000
28 #define DTCM_END                      0x20008000
29 #define SRAM_END                      0x38080000
30 #define FLASH_END                     0x00400000
31 
32 /* PMP entry 0 : 0 ~ (_start), lock, TOR range, excutable, no writable, readable */
33 extern char _start;
34 
35 /* PMP entry 1(code/RO data section) :  (_start) ~ (_data_lmastart), lock, TOR range, excutable, no writable, readable */
36 extern char _data_lmastart;
37 
38 /* PMP entry 2(FLASH) : (_data_lmastart) ~ (FLASH_END), lock, TOR range, no excutable, writable, readable */
39 
40 /* PMP entry 3(null section) : (FLASH_END) ~ (_itcm_ema_start), lock, TOR range, no excutable, no writable, no readable */
41 extern char _itcm_ema_start;
42 
43 /* PMP entry 4(itcm section) : (_itcm_ema_start) ~ (_dtcm_ema_start), lock, TOR range, excutable, no writable, readable */
44 extern char _dtcm_ema_start;
45 
46 /* PMP entry 5(dtcm/sram section) : (_dtcm_ema_start) ~ (SRAM_END), lock, TOR range, no excutable,  writable, readable */
47 
48 /* PMP entry 6(max address section) : (SRAM_END) ~ (ADDR_MAPPING_MAX), lock, TOR range, no excutable,  writable, readable */
49 
50 
51 
52 #if (!CONFIG_SLAVE_CORE)
53 const pmp_config_t pmp_tor_config_table[] = {\
54     {ENTRY_PMPADDR0, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON),  (void*)(&_start + 4)}, \
55     {ENTRY_PMPADDR1, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON),  (void*)(&_data_lmastart + 4) }, \
56     {ENTRY_PMPADDR2, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON),  (void*)(FLASH_END + 4) }, \
57     {ENTRY_PMPADDR3, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_OFF, PMP_R_OFF),  (void*)(&_itcm_ema_start + 4) }, \
58     {ENTRY_PMPADDR4, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON),  (void*)(&_dtcm_ema_start + 4) }, \
59     {ENTRY_PMPADDR5, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON),  (void*)(SRAM_END +4) }, \
60     {ENTRY_PMPADDR6, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON),   (void*)(ADDR_MAPPING_MAX+4) } \
61 };
62 #else
63 const pmp_config_t pmp_tor_config_table[] = {\
64 };
65 #endif //#if (!CONFIG_SLAVE_CORE)
66 
67 extern void sys_delay_sync(uint32_t time_count );
68 
pmp_tor_config(char entry,void * address,char pmp_cfg)69 void pmp_tor_config(char entry, void* address, char pmp_cfg)
70 {
71     long pmpcfg = pmp_cfg & 0xFF;
72 
73     void * va = (void *)((((uint32)(address)+3)/4) * 4);
74 
75     os_printf("pmp_tor_config[%d]: addr(0x%08x),TOR(0x%08x) cfg(0x%02x).\n", entry, va, TOR(va), pmpcfg);
76     switch (entry) {
77     case ENTRY_PMPADDR0:
78         write_csr(NDS_PMPADDR0, TOR(va));
79         break;
80     case ENTRY_PMPADDR1:
81         write_csr(NDS_PMPADDR1, TOR(va));
82         break;
83     case ENTRY_PMPADDR2:
84         write_csr(NDS_PMPADDR2, TOR(va));
85         break;
86     case ENTRY_PMPADDR3:
87         write_csr(NDS_PMPADDR3, TOR(va));
88         break;
89     case ENTRY_PMPADDR4:
90         write_csr(NDS_PMPADDR4, TOR(va));
91         break;
92     case ENTRY_PMPADDR5:
93         write_csr(NDS_PMPADDR5, TOR(va));
94         break;
95     case ENTRY_PMPADDR6:
96         write_csr(NDS_PMPADDR6, TOR(va));
97         break;
98     case ENTRY_PMPADDR7:
99         write_csr(NDS_PMPADDR7, TOR(va));
100         break;
101     case ENTRY_PMPADDR8:
102         write_csr(NDS_PMPADDR8, TOR(va));
103         break;
104     case ENTRY_PMPADDR9:
105         write_csr(NDS_PMPADDR9, TOR(va));
106         break;
107     case ENTRY_PMPADDR10:
108         write_csr(NDS_PMPADDR10, TOR(va));
109         break;
110     case ENTRY_PMPADDR11:
111         write_csr(NDS_PMPADDR11, TOR(va));
112         break;
113     case ENTRY_PMPADDR12:
114         write_csr(NDS_PMPADDR12, TOR(va));
115         break;
116     case ENTRY_PMPADDR13:
117         write_csr(NDS_PMPADDR13, TOR(va));
118         break;
119     case ENTRY_PMPADDR14:
120         write_csr(NDS_PMPADDR14, TOR(va));
121         break;
122     case ENTRY_PMPADDR15:
123         write_csr(NDS_PMPADDR15, TOR(va));
124         break;
125     }
126 
127 #if __riscv_xlen == 64
128     switch (entry >> 3){
129     case ENTRY_PMPCFG0:
130         write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
131         break;
132     case ENTRY_PMPCFG1:
133         write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
134         break;
135     }
136 #else
137     switch (entry >> 2) {
138     case ENTRY_PMPCFG0:
139         write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
140         break;
141     case ENTRY_PMPCFG1:
142         write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
143         break;
144     case ENTRY_PMPCFG2:
145         write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
146         break;
147     case ENTRY_PMPCFG3:
148         write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
149         break;
150     }
151 #endif
152 }
153 
pmp_napot_config(char entry,void * va,unsigned long size,char pmpcfg)154 void pmp_napot_config(char entry, void* va, unsigned long size, char pmpcfg)
155 {
156     switch (entry) {
157     case ENTRY_PMPADDR0:
158         write_csr(NDS_PMPADDR0, NAPOT(va, size));
159         break;
160     case ENTRY_PMPADDR1:
161         write_csr(NDS_PMPADDR1, NAPOT(va, size));
162         break;
163     case ENTRY_PMPADDR2:
164         write_csr(NDS_PMPADDR2, NAPOT(va, size));
165         break;
166     case ENTRY_PMPADDR3:
167         write_csr(NDS_PMPADDR3, NAPOT(va, size));
168         break;
169     case ENTRY_PMPADDR4:
170         write_csr(NDS_PMPADDR4, NAPOT(va, size));
171         break;
172     case ENTRY_PMPADDR5:
173         write_csr(NDS_PMPADDR5, NAPOT(va, size));
174         break;
175     case ENTRY_PMPADDR6:
176         write_csr(NDS_PMPADDR6, NAPOT(va, size));
177         break;
178     case ENTRY_PMPADDR7:
179         write_csr(NDS_PMPADDR7, NAPOT(va, size));
180         break;
181     case ENTRY_PMPADDR8:
182         write_csr(NDS_PMPADDR8, NAPOT(va, size));
183         break;
184     case ENTRY_PMPADDR9:
185         write_csr(NDS_PMPADDR9, NAPOT(va, size));
186         break;
187     case ENTRY_PMPADDR10:
188         write_csr(NDS_PMPADDR10, NAPOT(va, size));
189         break;
190     case ENTRY_PMPADDR11:
191         write_csr(NDS_PMPADDR11, NAPOT(va, size));
192         break;
193     case ENTRY_PMPADDR12:
194         write_csr(NDS_PMPADDR12, NAPOT(va, size));
195         break;
196     case ENTRY_PMPADDR13:
197         write_csr(NDS_PMPADDR13, NAPOT(va, size));
198         break;
199     case ENTRY_PMPADDR14:
200         write_csr(NDS_PMPADDR14, NAPOT(va, size));
201         break;
202     case ENTRY_PMPADDR15:
203         write_csr(NDS_PMPADDR15, NAPOT(va, size));
204         break;
205     }
206 
207 #if __riscv_xlen == 64
208     switch (entry >> 3){
209     case ENTRY_PMPCFG0:
210         write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
211         break;
212     case ENTRY_PMPCFG1:
213         write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
214         break;
215     }
216 #else
217     switch (entry >> 2) {
218     case ENTRY_PMPCFG0:
219         write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
220         break;
221     case ENTRY_PMPCFG1:
222         write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
223         break;
224     case ENTRY_PMPCFG2:
225         write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
226         break;
227     case ENTRY_PMPCFG3:
228         write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
229         break;
230     }
231 #endif
232 }
233 
234 
init_pmp_config()235 void init_pmp_config()
236 {
237     int i = 0;
238     int config_count = 0;
239     /*
240      * Check whether the CPU configured with PMP feature.
241      * Write 0x3 to the pmpcfg0 register, and read it back
242      * to check the number of PMP entries.
243      */
244     write_csr(NDS_PMPCFG0, 0x3);
245     if (!read_csr(NDS_PMPCFG0)) {
246         os_printf("PMP entries is 0, CPU does NOT support PMP.\n");
247         while(1);
248     }
249 
250     /* Disable global interrupt but allow exception */
251     clear_csr(NDS_MSTATUS, MSTATUS_MIE);
252 
253 #if USE_NAPOT
254 
255     os_printf("PMP uses NAPOT scheme!.\n");
256 
257 #else    /* USE_TOR */
258 
259     os_printf("PMP uses TOR scheme!.\n");
260     config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t);
261 
262     os_printf("PMP config count(%d).\n", config_count);
263     for (i = 0; i < config_count; i++)
264     {
265         pmp_tor_config(pmp_tor_config_table[i].pmp_entry,
266                     pmp_tor_config_table[i].pmp_addr,
267                     pmp_tor_config_table[i].pmp_config);
268 
269         sys_delay_sync(SYS_DELAY_TIME_10US);
270     }
271 
272 #endif
273 }
274 
show_pmp_config()275 void show_pmp_config()
276 {
277     os_printf("==========PMP config info===============\r\n");
278 
279     int i = 0;
280     int config_count = 0;
281     long pmp_config0 = read_csr(NDS_PMPCFG0);
282     if (!pmp_config0) {
283         os_printf("PMP entries is 0, CPU does NOT support PMP.\n");
284     }
285 
286 #if USE_NAPOT
287 
288     os_printf("PMP uses NAPOT scheme!.\n");
289 
290 #else    /* USE_TOR */
291 
292     os_printf("PMP uses TOR scheme!.\n");
293     config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t);
294 
295     os_printf("PMP user config count(%d).\n", config_count);
296     for (i = 0; i < config_count; i++)
297     {
298         os_printf("PMP config[%d], 0x%08x, 0x%0x.\r\n", i,
299                     (void *)pmp_tor_config_table[i].pmp_addr,
300                     pmp_tor_config_table[i].pmp_config);
301 
302     }
303 
304 #endif
305     os_printf("==========PMP actural config:\r\n");
306     os_printf("==========NDS_PMPCFG0:  0x%08x.\r\n", pmp_config0);
307     os_printf("==========NDS_PMPCFG1:  0x%08x.\r\n", read_csr(NDS_PMPCFG1));
308 
309     os_printf("==========NDS_PMPADDR0: 0x%08x.\r\n", read_csr(NDS_PMPADDR0));
310     os_printf("==========NDS_PMPADDR1: 0x%08x.\r\n", read_csr(NDS_PMPADDR1));
311     os_printf("==========NDS_PMPADDR2: 0x%08x.\r\n", read_csr(NDS_PMPADDR2));
312     os_printf("==========NDS_PMPADDR3: 0x%08x.\r\n", read_csr(NDS_PMPADDR3));
313     os_printf("==========NDS_PMPADDR4: 0x%08x.\r\n", read_csr(NDS_PMPADDR4));
314     os_printf("==========NDS_PMPADDR5: 0x%08x.\r\n", read_csr(NDS_PMPADDR5));
315     os_printf("==========NDS_PMPADDR6: 0x%08x.\r\n", read_csr(NDS_PMPADDR6));
316     os_printf("==========NDS_PMPADDR7: 0x%08x.\r\n", read_csr(NDS_PMPADDR7));
317 
318 }
319