xref: /nrf52832-nimble/rt-thread/libcpu/arm/dm36x/mmu.c (revision 104654410c56c573564690304ae786df310c91fc)
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 	i |= (1 << 13); /* High exception vectors selected, address range = 0xFFFF0000-0xFFFF001C */
263*10465441SEvalZero 	/* S R bit=1 0  for system protection */
264*10465441SEvalZero 	i |= (1 << 8);
265*10465441SEvalZero 	i &= ~(1 << 9);
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 static volatile unsigned int _pte_table[RT_MMU_PTE_SIZE] ALIGN(1*1024);
430*10465441SEvalZero 
mmu_create_pgd(struct mem_desc * mdesc)431*10465441SEvalZero void mmu_create_pgd(struct mem_desc *mdesc)
432*10465441SEvalZero {
433*10465441SEvalZero     volatile rt_uint32_t *pTT;
434*10465441SEvalZero     volatile int i, nSec;
435*10465441SEvalZero     pTT = (rt_uint32_t *)_pgd_table + (mdesc->vaddr_start >> 20);
436*10465441SEvalZero     nSec = (mdesc->vaddr_end >> 20) - (mdesc->vaddr_start >> 20);
437*10465441SEvalZero     for(i = 0; i <= nSec; i++)
438*10465441SEvalZero     {
439*10465441SEvalZero         *pTT = mdesc->sect_attr | (((mdesc->paddr_start >> 20) + i) << 20);
440*10465441SEvalZero         pTT++;
441*10465441SEvalZero     }
442*10465441SEvalZero }
443*10465441SEvalZero 
mmu_create_pte(struct mem_desc * mdesc)444*10465441SEvalZero void mmu_create_pte(struct mem_desc *mdesc)
445*10465441SEvalZero {
446*10465441SEvalZero     volatile rt_uint32_t *pTT;
447*10465441SEvalZero     volatile rt_uint32_t *p_pteentry;
448*10465441SEvalZero     int i;
449*10465441SEvalZero     rt_uint32_t vaddr;
450*10465441SEvalZero     rt_uint32_t total_page = 0;
451*10465441SEvalZero     rt_uint32_t pte_offset = 0;
452*10465441SEvalZero     rt_uint32_t sect_attr = 0;
453*10465441SEvalZero 
454*10465441SEvalZero     total_page = (mdesc->vaddr_end >> 12) - (mdesc->vaddr_start >> 12) + 1;
455*10465441SEvalZero     pte_offset = mdesc->sect_attr & 0xfffffc00;
456*10465441SEvalZero     sect_attr = mdesc->sect_attr & 0x3ff;
457*10465441SEvalZero     vaddr = mdesc->vaddr_start;
458*10465441SEvalZero 
459*10465441SEvalZero     for(i = 0; i < total_page; i++)
460*10465441SEvalZero     {
461*10465441SEvalZero         pTT = (rt_uint32_t *)_pgd_table + (vaddr >> 20);
462*10465441SEvalZero         if (*pTT == 0) /* Level 1 page table item not used, now update pgd item */
463*10465441SEvalZero         {
464*10465441SEvalZero             *pTT = pte_offset | sect_attr;
465*10465441SEvalZero             p_pteentry = (rt_uint32_t *)pte_offset +
466*10465441SEvalZero             ((vaddr & 0x000ff000) >> 12);
467*10465441SEvalZero             pte_offset += 1024;
468*10465441SEvalZero         }
469*10465441SEvalZero         else /* using old Level 1 page table item */
470*10465441SEvalZero         {
471*10465441SEvalZero             p_pteentry = (rt_uint32_t *)(*pTT & 0xfffffc00) +
472*10465441SEvalZero             ((vaddr & 0x000ff000) >> 12);
473*10465441SEvalZero         }
474*10465441SEvalZero 
475*10465441SEvalZero 
476*10465441SEvalZero         *p_pteentry = mdesc->page_attr | (((mdesc->paddr_start >> 12) + i) << 12);
477*10465441SEvalZero         vaddr += 0x1000;
478*10465441SEvalZero     }
479*10465441SEvalZero }
480*10465441SEvalZero 
build_pte_mem_desc(struct mem_desc * mdesc,rt_uint32_t size)481*10465441SEvalZero static void build_pte_mem_desc(struct mem_desc *mdesc, rt_uint32_t size)
482*10465441SEvalZero {
483*10465441SEvalZero     rt_uint32_t pte_offset = 0;
484*10465441SEvalZero     rt_uint32_t nsec = 0;
485*10465441SEvalZero     /* set page table */
486*10465441SEvalZero     for (; size > 0; size--)
487*10465441SEvalZero     {
488*10465441SEvalZero         if (mdesc->mapped_mode == PAGE_MAPPED)
489*10465441SEvalZero         {
490*10465441SEvalZero             nsec = (RT_ALIGN(mdesc->vaddr_end, 0x100000) - RT_ALIGN_DOWN(mdesc->vaddr_start, 0x100000)) >> 20;
491*10465441SEvalZero             mdesc->sect_attr |= (((rt_uint32_t)_pte_table)& 0xfffffc00) + pte_offset;
492*10465441SEvalZero             pte_offset += nsec << 10;
493*10465441SEvalZero         }
494*10465441SEvalZero         if (pte_offset >= RT_MMU_PTE_SIZE)
495*10465441SEvalZero         {
496*10465441SEvalZero             rt_kprintf("PTE table size too little\n");
497*10465441SEvalZero             RT_ASSERT(0);
498*10465441SEvalZero         }
499*10465441SEvalZero 
500*10465441SEvalZero         mdesc++;
501*10465441SEvalZero     }
502*10465441SEvalZero }
503*10465441SEvalZero 
rt_hw_mmu_init(struct mem_desc * mdesc,rt_uint32_t size)504*10465441SEvalZero void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
505*10465441SEvalZero {
506*10465441SEvalZero 	/* disable I/D cache */
507*10465441SEvalZero 	mmu_disable_dcache();
508*10465441SEvalZero 	mmu_disable_icache();
509*10465441SEvalZero 	mmu_disable();
510*10465441SEvalZero 	mmu_invalidate_tlb();
511*10465441SEvalZero 
512*10465441SEvalZero 	/* clear pgd and pte table */
513*10465441SEvalZero     rt_memset((void *)_pgd_table, 0, 16*1024);
514*10465441SEvalZero     rt_memset((void *)_pte_table, 0, RT_MMU_PTE_SIZE);
515*10465441SEvalZero     build_pte_mem_desc(mdesc, size);
516*10465441SEvalZero     /* set page table */
517*10465441SEvalZero     for (; size > 0; size--)
518*10465441SEvalZero     {
519*10465441SEvalZero         if (mdesc->mapped_mode == SECT_MAPPED)
520*10465441SEvalZero         {
521*10465441SEvalZero             mmu_create_pgd(mdesc);
522*10465441SEvalZero         }
523*10465441SEvalZero         else
524*10465441SEvalZero         {
525*10465441SEvalZero             mmu_create_pte(mdesc);
526*10465441SEvalZero         }
527*10465441SEvalZero 
528*10465441SEvalZero         mdesc++;
529*10465441SEvalZero     }
530*10465441SEvalZero 
531*10465441SEvalZero     /* set MMU table address */
532*10465441SEvalZero     mmu_setttbase((rt_uint32_t)_pgd_table);
533*10465441SEvalZero 
534*10465441SEvalZero     /* enables MMU */
535*10465441SEvalZero     mmu_enable();
536*10465441SEvalZero 
537*10465441SEvalZero     /* enable Instruction Cache */
538*10465441SEvalZero     mmu_enable_icache();
539*10465441SEvalZero 
540*10465441SEvalZero     /* enable Data Cache */
541*10465441SEvalZero     mmu_enable_dcache();
542*10465441SEvalZero 
543*10465441SEvalZero     mmu_invalidate_icache();
544*10465441SEvalZero     mmu_invalidate_dcache_all();
545*10465441SEvalZero }
546*10465441SEvalZero 
547