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 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 */ 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> 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 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 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 256 static void CP0_config2_analyze(unsigned long value) 257 { 258 /* [31] M */ 259 if(value & (1UL<<31)) 260 rt_kprintf(" M"); 261 } 262 263 static void CP0_config3_analyze(unsigned long value) 264 { 265 /* [31] M */ 266 if(value & (1UL<<31)) 267 rt_kprintf(" M"); 268 } 269 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