xref: /nrf52832-nimble/rt-thread/libcpu/mips/xburst/mipscfg.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * File      : mipscfg.c
3  * COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Change Logs:
20  * Date           Author       Notes
21  * 2010-05-27     swkyer       first version
22  */
23 #include <rtthread.h>
24 #include "../common/mipsregs.h"
25 #include "../common/mipscfg.h"
26 
27 mips32_core_cfg_t g_mips_core =
28 {
29     16,     /* icache_line_size */
30     256,    /* icache_lines_per_way */
31     4,      /* icache_ways */
32     16,     /* dcache_line_size */
33     256,    /* dcache_lines_per_way */
34     4,      /* dcache_ways */
35     16,     /* max_tlb_entries */
36 };
37 
m_pow(rt_uint16_t b,rt_uint16_t n)38 static rt_uint16_t m_pow(rt_uint16_t b, rt_uint16_t n)
39 {
40     rt_uint16_t rets = 1;
41 
42     while (n--)
43         rets *= b;
44 
45     return rets;
46 }
47 
48 /**
49  * read core attribute
50  */
mips32_cfg_init(void)51 void mips32_cfg_init(void)
52 {
53     rt_uint16_t val;
54     rt_uint32_t cp0_config1;
55 
56     cp0_config1 = read_c0_config();
57     if (cp0_config1 & 0x80000000)
58     {
59         cp0_config1 = read_c0_config1();
60 
61         val = (cp0_config1 & (7<<22))>>22;
62         g_mips_core.icache_lines_per_way = 64 * m_pow(2, val);
63         val = (cp0_config1 & (7<<19))>>19;
64         g_mips_core.icache_line_size = 2 * m_pow(2, val);
65         val = (cp0_config1 & (7<<16))>>16;
66         g_mips_core.icache_ways = val + 1;
67 
68         val = (cp0_config1 & (7<<13))>>13;
69         g_mips_core.dcache_lines_per_way = 64 * m_pow(2, val);
70         val = (cp0_config1 & (7<<10))>>10;
71         g_mips_core.dcache_line_size = 2 * m_pow(2, val);
72         val = (cp0_config1 & (7<<7))>>7;
73         g_mips_core.dcache_ways = val + 1;
74 
75         val = (cp0_config1 & (0x3F<<25))>>25;
76         g_mips_core.max_tlb_entries = val + 1;
77     }
78 }
79 
80 #ifdef RT_USING_FINSH
81 #include <finsh.h>
CP0_status_analyze(unsigned long value)82 static void CP0_status_analyze(unsigned long value)
83 {
84     if(value & (1<<26))
85         rt_kprintf(" FR");
86     if(value & (1<<23))
87         rt_kprintf(" PX");
88     if(value & (1<<22))
89         rt_kprintf(" BEV");
90     if(value & (1<<20))
91         rt_kprintf(" SR");
92     if(value & (1<<19))
93         rt_kprintf(" NMI");
94     if(value & (1<<20))
95         rt_kprintf(" SR");
96     if(value & (0xFF<<8))
97         rt_kprintf(" IM:0x%02X", (value >> 8) & 0xFF);
98     if(value & (1<<7))
99         rt_kprintf(" KX");
100     if(value & (1<<6))
101         rt_kprintf(" SX");
102     if(value & (1<<5))
103         rt_kprintf(" UX");
104     if(value & (0x03<<3))
105         rt_kprintf(" KSU:0x%02X", (value >> 3) & 0x03);
106     if(value & (1<<2))
107         rt_kprintf(" ERL");
108     if(value & (1<<1))
109         rt_kprintf(" EXL");
110     if(value & (1<<0))
111         rt_kprintf(" IE");
112 }
113 
CP0_config0_analyze(unsigned long value)114 static void CP0_config0_analyze(unsigned long value)
115 {
116     /* [31] M */
117     if(value & (1UL<<31))
118         rt_kprintf(" M");
119 
120     /* [15] BE */
121     if(value & (1<<15))
122         rt_kprintf(" big-endian");
123     else
124         rt_kprintf(" little-endian");
125 
126     /* [14:13] AT */
127     {
128         int AT = (value >> 13) & 0x03;
129 
130         if(AT == 0)
131         {
132             rt_kprintf(" MIPS32");
133         }
134         else if(AT == 1)
135         {
136             rt_kprintf(" MIPS64/A32");
137         }
138         else if(AT == 2)
139         {
140             rt_kprintf(" MIPS64/A64");
141         }
142         else
143         {
144             rt_kprintf(" unkown");
145         }
146     }
147 
148     /* [12:10] AR */
149     {
150         int AR = (value >> 10) & 0x07;
151 
152         if(AR == 0)
153         {
154             rt_kprintf(" R1");
155         }
156         else if(AR == 1)
157         {
158             rt_kprintf(" R2");
159         }
160         else
161         {
162             rt_kprintf(" reserve");
163         }
164     }
165 
166     /* [3] VI */
167     if(value & (1UL<<31))
168         rt_kprintf(" VI");
169 
170     /* [2:0] K0 */
171     {
172         int K0 = value & 0x07;
173 
174         if(K0 == 2)
175         {
176             rt_kprintf(" uncached");
177         }
178         else if(K0 == 3)
179         {
180             rt_kprintf(" cacheable");
181         }
182         else
183         {
184             rt_kprintf(" K0:reserve");
185         }
186     }
187 }
188 
CP0_config1_analyze(unsigned long value)189 static void CP0_config1_analyze(unsigned long value)
190 {
191     /* [31] M */
192     if(value & (1UL<<31))
193         rt_kprintf(" M");
194 
195     /* [30:25] MMU size */
196     {
197         int MMU_size = (value >> 25) & 0x3F;
198         rt_kprintf(" TLB:%d", MMU_size + 1);
199     }
200 
201     /* [24:22] IS, [21:19] IL, [18:16] IA */
202     {
203         int IS = (value >> 22) & 0x07;
204         int IL = (value >> 19) & 0x07;
205         int IA = (value >> 16) & 0x07;
206 
207         IA = IA + 1;
208         IS = 64 << IS;
209         IL = 2 << IL;
210         rt_kprintf(" Icache-%dKB:%dway*%dset*%dbyte",
211                    (IA*IS*IL) >> 10, IA, IS, IL);
212     }
213 
214     /* [15:13] DS, [12:10] DL, [9:7] DA */
215     {
216         int DS = (value >> 13) & 0x07;
217         int DL = (value >> 10) & 0x07;
218         int DA = (value >> 7)  & 0x07;
219 
220         DA = DA + 1;
221         DS = 64 << DS;
222         DL = 2 << DL;
223         rt_kprintf(" Dcache-%dKB:%dway*%dset*%dbyte",
224                    (DA*DS*DL) >> 10, DA, DS, DL);
225     }
226 
227     /* [6] C2 */
228     if(value & (1UL<<6))
229         rt_kprintf(" CP2");
230 
231     /* [5] MD */
232     if(value & (1UL<<5))
233         rt_kprintf(" MDMX-ASE");
234 
235     /* [4] PC */
236     if(value & (1UL<<4))
237         rt_kprintf(" performa-count");
238 
239     /* [3] WR */
240     if(value & (1UL<<3))
241         rt_kprintf(" Watch");
242 
243     /* [2] CA */
244     if(value & (1UL<<2))
245         rt_kprintf(" MIPS16e");
246 
247     /* [1] EP */
248     if(value & (1UL<<1))
249         rt_kprintf(" EJTAG");
250 
251     /* [0] FP */
252     if(value & (1UL<<0))
253         rt_kprintf(" FPU");
254 }
255 
CP0_config2_analyze(unsigned long value)256 static void CP0_config2_analyze(unsigned long value)
257 {
258     /* [31] M */
259     if(value & (1UL<<31))
260         rt_kprintf(" M");
261 }
262 
CP0_config3_analyze(unsigned long value)263 static void CP0_config3_analyze(unsigned long value)
264 {
265     /* [31] M */
266     if(value & (1UL<<31))
267         rt_kprintf(" M");
268 }
269 
list_mips(void)270 static void list_mips(void)
271 {
272     unsigned long value;
273     unsigned long num = 0;
274 
275     rt_kprintf("MIPS coprocessor register:\r\n");
276 
277     rt_kprintf("( 0,0) INDEX     : 0x%08X\r\n", read_c0_index());
278     rt_kprintf("( 1,0) RANDOM    : 0x%08X\r\n", read_c0_random());
279     rt_kprintf("( 2,0) ENTRYLO0  : 0x%08X\r\n", read_c0_entrylo0());
280     rt_kprintf("( 3,0) ENTRYLO1  : 0x%08X\r\n", read_c0_entrylo1());
281     rt_kprintf("( 4,0) CONTEXT   : 0x%08X\r\n", read_c0_context());
282     rt_kprintf("( 5,0) PAGEMASK  : 0x%08X\r\n", read_c0_pagemask());
283     rt_kprintf("( 6,0) WIRED     : 0x%08X\r\n", read_c0_wired());
284     rt_kprintf("( 7,0) INFO      : 0x%08X\r\n", read_c0_info());
285     rt_kprintf("( 8,0) BADVADDR  : 0x%08X\r\n", read_c0_badvaddr());
286     rt_kprintf("( 9,0) COUNT     : 0x%08X\r\n", read_c0_count());
287     rt_kprintf("(10,0) ENTRYHI   : 0x%08X\r\n", read_c0_entryhi());
288     rt_kprintf("(11,0) COMPARE   : 0x%08X\r\n", read_c0_compare());
289 
290     value = read_c0_status();
291     rt_kprintf("(12,0) STATUS    : 0x%08X", value);
292     CP0_status_analyze(value);
293     rt_kprintf("\r\n");
294 
295     /*
296     rt_kprintf("(12,1) INTCTL    : 0x%08X\r\n", __read_32bit_c0_register(12, 1));
297     rt_kprintf("(12,2) SRSCTL    : 0x%08X\r\n", __read_32bit_c0_register(12, 2));
298     */
299 
300     rt_kprintf("(13,0) CAUSE     : 0x%08X\r\n", read_c0_cause());
301     rt_kprintf("(14,0) EPC       : 0x%08X\r\n", read_c0_epc());
302     rt_kprintf("(15,0) PRID      : 0x%08X\r\n", read_c0_prid());
303     rt_kprintf("(15,1) EBASE     : 0x%08X\r\n", read_c0_ebase());
304 
305     value = read_c0_config();
306     rt_kprintf("(16,0) CONFIG    : 0x%08X", value);
307     CP0_config0_analyze(value);
308     rt_kprintf("\r\n");
309     if(value & (1UL << 31))
310     {
311         value = read_c0_config1();
312         rt_kprintf("(16,1) CONFIG1   : 0x%08X", value);
313         CP0_config1_analyze(value);
314         rt_kprintf("\r\n");
315 
316         if(value & (1UL << 31))
317         {
318             value = read_c0_config2();
319             rt_kprintf("(16,2) CONFIG2   : 0x%08X\r\n", value);
320             CP0_config2_analyze(value);
321             rt_kprintf("\r\n");
322 
323             if(value & (1UL << 31))
324             {
325                 value = read_c0_config3();
326                 rt_kprintf("(16,3) CONFIG3   : 0x%08X\r\n", value);
327                 CP0_config3_analyze(value);
328                 rt_kprintf("\r\n");
329             }
330         }
331     }
332 
333     rt_kprintf("(17,0) LLADDR    : 0x%08X\r\n", __read_32bit_c0_register($17, 0));
334     rt_kprintf("(18,0) WATCHLO   : 0x%08X\r\n", __read_32bit_c0_register($18, 0));
335     rt_kprintf("(19,0) WATCHHI   : 0x%08X\r\n", __read_32bit_c0_register($19, 0));
336     rt_kprintf("(20,0) XCONTEXT  : 0x%08X\r\n", __read_32bit_c0_register($20, 0));
337     rt_kprintf("(21,0) FRAMEMASK : 0x%08X\r\n", __read_32bit_c0_register($21, 0));
338     rt_kprintf("(22,0) DIAGNOSTIC: 0x%08X\r\n", __read_32bit_c0_register($22, 0));
339     rt_kprintf("(23,0) DEBUG     : 0x%08X\r\n", __read_32bit_c0_register($23, 0));
340     rt_kprintf("(24,0) DEPC      : 0x%08X\r\n", __read_32bit_c0_register($24, 0));
341 
342     rt_kprintf("(25,0) PERFCTL0  : 0x%08X\r\n", __read_32bit_c0_register($25, 0));
343     rt_kprintf("(26,0) ECC       : 0x%08X\r\n", __read_32bit_c0_register($26, 0));
344     rt_kprintf("(27,0) CACHEERR  : 0x%08X\r\n", __read_32bit_c0_register($27, 0));
345     rt_kprintf("(28,0) TAGLO     : 0x%08X\r\n", __read_32bit_c0_register($28, 0));
346     rt_kprintf("(29,0) TAGHI     : 0x%08X\r\n", __read_32bit_c0_register($29, 0));
347 
348     /*
349     rt_kprintf("(30,0) ERROREPC  : 0x%08X\r\n", __read_32bit_c0_register($30, 0));
350     rt_kprintf("(31,0) DESAVE    : 0x%08X\r\n", __read_32bit_c0_register($31, 0));
351     */
352 
353 
354     rt_kprintf("\r\n");
355 }
356 FINSH_FUNCTION_EXPORT(list_mips, list  CPU info)
357 #endif /* RT_USING_FINSH */
358 
359