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 * 2012-01-10 bernard porting to AM1808
9*10465441SEvalZero */
10*10465441SEvalZero
11*10465441SEvalZero #include <rtthread.h>
12*10465441SEvalZero #include <rthw.h>
13*10465441SEvalZero #include <board.h>
14*10465441SEvalZero
15*10465441SEvalZero #include "cp15.h"
16*10465441SEvalZero
17*10465441SEvalZero #define DESC_SEC (0x2)
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 #define XN (1<<4) // eXecute Never
25*10465441SEvalZero
26*10465441SEvalZero #define DOMAIN_FAULT (0x0)
27*10465441SEvalZero #define DOMAIN_CHK (0x1)
28*10465441SEvalZero #define DOMAIN_NOTCHK (0x3)
29*10465441SEvalZero #define DOMAIN0 (0x0<<5)
30*10465441SEvalZero #define DOMAIN1 (0x1<<5)
31*10465441SEvalZero
32*10465441SEvalZero #define DOMAIN0_ATTR (DOMAIN_CHK<<0)
33*10465441SEvalZero #define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
34*10465441SEvalZero
35*10465441SEvalZero /* Read/Write, cache, write back */
36*10465441SEvalZero #define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC)
37*10465441SEvalZero /* Read/Write, cache, write through */
38*10465441SEvalZero #define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC)
39*10465441SEvalZero /* Read/Write without cache and write buffer */
40*10465441SEvalZero #define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC)
41*10465441SEvalZero /* Read/Write without cache and write buffer, no execute */
42*10465441SEvalZero #define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN)
43*10465441SEvalZero /* Read/Write without cache and write buffer */
44*10465441SEvalZero #define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC)
45*10465441SEvalZero
46*10465441SEvalZero /* dump 2nd level page table */
rt_hw_cpu_dump_page_table_2nd(rt_uint32_t * ptb)47*10465441SEvalZero void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
48*10465441SEvalZero {
49*10465441SEvalZero int i;
50*10465441SEvalZero int fcnt = 0;
51*10465441SEvalZero
52*10465441SEvalZero for (i = 0; i < 256; i++)
53*10465441SEvalZero {
54*10465441SEvalZero rt_uint32_t pte2 = ptb[i];
55*10465441SEvalZero if ((pte2 & 0x3) == 0)
56*10465441SEvalZero {
57*10465441SEvalZero if (fcnt == 0)
58*10465441SEvalZero rt_kprintf(" ");
59*10465441SEvalZero rt_kprintf("%04x: ", i);
60*10465441SEvalZero fcnt++;
61*10465441SEvalZero if (fcnt == 16)
62*10465441SEvalZero {
63*10465441SEvalZero rt_kprintf("fault\n");
64*10465441SEvalZero fcnt = 0;
65*10465441SEvalZero }
66*10465441SEvalZero continue;
67*10465441SEvalZero }
68*10465441SEvalZero if (fcnt != 0)
69*10465441SEvalZero {
70*10465441SEvalZero rt_kprintf("fault\n");
71*10465441SEvalZero fcnt = 0;
72*10465441SEvalZero }
73*10465441SEvalZero
74*10465441SEvalZero rt_kprintf(" %04x: %x: ", i, pte2);
75*10465441SEvalZero if ((pte2 & 0x3) == 0x1)
76*10465441SEvalZero {
77*10465441SEvalZero rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
78*10465441SEvalZero ((pte2 >> 7) | (pte2 >> 4))& 0xf,
79*10465441SEvalZero (pte2 >> 15) & 0x1,
80*10465441SEvalZero ((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
81*10465441SEvalZero }
82*10465441SEvalZero else
83*10465441SEvalZero {
84*10465441SEvalZero rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
85*10465441SEvalZero ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
86*10465441SEvalZero ((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
87*10465441SEvalZero }
88*10465441SEvalZero }
89*10465441SEvalZero }
90*10465441SEvalZero
rt_hw_cpu_dump_page_table(rt_uint32_t * ptb)91*10465441SEvalZero void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
92*10465441SEvalZero {
93*10465441SEvalZero int i;
94*10465441SEvalZero int fcnt = 0;
95*10465441SEvalZero
96*10465441SEvalZero rt_kprintf("page table@%p\n", ptb);
97*10465441SEvalZero for (i = 0; i < 1024*4; i++)
98*10465441SEvalZero {
99*10465441SEvalZero rt_uint32_t pte1 = ptb[i];
100*10465441SEvalZero if ((pte1 & 0x3) == 0)
101*10465441SEvalZero {
102*10465441SEvalZero rt_kprintf("%03x: ", i);
103*10465441SEvalZero fcnt++;
104*10465441SEvalZero if (fcnt == 16)
105*10465441SEvalZero {
106*10465441SEvalZero rt_kprintf("fault\n");
107*10465441SEvalZero fcnt = 0;
108*10465441SEvalZero }
109*10465441SEvalZero continue;
110*10465441SEvalZero }
111*10465441SEvalZero if (fcnt != 0)
112*10465441SEvalZero {
113*10465441SEvalZero rt_kprintf("fault\n");
114*10465441SEvalZero fcnt = 0;
115*10465441SEvalZero }
116*10465441SEvalZero
117*10465441SEvalZero rt_kprintf("%03x: %08x: ", i, pte1);
118*10465441SEvalZero if ((pte1 & 0x3) == 0x3)
119*10465441SEvalZero {
120*10465441SEvalZero rt_kprintf("LPAE\n");
121*10465441SEvalZero }
122*10465441SEvalZero else if ((pte1 & 0x3) == 0x1)
123*10465441SEvalZero {
124*10465441SEvalZero rt_kprintf("pte,ns:%d,domain:%d\n",
125*10465441SEvalZero (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
126*10465441SEvalZero /*
127*10465441SEvalZero *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
128*10465441SEvalZero * - 0x80000000 + 0xC0000000));
129*10465441SEvalZero */
130*10465441SEvalZero }
131*10465441SEvalZero else if (pte1 & (1 << 18))
132*10465441SEvalZero {
133*10465441SEvalZero rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
134*10465441SEvalZero (pte1 >> 19) & 0x1,
135*10465441SEvalZero ((pte1 >> 13) | (pte1 >> 10))& 0xf,
136*10465441SEvalZero (pte1 >> 4) & 0x1,
137*10465441SEvalZero ((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
138*10465441SEvalZero }
139*10465441SEvalZero else
140*10465441SEvalZero {
141*10465441SEvalZero rt_kprintf("section,ns:%d,ap:%x,"
142*10465441SEvalZero "xn:%d,texcb:%02x,domain:%d\n",
143*10465441SEvalZero (pte1 >> 19) & 0x1,
144*10465441SEvalZero ((pte1 >> 13) | (pte1 >> 10))& 0xf,
145*10465441SEvalZero (pte1 >> 4) & 0x1,
146*10465441SEvalZero (((pte1 & (0x7 << 12)) >> 10) |
147*10465441SEvalZero ((pte1 & 0x0c) >> 2)) & 0x1f,
148*10465441SEvalZero (pte1 >> 5) & 0xf);
149*10465441SEvalZero }
150*10465441SEvalZero }
151*10465441SEvalZero }
152*10465441SEvalZero
153*10465441SEvalZero /* level1 page table, each entry for 1MB memory. */
154*10465441SEvalZero volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024)));
rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,rt_uint32_t vaddrEnd,rt_uint32_t paddrStart,rt_uint32_t attr)155*10465441SEvalZero void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,
156*10465441SEvalZero rt_uint32_t vaddrEnd,
157*10465441SEvalZero rt_uint32_t paddrStart,
158*10465441SEvalZero rt_uint32_t attr)
159*10465441SEvalZero {
160*10465441SEvalZero volatile rt_uint32_t *pTT;
161*10465441SEvalZero volatile int i, nSec;
162*10465441SEvalZero pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20);
163*10465441SEvalZero nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
164*10465441SEvalZero for(i = 0; i <= nSec; i++)
165*10465441SEvalZero {
166*10465441SEvalZero *pTT = attr | (((paddrStart >> 20) + i) << 20);
167*10465441SEvalZero pTT++;
168*10465441SEvalZero }
169*10465441SEvalZero }
170*10465441SEvalZero
rt_hw_set_domain_register(unsigned long domain_val)171*10465441SEvalZero unsigned long rt_hw_set_domain_register(unsigned long domain_val)
172*10465441SEvalZero {
173*10465441SEvalZero unsigned long old_domain;
174*10465441SEvalZero
175*10465441SEvalZero asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain));
176*10465441SEvalZero asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory");
177*10465441SEvalZero
178*10465441SEvalZero return old_domain;
179*10465441SEvalZero }
180*10465441SEvalZero
rt_hw_mmu_init(void)181*10465441SEvalZero void rt_hw_mmu_init(void)
182*10465441SEvalZero {
183*10465441SEvalZero rt_hw_cpu_dcache_disable();
184*10465441SEvalZero rt_hw_cpu_icache_disable();
185*10465441SEvalZero rt_cpu_mmu_disable();
186*10465441SEvalZero
187*10465441SEvalZero /* set page table */
188*10465441SEvalZero /* 4G 1:1 memory */
189*10465441SEvalZero rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB);
190*10465441SEvalZero /* IO memory region */
191*10465441SEvalZero rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN);
192*10465441SEvalZero
193*10465441SEvalZero /*rt_hw_cpu_dump_page_table(MMUTable);*/
194*10465441SEvalZero rt_hw_set_domain_register(0x55555555);
195*10465441SEvalZero
196*10465441SEvalZero rt_cpu_tlb_set(MMUTable);
197*10465441SEvalZero
198*10465441SEvalZero rt_cpu_mmu_enable();
199*10465441SEvalZero
200*10465441SEvalZero rt_hw_cpu_icache_enable();
201*10465441SEvalZero rt_hw_cpu_dcache_enable();
202*10465441SEvalZero }
203*10465441SEvalZero
204