xref: /nrf52832-nimble/rt-thread/libcpu/arm/s3c24x0/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  * 2008-04-25     Yi.qiu       first version
9*10465441SEvalZero  * 2009-12-18     Bernard      port to armcc
10*10465441SEvalZero  */
11*10465441SEvalZero 
12*10465441SEvalZero #include <rtthread.h>
13*10465441SEvalZero #include "s3c24x0.h"
14*10465441SEvalZero 
15*10465441SEvalZero #define _MMUTT_STARTADDRESS	 0x33FF0000
16*10465441SEvalZero 
17*10465441SEvalZero #define DESC_SEC		(0x2|(1<<4))
18*10465441SEvalZero #define CB				(3<<2)  //cache_on, write_back
19*10465441SEvalZero #define CNB				(2<<2)  //cache_on, write_through
20*10465441SEvalZero #define NCB				(1<<2)  //cache_off,WR_BUF on
21*10465441SEvalZero #define NCNB				(0<<2)  //cache_off,WR_BUF off
22*10465441SEvalZero #define AP_RW			(3<<10) //supervisor=RW, user=RW
23*10465441SEvalZero #define AP_RO			(2<<10) //supervisor=RW, user=RO
24*10465441SEvalZero 
25*10465441SEvalZero #define DOMAIN_FAULT	(0x0)
26*10465441SEvalZero #define DOMAIN_CHK		(0x1)
27*10465441SEvalZero #define DOMAIN_NOTCHK	(0x3)
28*10465441SEvalZero #define DOMAIN0			(0x0<<5)
29*10465441SEvalZero #define DOMAIN1			(0x1<<5)
30*10465441SEvalZero 
31*10465441SEvalZero #define DOMAIN0_ATTR	(DOMAIN_CHK<<0)
32*10465441SEvalZero #define DOMAIN1_ATTR	(DOMAIN_FAULT<<2)
33*10465441SEvalZero 
34*10465441SEvalZero #define RW_CB		(AP_RW|DOMAIN0|CB|DESC_SEC)
35*10465441SEvalZero #define RW_CNB		(AP_RW|DOMAIN0|CNB|DESC_SEC)
36*10465441SEvalZero #define RW_NCNB		(AP_RW|DOMAIN0|NCNB|DESC_SEC)
37*10465441SEvalZero #define RW_FAULT	(AP_RW|DOMAIN1|NCNB|DESC_SEC)
38*10465441SEvalZero 
39*10465441SEvalZero #ifdef __GNUC__
mmu_setttbase(register rt_uint32_t i)40*10465441SEvalZero void mmu_setttbase(register rt_uint32_t i)
41*10465441SEvalZero {
42*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c2, c0, 0": :"r" (i));
43*10465441SEvalZero }
44*10465441SEvalZero 
mmu_set_domain(register rt_uint32_t i)45*10465441SEvalZero void mmu_set_domain(register rt_uint32_t i)
46*10465441SEvalZero {
47*10465441SEvalZero 	asm volatile ("mcr p15,0, %0, c3, c0,  0": :"r" (i));
48*10465441SEvalZero }
49*10465441SEvalZero 
mmu_enable()50*10465441SEvalZero void mmu_enable()
51*10465441SEvalZero {
52*10465441SEvalZero 	register rt_uint32_t i;
53*10465441SEvalZero 
54*10465441SEvalZero 	/* read control register */
55*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
56*10465441SEvalZero 
57*10465441SEvalZero 	i |= 0x1;
58*10465441SEvalZero 
59*10465441SEvalZero 	/* write back to control register */
60*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
61*10465441SEvalZero }
62*10465441SEvalZero 
mmu_disable()63*10465441SEvalZero void mmu_disable()
64*10465441SEvalZero {
65*10465441SEvalZero 	register rt_uint32_t i;
66*10465441SEvalZero 
67*10465441SEvalZero 	/* read control register */
68*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
69*10465441SEvalZero 
70*10465441SEvalZero 	i &= ~0x1;
71*10465441SEvalZero 
72*10465441SEvalZero 	/* write back to control register */
73*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
74*10465441SEvalZero }
75*10465441SEvalZero 
mmu_enable_icache()76*10465441SEvalZero void mmu_enable_icache()
77*10465441SEvalZero {
78*10465441SEvalZero 	register rt_uint32_t i;
79*10465441SEvalZero 
80*10465441SEvalZero 	/* read control register */
81*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
82*10465441SEvalZero 
83*10465441SEvalZero 	i |= (1 << 12);
84*10465441SEvalZero 
85*10465441SEvalZero 	/* write back to control register */
86*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
87*10465441SEvalZero }
88*10465441SEvalZero 
mmu_enable_dcache()89*10465441SEvalZero void mmu_enable_dcache()
90*10465441SEvalZero {
91*10465441SEvalZero 	register rt_uint32_t i;
92*10465441SEvalZero 
93*10465441SEvalZero 	/* read control register */
94*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
95*10465441SEvalZero 
96*10465441SEvalZero 	i |= (1 << 2);
97*10465441SEvalZero 
98*10465441SEvalZero 	/* write back to control register */
99*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
100*10465441SEvalZero }
101*10465441SEvalZero 
mmu_disable_icache()102*10465441SEvalZero void mmu_disable_icache()
103*10465441SEvalZero {
104*10465441SEvalZero 	register rt_uint32_t i;
105*10465441SEvalZero 
106*10465441SEvalZero 	/* read control register */
107*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
108*10465441SEvalZero 
109*10465441SEvalZero 	i &= ~(1 << 12);
110*10465441SEvalZero 
111*10465441SEvalZero 	/* write back to control register */
112*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
113*10465441SEvalZero }
114*10465441SEvalZero 
mmu_disable_dcache()115*10465441SEvalZero void mmu_disable_dcache()
116*10465441SEvalZero {
117*10465441SEvalZero 	register rt_uint32_t i;
118*10465441SEvalZero 
119*10465441SEvalZero 	/* read control register */
120*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
121*10465441SEvalZero 
122*10465441SEvalZero 	i &= ~(1 << 2);
123*10465441SEvalZero 
124*10465441SEvalZero 	/* write back to control register */
125*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
126*10465441SEvalZero }
127*10465441SEvalZero 
mmu_enable_alignfault()128*10465441SEvalZero void mmu_enable_alignfault()
129*10465441SEvalZero {
130*10465441SEvalZero 	register rt_uint32_t i;
131*10465441SEvalZero 
132*10465441SEvalZero 	/* read control register */
133*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
134*10465441SEvalZero 
135*10465441SEvalZero 	i |= (1 << 1);
136*10465441SEvalZero 
137*10465441SEvalZero 	/* write back to control register */
138*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
139*10465441SEvalZero }
140*10465441SEvalZero 
mmu_disable_alignfault()141*10465441SEvalZero void mmu_disable_alignfault()
142*10465441SEvalZero {
143*10465441SEvalZero 	register rt_uint32_t i;
144*10465441SEvalZero 
145*10465441SEvalZero 	/* read control register */
146*10465441SEvalZero 	asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
147*10465441SEvalZero 
148*10465441SEvalZero 	i &= ~(1 << 1);
149*10465441SEvalZero 
150*10465441SEvalZero 	/* write back to control register */
151*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
152*10465441SEvalZero }
153*10465441SEvalZero 
mmu_clean_invalidated_cache_index(int index)154*10465441SEvalZero void mmu_clean_invalidated_cache_index(int index)
155*10465441SEvalZero {
156*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
157*10465441SEvalZero }
158*10465441SEvalZero 
mmu_invalidate_tlb()159*10465441SEvalZero void mmu_invalidate_tlb()
160*10465441SEvalZero {
161*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
162*10465441SEvalZero }
163*10465441SEvalZero 
mmu_invalidate_icache()164*10465441SEvalZero void mmu_invalidate_icache()
165*10465441SEvalZero {
166*10465441SEvalZero 	asm volatile ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
167*10465441SEvalZero }
168*10465441SEvalZero #endif
169*10465441SEvalZero 
170*10465441SEvalZero #ifdef __CC_ARM
mmu_setttbase(rt_uint32_t i)171*10465441SEvalZero void mmu_setttbase(rt_uint32_t i)
172*10465441SEvalZero {
173*10465441SEvalZero     __asm volatile
174*10465441SEvalZero     {
175*10465441SEvalZero         mcr p15, 0, i, c2, c0, 0
176*10465441SEvalZero     }
177*10465441SEvalZero }
178*10465441SEvalZero 
mmu_set_domain(rt_uint32_t i)179*10465441SEvalZero void mmu_set_domain(rt_uint32_t i)
180*10465441SEvalZero {
181*10465441SEvalZero     __asm volatile
182*10465441SEvalZero     {
183*10465441SEvalZero         mcr p15,0, i, c3, c0,  0
184*10465441SEvalZero     }
185*10465441SEvalZero }
186*10465441SEvalZero 
mmu_enable()187*10465441SEvalZero void mmu_enable()
188*10465441SEvalZero {
189*10465441SEvalZero     register rt_uint32_t value;
190*10465441SEvalZero 
191*10465441SEvalZero     __asm volatile
192*10465441SEvalZero     {
193*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
194*10465441SEvalZero         orr value, value, #0x01
195*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
196*10465441SEvalZero     }
197*10465441SEvalZero }
198*10465441SEvalZero 
mmu_disable()199*10465441SEvalZero void mmu_disable()
200*10465441SEvalZero {
201*10465441SEvalZero     register rt_uint32_t value;
202*10465441SEvalZero 
203*10465441SEvalZero     __asm volatile
204*10465441SEvalZero     {
205*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
206*10465441SEvalZero         bic value, value, #0x01
207*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
208*10465441SEvalZero     }
209*10465441SEvalZero }
210*10465441SEvalZero 
mmu_enable_icache()211*10465441SEvalZero void mmu_enable_icache()
212*10465441SEvalZero {
213*10465441SEvalZero     register rt_uint32_t value;
214*10465441SEvalZero 
215*10465441SEvalZero     __asm volatile
216*10465441SEvalZero     {
217*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
218*10465441SEvalZero         orr value, value, #0x1000
219*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
220*10465441SEvalZero     }
221*10465441SEvalZero }
222*10465441SEvalZero 
mmu_enable_dcache()223*10465441SEvalZero void mmu_enable_dcache()
224*10465441SEvalZero {
225*10465441SEvalZero     register rt_uint32_t value;
226*10465441SEvalZero 
227*10465441SEvalZero     __asm volatile
228*10465441SEvalZero     {
229*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
230*10465441SEvalZero         orr value, value, #0x04
231*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
232*10465441SEvalZero     }
233*10465441SEvalZero }
234*10465441SEvalZero 
mmu_disable_icache()235*10465441SEvalZero void mmu_disable_icache()
236*10465441SEvalZero {
237*10465441SEvalZero     register rt_uint32_t value;
238*10465441SEvalZero 
239*10465441SEvalZero     __asm volatile
240*10465441SEvalZero     {
241*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
242*10465441SEvalZero         bic value, value, #0x1000
243*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
244*10465441SEvalZero     }
245*10465441SEvalZero }
246*10465441SEvalZero 
mmu_disable_dcache()247*10465441SEvalZero void mmu_disable_dcache()
248*10465441SEvalZero {
249*10465441SEvalZero     register rt_uint32_t value;
250*10465441SEvalZero 
251*10465441SEvalZero     __asm volatile
252*10465441SEvalZero     {
253*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
254*10465441SEvalZero         bic value, value, #0x04
255*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
256*10465441SEvalZero     }
257*10465441SEvalZero }
258*10465441SEvalZero 
mmu_enable_alignfault()259*10465441SEvalZero void mmu_enable_alignfault()
260*10465441SEvalZero {
261*10465441SEvalZero     register rt_uint32_t value;
262*10465441SEvalZero 
263*10465441SEvalZero     __asm volatile
264*10465441SEvalZero     {
265*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
266*10465441SEvalZero         orr value, value, #0x02
267*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
268*10465441SEvalZero     }
269*10465441SEvalZero }
270*10465441SEvalZero 
mmu_disable_alignfault()271*10465441SEvalZero void mmu_disable_alignfault()
272*10465441SEvalZero {
273*10465441SEvalZero     register rt_uint32_t value;
274*10465441SEvalZero 
275*10465441SEvalZero     __asm volatile
276*10465441SEvalZero     {
277*10465441SEvalZero         mrc p15, 0, value, c1, c0, 0
278*10465441SEvalZero         bic value, value, #0x02
279*10465441SEvalZero         mcr p15, 0, value, c1, c0, 0
280*10465441SEvalZero     }
281*10465441SEvalZero }
282*10465441SEvalZero 
mmu_clean_invalidated_cache_index(int index)283*10465441SEvalZero void mmu_clean_invalidated_cache_index(int index)
284*10465441SEvalZero {
285*10465441SEvalZero     __asm volatile
286*10465441SEvalZero     {
287*10465441SEvalZero         mcr p15, 0, index, c7, c14, 2
288*10465441SEvalZero     }
289*10465441SEvalZero }
290*10465441SEvalZero 
mmu_invalidate_tlb()291*10465441SEvalZero void mmu_invalidate_tlb()
292*10465441SEvalZero {
293*10465441SEvalZero     register rt_uint32_t value;
294*10465441SEvalZero 
295*10465441SEvalZero     value = 0;
296*10465441SEvalZero     __asm volatile
297*10465441SEvalZero     {
298*10465441SEvalZero         mcr p15, 0, value, c8, c7, 0
299*10465441SEvalZero     }
300*10465441SEvalZero }
301*10465441SEvalZero 
mmu_invalidate_icache()302*10465441SEvalZero void mmu_invalidate_icache()
303*10465441SEvalZero {
304*10465441SEvalZero     register rt_uint32_t value;
305*10465441SEvalZero 
306*10465441SEvalZero     value = 0;
307*10465441SEvalZero 
308*10465441SEvalZero     __asm volatile
309*10465441SEvalZero     {
310*10465441SEvalZero         mcr p15, 0, value, c7, c5, 0
311*10465441SEvalZero     }
312*10465441SEvalZero }
313*10465441SEvalZero #endif
314*10465441SEvalZero 
mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr)315*10465441SEvalZero void mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
316*10465441SEvalZero {
317*10465441SEvalZero     volatile rt_uint32_t *pTT;
318*10465441SEvalZero     volatile int i,nSec;
319*10465441SEvalZero     pTT=(rt_uint32_t *)_MMUTT_STARTADDRESS+(vaddrStart>>20);
320*10465441SEvalZero     nSec=(vaddrEnd>>20)-(vaddrStart>>20);
321*10465441SEvalZero     for(i=0;i<=nSec;i++)
322*10465441SEvalZero     {
323*10465441SEvalZero 		*pTT = attr |(((paddrStart>>20)+i)<<20);
324*10465441SEvalZero 		pTT++;
325*10465441SEvalZero     }
326*10465441SEvalZero }
327*10465441SEvalZero 
rt_hw_mmu_init(void)328*10465441SEvalZero void rt_hw_mmu_init(void)
329*10465441SEvalZero {
330*10465441SEvalZero 	int i,j;
331*10465441SEvalZero 	//========================== IMPORTANT NOTE =========================
332*10465441SEvalZero 	//The current stack and code area can't be re-mapped in this routine.
333*10465441SEvalZero 	//If you want memory map mapped freely, your own sophiscated mmu
334*10465441SEvalZero 	//initialization code is needed.
335*10465441SEvalZero 	//===================================================================
336*10465441SEvalZero 
337*10465441SEvalZero 	mmu_disable_dcache();
338*10465441SEvalZero 	mmu_disable_icache();
339*10465441SEvalZero 
340*10465441SEvalZero 	//If write-back is used,the DCache should be cleared.
341*10465441SEvalZero 	for(i=0;i<64;i++)
342*10465441SEvalZero 		for(j=0;j<8;j++)
343*10465441SEvalZero 			mmu_clean_invalidated_cache_index((i<<26)|(j<<5));
344*10465441SEvalZero 
345*10465441SEvalZero 	mmu_invalidate_icache();
346*10465441SEvalZero 
347*10465441SEvalZero 	//To complete mmu_Init() fast, Icache may be turned on here.
348*10465441SEvalZero 	mmu_enable_icache();
349*10465441SEvalZero 
350*10465441SEvalZero 	mmu_disable();
351*10465441SEvalZero 	mmu_invalidate_tlb();
352*10465441SEvalZero 
353*10465441SEvalZero 	//mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr);
354*10465441SEvalZero 	mmu_setmtt(0x00000000,0x07f00000,0x00000000,RW_CNB);  //bank0
355*10465441SEvalZero 	mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB);  //bank0
356*10465441SEvalZero 	mmu_setmtt(0x04000000,0x07f00000,0,RW_NCNB);  			//bank0
357*10465441SEvalZero 	mmu_setmtt(0x08000000,0x0ff00000,0x08000000,RW_CNB);  //bank1
358*10465441SEvalZero 	mmu_setmtt(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2
359*10465441SEvalZero 	mmu_setmtt(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3
360*10465441SEvalZero 	//mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4
361*10465441SEvalZero 	mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_NCNB); //bank4 for  DM9000
362*10465441SEvalZero 	mmu_setmtt(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5
363*10465441SEvalZero 	//30f00000->30100000, 31000000->30200000
364*10465441SEvalZero 	mmu_setmtt(0x30000000,0x30100000,0x30000000,RW_CB);	  //bank6-1
365*10465441SEvalZero 	mmu_setmtt(0x30200000,0x33e00000,0x30200000,RW_CB); //bank6-2
366*10465441SEvalZero 
367*10465441SEvalZero 	mmu_setmtt(0x33f00000,0x34000000,0x33f00000,RW_NCNB);   //bank6-3
368*10465441SEvalZero 	mmu_setmtt(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7
369*10465441SEvalZero 
370*10465441SEvalZero 	mmu_setmtt(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR
371*10465441SEvalZero 	mmu_setmtt(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR
372*10465441SEvalZero 	mmu_setmtt(0x5b000000,0x5b000000,0x5b000000,RW_NCNB); //SFR
373*10465441SEvalZero 	mmu_setmtt(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//not used
374*10465441SEvalZero 	mmu_setmtt(0x60000000,0x67f00000,0x60000000,RW_NCNB); //SFR
375*10465441SEvalZero 
376*10465441SEvalZero 	mmu_setttbase(_MMUTT_STARTADDRESS);
377*10465441SEvalZero 
378*10465441SEvalZero 	/* DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked) */
379*10465441SEvalZero 	mmu_set_domain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR);
380*10465441SEvalZero 
381*10465441SEvalZero 	mmu_enable_alignfault();
382*10465441SEvalZero 
383*10465441SEvalZero 	mmu_enable();
384*10465441SEvalZero 
385*10465441SEvalZero 	/* ICache enable */
386*10465441SEvalZero 	mmu_enable_icache();
387*10465441SEvalZero 	/* DCache should be turned on after mmu is turned on. */
388*10465441SEvalZero 	mmu_enable_dcache();
389*10465441SEvalZero }
390*10465441SEvalZero 
391