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