1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2012-01-10 bernard porting to AM1808
9 * 2019-07-28 zdzn add smp support
10 */
11
12 #include "mmu.h"
13
14 /* dump 2nd level page table */
rt_hw_cpu_dump_page_table_2nd(rt_uint32_t * ptb)15 void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
16 {
17 int i;
18 int fcnt = 0;
19
20 for (i = 0; i < 256; i++)
21 {
22 rt_uint32_t pte2 = ptb[i];
23 if ((pte2 & 0x3) == 0)
24 {
25 if (fcnt == 0)
26 rt_kprintf(" ");
27 rt_kprintf("%04x: ", i);
28 fcnt++;
29 if (fcnt == 16)
30 {
31 rt_kprintf("fault\n");
32 fcnt = 0;
33 }
34 continue;
35 }
36 if (fcnt != 0)
37 {
38 rt_kprintf("fault\n");
39 fcnt = 0;
40 }
41
42 rt_kprintf(" %04x: %x: ", i, pte2);
43 if ((pte2 & 0x3) == 0x1)
44 {
45 rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
46 ((pte2 >> 7) | (pte2 >> 4))& 0xf,
47 (pte2 >> 15) & 0x1,
48 ((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
49 }
50 else
51 {
52 rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
53 ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
54 ((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
55 }
56 }
57 }
58
rt_hw_cpu_dump_page_table(rt_uint32_t * ptb)59 void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
60 {
61 int i;
62 int fcnt = 0;
63
64 rt_kprintf("page table@%p\n", ptb);
65 for (i = 0; i < 1024*4; i++)
66 {
67 rt_uint32_t pte1 = ptb[i];
68 if ((pte1 & 0x3) == 0)
69 {
70 rt_kprintf("%03x: ", i);
71 fcnt++;
72 if (fcnt == 16)
73 {
74 rt_kprintf("fault\n");
75 fcnt = 0;
76 }
77 continue;
78 }
79 if (fcnt != 0)
80 {
81 rt_kprintf("fault\n");
82 fcnt = 0;
83 }
84
85 rt_kprintf("%03x: %08x: ", i, pte1);
86 if ((pte1 & 0x3) == 0x3)
87 {
88 rt_kprintf("LPAE\n");
89 }
90 else if ((pte1 & 0x3) == 0x1)
91 {
92 rt_kprintf("pte,ns:%d,domain:%d\n",
93 (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
94 /*
95 *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
96 * - 0x80000000 + 0xC0000000));
97 */
98 }
99 else if (pte1 & (1 << 18))
100 {
101 rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
102 (pte1 >> 19) & 0x1,
103 ((pte1 >> 13) | (pte1 >> 10))& 0xf,
104 (pte1 >> 4) & 0x1,
105 ((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
106 }
107 else
108 {
109 rt_kprintf("section,ns:%d,ap:%x,"
110 "xn:%d,texcb:%02x,domain:%d\n",
111 (pte1 >> 19) & 0x1,
112 ((pte1 >> 13) | (pte1 >> 10))& 0xf,
113 (pte1 >> 4) & 0x1,
114 (((pte1 & (0x7 << 12)) >> 10) |
115 ((pte1 & 0x0c) >> 2)) & 0x1f,
116 (pte1 >> 5) & 0xf);
117 }
118 }
119 }
120
121 /* level1 page table, each entry for 1MB memory. */
122 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)123 void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,
124 rt_uint32_t vaddrEnd,
125 rt_uint32_t paddrStart,
126 rt_uint32_t attr)
127 {
128 volatile rt_uint32_t *pTT;
129 volatile int i, nSec;
130 pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20);
131 nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
132 for (i = 0; i <= nSec; i++)
133 {
134 *pTT = attr | (((paddrStart >> 20) + i) << 20);
135 pTT++;
136 }
137 }
138
rt_hw_set_domain_register(unsigned long domain_val)139 unsigned long rt_hw_set_domain_register(unsigned long domain_val)
140 {
141 unsigned long old_domain;
142
143 asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain));
144 asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory");
145
146 return old_domain;
147 }
148
rt_hw_init_mmu_table()149 void rt_hw_init_mmu_table()
150 {
151 /* set page table */
152 /* 4G 1:1 memory */
153 rt_hw_mmu_setmtt(0x00000000, 0x3effffff, 0x00000000, NORMAL_MEM);
154 /* IO memory region */
155 rt_hw_mmu_setmtt(0x3f000000, 0x40010000, 0x3f000000, DEVICE_MEM);
156 }
157
rt_hw_change_mmu_table(rt_uint32_t vaddrStart,rt_uint32_t size,rt_uint32_t paddrStart,rt_uint32_t attr)158 void rt_hw_change_mmu_table(rt_uint32_t vaddrStart,
159 rt_uint32_t size,
160 rt_uint32_t paddrStart, rt_uint32_t attr)
161 {
162 rt_hw_mmu_setmtt(vaddrStart, vaddrStart+size-1, paddrStart, attr);
163 #ifndef RT_USING_SMP
164 rt_cpu_dcache_clean_flush();
165 rt_cpu_icache_flush();
166 #endif
167 }
168
169
rt_hw_mmu_init(void)170 void rt_hw_mmu_init(void)
171 {
172 rt_cpu_dcache_clean_flush();
173 rt_cpu_icache_flush();
174 rt_hw_cpu_dcache_disable();
175 rt_hw_cpu_icache_disable();
176 rt_cpu_mmu_disable();
177
178 /*rt_hw_cpu_dump_page_table(MMUTable);*/
179 rt_hw_set_domain_register(0x55555555);
180
181 rt_cpu_tlb_set(MMUTable);
182
183 rt_cpu_mmu_enable();
184
185 rt_hw_cpu_icache_enable();
186 rt_hw_cpu_dcache_enable();
187 }
188
189