1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero */
9*10465441SEvalZero
10*10465441SEvalZero #include "mmu.h"
11*10465441SEvalZero
12*10465441SEvalZero #ifdef __CC_ARM
mmu_setttbase(rt_uint32_t i)13*10465441SEvalZero void mmu_setttbase(rt_uint32_t i)
14*10465441SEvalZero {
15*10465441SEvalZero register rt_uint32_t value;
16*10465441SEvalZero
17*10465441SEvalZero /* Invalidates all TLBs.Domain access is selected as
18*10465441SEvalZero * client by configuring domain access register,
19*10465441SEvalZero * in that case access controlled by permission value
20*10465441SEvalZero * set by page table entry
21*10465441SEvalZero */
22*10465441SEvalZero value = 0;
23*10465441SEvalZero __asm volatile
24*10465441SEvalZero {
25*10465441SEvalZero mcr p15, 0, value, c8, c7, 0
26*10465441SEvalZero }
27*10465441SEvalZero
28*10465441SEvalZero value = 0x55555555;
29*10465441SEvalZero __asm volatile
30*10465441SEvalZero {
31*10465441SEvalZero mcr p15, 0, value, c3, c0, 0
32*10465441SEvalZero mcr p15, 0, i, c2, c0, 0
33*10465441SEvalZero }
34*10465441SEvalZero }
35*10465441SEvalZero
mmu_set_domain(rt_uint32_t i)36*10465441SEvalZero void mmu_set_domain(rt_uint32_t i)
37*10465441SEvalZero {
38*10465441SEvalZero __asm volatile
39*10465441SEvalZero {
40*10465441SEvalZero mcr p15,0, i, c3, c0, 0
41*10465441SEvalZero }
42*10465441SEvalZero }
43*10465441SEvalZero
mmu_enable()44*10465441SEvalZero void mmu_enable()
45*10465441SEvalZero {
46*10465441SEvalZero register rt_uint32_t value;
47*10465441SEvalZero
48*10465441SEvalZero __asm volatile
49*10465441SEvalZero {
50*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
51*10465441SEvalZero orr value, value, #0x01
52*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
53*10465441SEvalZero }
54*10465441SEvalZero }
55*10465441SEvalZero
mmu_disable()56*10465441SEvalZero void mmu_disable()
57*10465441SEvalZero {
58*10465441SEvalZero register rt_uint32_t value;
59*10465441SEvalZero
60*10465441SEvalZero __asm volatile
61*10465441SEvalZero {
62*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
63*10465441SEvalZero bic value, value, #0x01
64*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
65*10465441SEvalZero }
66*10465441SEvalZero }
67*10465441SEvalZero
mmu_enable_icache()68*10465441SEvalZero void mmu_enable_icache()
69*10465441SEvalZero {
70*10465441SEvalZero register rt_uint32_t value;
71*10465441SEvalZero
72*10465441SEvalZero __asm volatile
73*10465441SEvalZero {
74*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
75*10465441SEvalZero orr value, value, #0x1000
76*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
77*10465441SEvalZero }
78*10465441SEvalZero }
79*10465441SEvalZero
mmu_enable_dcache()80*10465441SEvalZero void mmu_enable_dcache()
81*10465441SEvalZero {
82*10465441SEvalZero register rt_uint32_t value;
83*10465441SEvalZero
84*10465441SEvalZero __asm volatile
85*10465441SEvalZero {
86*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
87*10465441SEvalZero orr value, value, #0x04
88*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
89*10465441SEvalZero }
90*10465441SEvalZero }
91*10465441SEvalZero
mmu_disable_icache()92*10465441SEvalZero void mmu_disable_icache()
93*10465441SEvalZero {
94*10465441SEvalZero register rt_uint32_t value;
95*10465441SEvalZero
96*10465441SEvalZero __asm volatile
97*10465441SEvalZero {
98*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
99*10465441SEvalZero bic value, value, #0x1000
100*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
101*10465441SEvalZero }
102*10465441SEvalZero }
103*10465441SEvalZero
mmu_disable_dcache()104*10465441SEvalZero void mmu_disable_dcache()
105*10465441SEvalZero {
106*10465441SEvalZero register rt_uint32_t value;
107*10465441SEvalZero
108*10465441SEvalZero __asm volatile
109*10465441SEvalZero {
110*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
111*10465441SEvalZero bic value, value, #0x04
112*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
113*10465441SEvalZero }
114*10465441SEvalZero }
115*10465441SEvalZero
mmu_enable_alignfault()116*10465441SEvalZero void mmu_enable_alignfault()
117*10465441SEvalZero {
118*10465441SEvalZero register rt_uint32_t value;
119*10465441SEvalZero
120*10465441SEvalZero __asm volatile
121*10465441SEvalZero {
122*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
123*10465441SEvalZero orr value, value, #0x02
124*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
125*10465441SEvalZero }
126*10465441SEvalZero }
127*10465441SEvalZero
mmu_disable_alignfault()128*10465441SEvalZero void mmu_disable_alignfault()
129*10465441SEvalZero {
130*10465441SEvalZero register rt_uint32_t value;
131*10465441SEvalZero
132*10465441SEvalZero __asm volatile
133*10465441SEvalZero {
134*10465441SEvalZero mrc p15, 0, value, c1, c0, 0
135*10465441SEvalZero bic value, value, #0x02
136*10465441SEvalZero mcr p15, 0, value, c1, c0, 0
137*10465441SEvalZero }
138*10465441SEvalZero }
139*10465441SEvalZero
mmu_clean_invalidated_cache_index(int index)140*10465441SEvalZero void mmu_clean_invalidated_cache_index(int index)
141*10465441SEvalZero {
142*10465441SEvalZero __asm volatile
143*10465441SEvalZero {
144*10465441SEvalZero mcr p15, 0, index, c7, c14, 2
145*10465441SEvalZero }
146*10465441SEvalZero }
147*10465441SEvalZero
mmu_clean_invalidated_dcache(rt_uint32_t buffer,rt_uint32_t size)148*10465441SEvalZero void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
149*10465441SEvalZero {
150*10465441SEvalZero unsigned int ptr;
151*10465441SEvalZero
152*10465441SEvalZero ptr = buffer & ~(CACHE_LINE_SIZE - 1);
153*10465441SEvalZero
154*10465441SEvalZero while(ptr < buffer + size)
155*10465441SEvalZero {
156*10465441SEvalZero __asm volatile
157*10465441SEvalZero {
158*10465441SEvalZero MCR p15, 0, ptr, c7, c14, 1
159*10465441SEvalZero }
160*10465441SEvalZero ptr += CACHE_LINE_SIZE;
161*10465441SEvalZero }
162*10465441SEvalZero }
163*10465441SEvalZero
mmu_clean_dcache(rt_uint32_t buffer,rt_uint32_t size)164*10465441SEvalZero void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
165*10465441SEvalZero {
166*10465441SEvalZero unsigned int ptr;
167*10465441SEvalZero
168*10465441SEvalZero ptr = buffer & ~(CACHE_LINE_SIZE - 1);
169*10465441SEvalZero
170*10465441SEvalZero while (ptr < buffer + size)
171*10465441SEvalZero {
172*10465441SEvalZero __asm volatile
173*10465441SEvalZero {
174*10465441SEvalZero MCR p15, 0, ptr, c7, c10, 1
175*10465441SEvalZero }
176*10465441SEvalZero ptr += CACHE_LINE_SIZE;
177*10465441SEvalZero }
178*10465441SEvalZero }
179*10465441SEvalZero
mmu_invalidate_dcache(rt_uint32_t buffer,rt_uint32_t size)180*10465441SEvalZero void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
181*10465441SEvalZero {
182*10465441SEvalZero unsigned int ptr;
183*10465441SEvalZero
184*10465441SEvalZero ptr = buffer & ~(CACHE_LINE_SIZE - 1);
185*10465441SEvalZero
186*10465441SEvalZero while (ptr < buffer + size)
187*10465441SEvalZero {
188*10465441SEvalZero __asm volatile
189*10465441SEvalZero {
190*10465441SEvalZero MCR p15, 0, ptr, c7, c6, 1
191*10465441SEvalZero }
192*10465441SEvalZero ptr += CACHE_LINE_SIZE;
193*10465441SEvalZero }
194*10465441SEvalZero }
195*10465441SEvalZero
mmu_invalidate_tlb()196*10465441SEvalZero void mmu_invalidate_tlb()
197*10465441SEvalZero {
198*10465441SEvalZero register rt_uint32_t value;
199*10465441SEvalZero
200*10465441SEvalZero value = 0;
201*10465441SEvalZero __asm volatile
202*10465441SEvalZero {
203*10465441SEvalZero mcr p15, 0, value, c8, c7, 0
204*10465441SEvalZero }
205*10465441SEvalZero }
206*10465441SEvalZero
mmu_invalidate_icache()207*10465441SEvalZero void mmu_invalidate_icache()
208*10465441SEvalZero {
209*10465441SEvalZero register rt_uint32_t value;
210*10465441SEvalZero
211*10465441SEvalZero value = 0;
212*10465441SEvalZero
213*10465441SEvalZero __asm volatile
214*10465441SEvalZero {
215*10465441SEvalZero mcr p15, 0, value, c7, c5, 0
216*10465441SEvalZero }
217*10465441SEvalZero }
218*10465441SEvalZero
219*10465441SEvalZero
mmu_invalidate_dcache_all()220*10465441SEvalZero void mmu_invalidate_dcache_all()
221*10465441SEvalZero {
222*10465441SEvalZero register rt_uint32_t value;
223*10465441SEvalZero
224*10465441SEvalZero value = 0;
225*10465441SEvalZero
226*10465441SEvalZero __asm volatile
227*10465441SEvalZero {
228*10465441SEvalZero mcr p15, 0, value, c7, c6, 0
229*10465441SEvalZero }
230*10465441SEvalZero }
231*10465441SEvalZero #elif defined(__GNUC__)
mmu_setttbase(register rt_uint32_t i)232*10465441SEvalZero void mmu_setttbase(register rt_uint32_t i)
233*10465441SEvalZero {
234*10465441SEvalZero register rt_uint32_t value;
235*10465441SEvalZero
236*10465441SEvalZero /* Invalidates all TLBs.Domain access is selected as
237*10465441SEvalZero * client by configuring domain access register,
238*10465441SEvalZero * in that case access controlled by permission value
239*10465441SEvalZero * set by page table entry
240*10465441SEvalZero */
241*10465441SEvalZero value = 0;
242*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c8, c7, 0"::"r"(value));
243*10465441SEvalZero
244*10465441SEvalZero value = 0x55555555;
245*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
246*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c2, c0, 0"::"r"(i));
247*10465441SEvalZero }
248*10465441SEvalZero
mmu_set_domain(register rt_uint32_t i)249*10465441SEvalZero void mmu_set_domain(register rt_uint32_t i)
250*10465441SEvalZero {
251*10465441SEvalZero asm volatile ("mcr p15,0, %0, c3, c0, 0": :"r" (i));
252*10465441SEvalZero }
253*10465441SEvalZero
mmu_enable()254*10465441SEvalZero void mmu_enable()
255*10465441SEvalZero {
256*10465441SEvalZero register rt_uint32_t i;
257*10465441SEvalZero
258*10465441SEvalZero /* read control register */
259*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
260*10465441SEvalZero
261*10465441SEvalZero i |= 0x1;
262*10465441SEvalZero /* Enables the extended page tables to be configured for
263*10465441SEvalZero the hardware page translation mechanism, Subpage AP bits disabled */
264*10465441SEvalZero i |= (1 << 23); /* support for ARMv6 MMU features */
265*10465441SEvalZero i |= (1 << 13); /* High exception vectors selected, address range = 0xFFFF0000-0xFFFF001C */
266*10465441SEvalZero
267*10465441SEvalZero /* write back to control register */
268*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
269*10465441SEvalZero }
270*10465441SEvalZero
mmu_disable()271*10465441SEvalZero void mmu_disable()
272*10465441SEvalZero {
273*10465441SEvalZero register rt_uint32_t i;
274*10465441SEvalZero
275*10465441SEvalZero /* read control register */
276*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
277*10465441SEvalZero
278*10465441SEvalZero i &= ~0x1;
279*10465441SEvalZero
280*10465441SEvalZero /* write back to control register */
281*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
282*10465441SEvalZero }
283*10465441SEvalZero
mmu_enable_icache()284*10465441SEvalZero void mmu_enable_icache()
285*10465441SEvalZero {
286*10465441SEvalZero register rt_uint32_t i;
287*10465441SEvalZero
288*10465441SEvalZero /* read control register */
289*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
290*10465441SEvalZero
291*10465441SEvalZero i |= (1 << 12);
292*10465441SEvalZero
293*10465441SEvalZero /* write back to control register */
294*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
295*10465441SEvalZero }
296*10465441SEvalZero
mmu_enable_dcache()297*10465441SEvalZero void mmu_enable_dcache()
298*10465441SEvalZero {
299*10465441SEvalZero register rt_uint32_t i;
300*10465441SEvalZero
301*10465441SEvalZero /* read control register */
302*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
303*10465441SEvalZero
304*10465441SEvalZero i |= (1 << 2);
305*10465441SEvalZero
306*10465441SEvalZero /* write back to control register */
307*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
308*10465441SEvalZero }
309*10465441SEvalZero
mmu_disable_icache()310*10465441SEvalZero void mmu_disable_icache()
311*10465441SEvalZero {
312*10465441SEvalZero register rt_uint32_t i;
313*10465441SEvalZero
314*10465441SEvalZero /* read control register */
315*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
316*10465441SEvalZero
317*10465441SEvalZero i &= ~(1 << 12);
318*10465441SEvalZero
319*10465441SEvalZero /* write back to control register */
320*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
321*10465441SEvalZero }
322*10465441SEvalZero
mmu_disable_dcache()323*10465441SEvalZero void mmu_disable_dcache()
324*10465441SEvalZero {
325*10465441SEvalZero register rt_uint32_t i;
326*10465441SEvalZero
327*10465441SEvalZero /* read control register */
328*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
329*10465441SEvalZero
330*10465441SEvalZero i &= ~(1 << 2);
331*10465441SEvalZero
332*10465441SEvalZero /* write back to control register */
333*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
334*10465441SEvalZero }
335*10465441SEvalZero
mmu_enable_alignfault()336*10465441SEvalZero void mmu_enable_alignfault()
337*10465441SEvalZero {
338*10465441SEvalZero register rt_uint32_t i;
339*10465441SEvalZero
340*10465441SEvalZero /* read control register */
341*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
342*10465441SEvalZero
343*10465441SEvalZero i |= (1 << 1);
344*10465441SEvalZero
345*10465441SEvalZero /* write back to control register */
346*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
347*10465441SEvalZero }
348*10465441SEvalZero
mmu_disable_alignfault()349*10465441SEvalZero void mmu_disable_alignfault()
350*10465441SEvalZero {
351*10465441SEvalZero register rt_uint32_t i;
352*10465441SEvalZero
353*10465441SEvalZero /* read control register */
354*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
355*10465441SEvalZero
356*10465441SEvalZero i &= ~(1 << 1);
357*10465441SEvalZero
358*10465441SEvalZero /* write back to control register */
359*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
360*10465441SEvalZero }
361*10465441SEvalZero
mmu_clean_invalidated_cache_index(int index)362*10465441SEvalZero void mmu_clean_invalidated_cache_index(int index)
363*10465441SEvalZero {
364*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
365*10465441SEvalZero }
366*10465441SEvalZero
mmu_clean_invalidated_dcache(rt_uint32_t buffer,rt_uint32_t size)367*10465441SEvalZero void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
368*10465441SEvalZero {
369*10465441SEvalZero unsigned int ptr;
370*10465441SEvalZero
371*10465441SEvalZero ptr = buffer & ~(CACHE_LINE_SIZE - 1);
372*10465441SEvalZero
373*10465441SEvalZero while(ptr < buffer + size)
374*10465441SEvalZero {
375*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr));
376*10465441SEvalZero ptr += CACHE_LINE_SIZE;
377*10465441SEvalZero }
378*10465441SEvalZero }
379*10465441SEvalZero
380*10465441SEvalZero
mmu_clean_dcache(rt_uint32_t buffer,rt_uint32_t size)381*10465441SEvalZero void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
382*10465441SEvalZero {
383*10465441SEvalZero unsigned int ptr;
384*10465441SEvalZero
385*10465441SEvalZero ptr = buffer & ~(CACHE_LINE_SIZE - 1);
386*10465441SEvalZero
387*10465441SEvalZero while (ptr < buffer + size)
388*10465441SEvalZero {
389*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr));
390*10465441SEvalZero ptr += CACHE_LINE_SIZE;
391*10465441SEvalZero }
392*10465441SEvalZero }
393*10465441SEvalZero
mmu_invalidate_dcache(rt_uint32_t buffer,rt_uint32_t size)394*10465441SEvalZero void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
395*10465441SEvalZero {
396*10465441SEvalZero unsigned int ptr;
397*10465441SEvalZero
398*10465441SEvalZero ptr = buffer & ~(CACHE_LINE_SIZE - 1);
399*10465441SEvalZero
400*10465441SEvalZero while (ptr < buffer + size)
401*10465441SEvalZero {
402*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr));
403*10465441SEvalZero ptr += CACHE_LINE_SIZE;
404*10465441SEvalZero }
405*10465441SEvalZero }
406*10465441SEvalZero
mmu_invalidate_tlb()407*10465441SEvalZero void mmu_invalidate_tlb()
408*10465441SEvalZero {
409*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
410*10465441SEvalZero }
411*10465441SEvalZero
mmu_invalidate_icache()412*10465441SEvalZero void mmu_invalidate_icache()
413*10465441SEvalZero {
414*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
415*10465441SEvalZero }
416*10465441SEvalZero
mmu_invalidate_dcache_all()417*10465441SEvalZero void mmu_invalidate_dcache_all()
418*10465441SEvalZero {
419*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c7, c6, 0": :"r" (0));
420*10465441SEvalZero }
421*10465441SEvalZero #endif
422*10465441SEvalZero
423*10465441SEvalZero /* level1 page table */
424*10465441SEvalZero static volatile unsigned int _pgd_table[4*1024] ALIGN(16*1024);
425*10465441SEvalZero /*
426*10465441SEvalZero * level2 page table
427*10465441SEvalZero * RT_MMU_PTE_SIZE must be 1024*n
428*10465441SEvalZero */
429*10465441SEvalZero #define RT_MMU_PTE_SIZE 4096
430*10465441SEvalZero static volatile unsigned int _pte_table[RT_MMU_PTE_SIZE] ALIGN(1*1024);
431*10465441SEvalZero
mmu_create_pgd(struct mem_desc * mdesc)432*10465441SEvalZero void mmu_create_pgd(struct mem_desc *mdesc)
433*10465441SEvalZero {
434*10465441SEvalZero volatile rt_uint32_t *pTT;
435*10465441SEvalZero volatile int i, nSec;
436*10465441SEvalZero pTT = (rt_uint32_t *)_pgd_table + (mdesc->vaddr_start >> 20);
437*10465441SEvalZero nSec = (mdesc->vaddr_end >> 20) - (mdesc->vaddr_start >> 20);
438*10465441SEvalZero for(i = 0; i <= nSec; i++)
439*10465441SEvalZero {
440*10465441SEvalZero *pTT = mdesc->sect_attr | (((mdesc->paddr_start >> 20) + i) << 20);
441*10465441SEvalZero pTT++;
442*10465441SEvalZero }
443*10465441SEvalZero }
444*10465441SEvalZero
mmu_create_pte(struct mem_desc * mdesc)445*10465441SEvalZero void mmu_create_pte(struct mem_desc *mdesc)
446*10465441SEvalZero {
447*10465441SEvalZero volatile rt_uint32_t *pTT;
448*10465441SEvalZero volatile rt_uint32_t *p_pteentry;
449*10465441SEvalZero int i;
450*10465441SEvalZero rt_uint32_t vaddr;
451*10465441SEvalZero rt_uint32_t total_page = 0;
452*10465441SEvalZero rt_uint32_t pte_offset = 0;
453*10465441SEvalZero rt_uint32_t sect_attr = 0;
454*10465441SEvalZero
455*10465441SEvalZero total_page = (mdesc->vaddr_end >> 12) - (mdesc->vaddr_start >> 12) + 1;
456*10465441SEvalZero pte_offset = mdesc->sect_attr & 0xfffffc00;
457*10465441SEvalZero sect_attr = mdesc->sect_attr & 0x3ff;
458*10465441SEvalZero vaddr = mdesc->vaddr_start;
459*10465441SEvalZero
460*10465441SEvalZero for(i = 0; i < total_page; i++)
461*10465441SEvalZero {
462*10465441SEvalZero pTT = (rt_uint32_t *)_pgd_table + (vaddr >> 20);
463*10465441SEvalZero if (*pTT == 0) /* Level 1 page table item not used, now update pgd item */
464*10465441SEvalZero {
465*10465441SEvalZero *pTT = pte_offset | sect_attr;
466*10465441SEvalZero p_pteentry = (rt_uint32_t *)pte_offset +
467*10465441SEvalZero ((vaddr & 0x000ff000) >> 12);
468*10465441SEvalZero pte_offset += 1024;
469*10465441SEvalZero }
470*10465441SEvalZero else /* using old Level 1 page table item */
471*10465441SEvalZero {
472*10465441SEvalZero p_pteentry = (rt_uint32_t *)(*pTT & 0xfffffc00) +
473*10465441SEvalZero ((vaddr & 0x000ff000) >> 12);
474*10465441SEvalZero }
475*10465441SEvalZero
476*10465441SEvalZero
477*10465441SEvalZero *p_pteentry = mdesc->page_attr | (((mdesc->paddr_start >> 12) + i) << 12);
478*10465441SEvalZero vaddr += 0x1000;
479*10465441SEvalZero }
480*10465441SEvalZero }
481*10465441SEvalZero
build_pte_mem_desc(struct mem_desc * mdesc,rt_uint32_t size)482*10465441SEvalZero static void build_pte_mem_desc(struct mem_desc *mdesc, rt_uint32_t size)
483*10465441SEvalZero {
484*10465441SEvalZero rt_uint32_t pte_offset = 0;
485*10465441SEvalZero rt_uint32_t nsec = 0;
486*10465441SEvalZero /* set page table */
487*10465441SEvalZero for (; size > 0; size--)
488*10465441SEvalZero {
489*10465441SEvalZero if (mdesc->mapped_mode == PAGE_MAPPED)
490*10465441SEvalZero {
491*10465441SEvalZero nsec = (RT_ALIGN(mdesc->vaddr_end, 0x100000) - RT_ALIGN_DOWN(mdesc->vaddr_start, 0x100000)) >> 20;
492*10465441SEvalZero mdesc->sect_attr |= (((rt_uint32_t)_pte_table)& 0xfffffc00) + pte_offset;
493*10465441SEvalZero pte_offset += nsec << 10;
494*10465441SEvalZero }
495*10465441SEvalZero if (pte_offset >= RT_MMU_PTE_SIZE)
496*10465441SEvalZero {
497*10465441SEvalZero rt_kprintf("PTE table size too little\n");
498*10465441SEvalZero RT_ASSERT(0);
499*10465441SEvalZero }
500*10465441SEvalZero
501*10465441SEvalZero mdesc++;
502*10465441SEvalZero }
503*10465441SEvalZero }
504*10465441SEvalZero
505*10465441SEvalZero
rt_hw_mmu_init(struct mem_desc * mdesc,rt_uint32_t size)506*10465441SEvalZero void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
507*10465441SEvalZero {
508*10465441SEvalZero /* disable I/D cache */
509*10465441SEvalZero mmu_disable_dcache();
510*10465441SEvalZero mmu_disable_icache();
511*10465441SEvalZero mmu_disable();
512*10465441SEvalZero mmu_invalidate_tlb();
513*10465441SEvalZero
514*10465441SEvalZero /* clear pgd and pte table */
515*10465441SEvalZero rt_memset((void *)_pgd_table, 0, 16*1024);
516*10465441SEvalZero rt_memset((void *)_pte_table, 0, RT_MMU_PTE_SIZE);
517*10465441SEvalZero build_pte_mem_desc(mdesc, size);
518*10465441SEvalZero /* set page table */
519*10465441SEvalZero for (; size > 0; size--)
520*10465441SEvalZero {
521*10465441SEvalZero if (mdesc->mapped_mode == SECT_MAPPED)
522*10465441SEvalZero {
523*10465441SEvalZero mmu_create_pgd(mdesc);
524*10465441SEvalZero }
525*10465441SEvalZero else
526*10465441SEvalZero {
527*10465441SEvalZero mmu_create_pte(mdesc);
528*10465441SEvalZero }
529*10465441SEvalZero
530*10465441SEvalZero mdesc++;
531*10465441SEvalZero }
532*10465441SEvalZero
533*10465441SEvalZero /* set MMU table address */
534*10465441SEvalZero mmu_setttbase((rt_uint32_t)_pgd_table);
535*10465441SEvalZero
536*10465441SEvalZero /* enables MMU */
537*10465441SEvalZero mmu_enable();
538*10465441SEvalZero
539*10465441SEvalZero /* enable Instruction Cache */
540*10465441SEvalZero mmu_enable_icache();
541*10465441SEvalZero
542*10465441SEvalZero /* enable Data Cache */
543*10465441SEvalZero mmu_enable_dcache();
544*10465441SEvalZero
545*10465441SEvalZero mmu_invalidate_icache();
546*10465441SEvalZero mmu_invalidate_dcache_all();
547*10465441SEvalZero }
548*10465441SEvalZero
549