1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * All you never wanted to know about CPUs File: ui_cpuinfo.c 5 * 6 * Routines to display CPU info (common to all CPUs) 7 * 8 * Author: Mitch Lichtenberg 9 * 10 ********************************************************************* 11 * 12 * Copyright 2000,2001,2002,2003,2004,2005 13 * Broadcom Corporation. All rights reserved. 14 * 15 * This software is furnished under license and may be used and 16 * copied only in accordance with the following terms and 17 * conditions. Subject to these conditions, you may download, 18 * copy, install, use, modify and distribute modified or unmodified 19 * copies of this software in source and/or binary form. No title 20 * or ownership is transferred hereby. 21 * 22 * 1) Any source code used, modified or distributed must reproduce 23 * and retain this copyright notice and list of conditions 24 * as they appear in the source file. 25 * 26 * 2) No right is granted to use any trade name, trademark, or 27 * logo of Broadcom Corporation. The "Broadcom Corporation" 28 * name may not be used to endorse or promote products derived 29 * from this software without the prior written permission of 30 * Broadcom Corporation. 31 * 32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 44 * THE POSSIBILITY OF SUCH DAMAGE. 45 ********************************************************************* */ 46 47#include "cfe.h" 48#include "sbmips.h" 49#include "ui_command.h" 50 51#ifdef SIBYTE_SB1250 52#include "sb1250_regs.h" 53#include "sb1250_scd.h" 54#include "sb1250_wid.h" 55#endif 56#ifdef SIBYTE_BCM1480 57#include "bcm1480_regs.h" 58#include "bcm1480_scd.h" 59#include "bcm1480_l2c.h" 60#endif 61 62#include "env_subr.h" 63 64 65/* ********************************************************************* 66 * Macros 67 ********************************************************************* */ 68 69/* 70 * This lets us override the WID by poking values into our PromICE 71 */ 72#ifdef _MAGICWID_ 73#undef A_SCD_SYSTEM_REVISION 74#define A_SCD_SYSTEM_REVISION 0x1FC00508 75#undef A_SCD_SYSTEM_MANUF 76#define A_SCD_SYSTEM_MANUF 0x1FC00518 77#endif 78 79/* ********************************************************************* 80 * Externs/forwards 81 ********************************************************************* */ 82 83void sb1250_show_cpu_type(void); 84 85/* XXXCGD: could be const, when env_setenv can cope. */ 86#ifdef SIBYTE_SB1250 87static char *show_cpu_type_bcm1250(char *, uint64_t syscfg, uint64_t sysrev); 88static char *show_cpu_type_bcm112x(char *, uint64_t syscfg, uint64_t sysrev); 89static void ibm_waferid_str(uint64_t wid, char *wid_str); 90#endif 91#ifdef SIBYTE_BCM1480 92static char *show_cpu_type_bcm1480(char *, uint64_t syscfg, uint64_t sysrev); 93#endif 94 95 96/* ********************************************************************* 97 * ui_show_cpu_type() 98 * 99 * Display board CPU information 100 * 101 * Input parameters: 102 * nothing 103 * 104 * Return value: 105 * nothing 106 ********************************************************************* */ 107void sb1250_show_cpu_type(void) 108{ 109 uint64_t syscfg, sysrev; 110 /* XXXCGD: could be const, when env_setenv can cope. */ 111 char *envval; 112 char *cpuname; 113 char *(*infofn)(char *, uint64_t, uint64_t); 114 char temp[32]; 115 116 syscfg = SBREADCSR(A_SCD_SYSTEM_CFG); 117 sysrev = SBREADCSR(A_SCD_SYSTEM_REVISION); 118 119 switch (SYS_SOC_TYPE(sysrev)) { 120#ifdef SIBYTE_SB1250 121 case K_SYS_SOC_TYPE_BCM1250: 122 cpuname = "1250"; 123 infofn = show_cpu_type_bcm1250; 124 break; 125 126 case K_SYS_SOC_TYPE_BCM1120: 127 cpuname = "1120"; 128 infofn = show_cpu_type_bcm112x; 129 break; 130 131 case K_SYS_SOC_TYPE_BCM1125: 132 cpuname = "1125"; 133 infofn = show_cpu_type_bcm112x; 134 break; 135 136 case K_SYS_SOC_TYPE_BCM1125H: 137 cpuname = "1125H"; 138 infofn = show_cpu_type_bcm112x; 139 break; 140#endif /* SIBYTE_SB1250 */ 141 142#ifdef SIBYTE_BCM1480 143 case K_SYS_SOC_TYPE_BCM1x80: 144 if (G_SYS_PART(sysrev) == K_SYS_PART_BCM1480) 145 cpuname = "1480"; 146 else if (G_SYS_PART(sysrev) == K_SYS_PART_BCM1280) 147 cpuname = "1280"; 148 else if (G_SYS_PART(sysrev) == K_SYS_PART_BCM1158) 149 cpuname = "1158"; 150 else { 151 sprintf(temp, "unknown_1x80_%04x", (int)G_SYS_PART(sysrev)); 152 cpuname = temp; 153 } 154 infofn = show_cpu_type_bcm1480; 155 break; 156 157 case K_SYS_SOC_TYPE_BCM1x55: 158 if (G_SYS_PART(sysrev) == K_SYS_PART_BCM1455) 159 cpuname = "1455"; 160 else if (G_SYS_PART(sysrev) == K_SYS_PART_BCM1255) 161 cpuname = "1255"; 162 else { 163 sprintf(temp, "unknown_1x55_%04x", (int)G_SYS_PART(sysrev)); 164 cpuname = temp; 165 } 166 infofn = show_cpu_type_bcm1480; 167 break; 168#endif /* SIBYTE_BCM1480 */ 169 170 default: 171 sprintf(temp, "unknown_%04x", (int)G_SYS_PART(sysrev)); 172 cpuname = temp; 173 infofn = NULL; 174 break; 175 } 176 177 env_setenv("CPU_TYPE", cpuname, 178 ENV_FLG_BUILTIN | ENV_FLG_READONLY | ENV_FLG_ADMIN); 179 180 envval = NULL; 181 if (infofn != NULL) 182 envval = (*infofn)(cpuname, syscfg, sysrev); 183 if (envval == NULL) { 184 sprintf(temp, "unknown_%02x", (int)G_SYS_REVISION(sysrev)); 185 envval = temp; 186 } 187 env_setenv("CPU_REVISION", envval, 188 ENV_FLG_BUILTIN | ENV_FLG_READONLY | ENV_FLG_ADMIN); 189 190 /* Set # of CPUs based on 2nd hex digit of part number */ 191 sprintf(temp, "%d", (int)((G_SYS_PART(sysrev) >> 8) & 0x0F)); 192 env_setenv("CPU_NUM_CORES", temp, 193 ENV_FLG_BUILTIN | ENV_FLG_READONLY | ENV_FLG_ADMIN); 194 195} 196 197 198#ifdef SIBYTE_SB1250 199static void 200sb1xxx_show_syscfg(uint64_t syscfg) 201{ 202 int plldiv; 203 char temp[32]; 204 205 /* 206 * Set variable that contains CPU speed, spit out config register 207 */ 208 printf("SysCfg: %016llX [PLL_DIV: %d, IOB0_DIV: %s, IOB1_DIV: %s]\n", 209 syscfg, 210 (int)G_SYS_PLL_DIV(syscfg), 211 (syscfg & M_SYS_IOB0_DIV) ? "CPUCLK/3" : "CPUCLK/4", 212 (syscfg & M_SYS_IOB1_DIV) ? "CPUCLK/2" : "CPUCLK/3"); 213 214 plldiv = G_SYS_PLL_DIV(syscfg); 215 if (plldiv == 0) { 216 /* XXX: keep in synch with setting of CPU speed, above. */ 217 printf("PLL_DIV of zero found, assuming 6 (300MHz)\n"); 218 plldiv = 6; 219 } 220 221 sprintf(temp, "%d", plldiv * 50); 222 env_setenv("CPU_SPEED", temp, 223 ENV_FLG_BUILTIN | ENV_FLG_READONLY | ENV_FLG_ADMIN); 224} 225 226 227/* ********************************************************************* 228 * show_cpu_type_bcm1250() 229 * 230 * Display CPU information for BCM1250 CPUs 231 * 232 * Input parameters: 233 * revstr: pointer to string pointer, to be filled in with 234 * revision name. 235 * 236 * Return value: 237 * none. fills in revstr. 238 ********************************************************************* */ 239static char * 240show_cpu_type_bcm1250(char *cpuname, uint64_t syscfg, uint64_t sysrev) 241{ 242 char *revstr, *revprintstr; 243 uint64_t cachetest; 244 uint64_t sysmanuf, ibm_wid; 245 uint32_t wid; 246 int bin; 247 unsigned int cpu_pass; 248 char temp[32]; 249 static uint8_t cachesizes[16] = {4,2,2,2,2,1,1,1,2,1,1,1,2,1,1,0}; 250 static char *binnames[8] = { 251 "2CPU_FI_1D_H2", 252 "2CPU_FI_FD_F2 (OK)", 253 "2CPU_FI_FD_H2", 254 "2CPU_3I_3D_F2", 255 "2CPU_3I_3D_H2", 256 "1CPU_FI_FD_F2", 257 "1CPU_FI_FD_H2", 258 "2CPU_1I_1D_Q2"}; 259 260 cpu_pass = G_SYS_REVISION(sysrev); 261 262 wid = G_SYS_WID(SBREADCSR(A_SCD_SYSTEM_REVISION)); 263 wid = WID_UNCONVOLUTE(wid); 264 265 if ((wid != 0) && (cpu_pass == K_SYS_REVISION_BCM1250_A2)) { 266 cpu_pass = K_SYS_REVISION_BCM1250_A6; 267 } 268 269 switch (cpu_pass) { 270 case K_SYS_REVISION_BCM1250_PASS1: 271 revstr = "PASS1"; 272 revprintstr = "Pass 1"; 273 break; 274 case K_SYS_REVISION_BCM1250_A1: 275 revstr = "A1"; 276 revprintstr = "Pass 2.0 (wirebond)"; 277 break; 278 case K_SYS_REVISION_BCM1250_A2: 279 revstr = "A2"; 280 revprintstr = "Pass 2.0 (flip-chip)"; 281 break; 282 case K_SYS_REVISION_BCM1250_A3: 283 revstr = "A3"; 284 revprintstr = "A3 Pass 2.1 (flip-chip)"; 285 break; 286 case K_SYS_REVISION_BCM1250_A4: 287 revstr = "A4"; 288 revprintstr = "A4 Pass 2.1 (wirebond)"; 289 break; 290 case K_SYS_REVISION_BCM1250_A6: 291 revstr = revprintstr = "A6"; 292 break; 293 case K_SYS_REVISION_BCM1250_A8: 294 revprintstr = "A8/A10"; 295 revstr = "A8"; 296 break; 297 case K_SYS_REVISION_BCM1250_A9: 298 revstr = revprintstr = "A9"; 299 break; 300 case K_SYS_REVISION_BCM1250_B1: 301 revprintstr = "B0/B1"; 302 revstr = "B1"; 303 break; 304 case K_SYS_REVISION_BCM1250_B2: 305 revstr = revprintstr = "B2"; 306 break; 307 case K_SYS_REVISION_BCM1250_C0: 308 revstr = revprintstr = "C0"; 309 break; 310 case K_SYS_REVISION_BCM1250_C1: 311 revstr = revprintstr = "C1"; 312 break; 313 case K_SYS_REVISION_BCM1250_C2: 314 revstr = revprintstr = "C2"; 315 break; 316 default: 317 revstr = NULL; 318 sprintf(temp, "rev 0x%x", (int)G_SYS_REVISION(sysrev)); 319 revprintstr = temp; 320 break; 321 } 322 printf("CPU: BCM1250 %s\n", revprintstr); 323 324 if (((G_SYS_PART(sysrev) >> 8) & 0x0F) == 1) { 325 printf("[Uniprocessor CPU mode]\n"); 326 } 327 328 /* 329 * Report cache status if the cache was disabled, or the status of 330 * the cache test for non-WID pass2 and pass3 parts. 331 */ 332 printf("L2 Cache Status: "); 333 if ((syscfg & M_SYS_L2C_RESET) != 0) { 334 printf("disabled via JTAG\n"); 335 } 336 else if ((cpu_pass == K_SYS_REVISION_BCM1250_A1) || 337 (cpu_pass == K_SYS_REVISION_BCM1250_A2) || 338 (cpu_pass == K_SYS_REVISION_BCM1250_C0) || 339 (cpu_pass == K_SYS_REVISION_BCM1250_C1) ) { 340 cachetest = (SBREADCSR(A_MAC_REGISTER(2, R_MAC_HASH_BASE)) & 0x0F); 341 printf("0x%llX Available L2 Cache: %dKB\n", cachetest, 342 ((int)cachesizes[(int)cachetest])*128); 343 } 344 else printf("OK\n"); 345 346 if (wid == 0) { 347 printf("Wafer ID: Not set\n"); 348 } 349 else if (cpu_pass < K_SYS_REVISION_BCM1250_C0) { 350 351 printf("Wafer ID: 0x%08X [Lot %d, Wafer %d]\n", wid, 352 G_WID_LOTID(wid), G_WID_WAFERID(wid)); 353 354 bin = G_WID_BIN(wid); 355 356 printf("Manuf Test: Bin %c [%s] ", "EABCDFGH"[bin], binnames[bin]); 357 358 if (bin != K_WID_BIN_2CPU_FI_FD_F2) { 359 printf("L2:%d ", G_WID_L2QTR(wid)); 360 printf("CPU0:[I=%d D=%d] ", G_WID_CPU0_L1I(wid), G_WID_CPU0_L1D(wid)); 361 printf("CPU1:[I=%d D=%d]", G_WID_CPU1_L1I(wid), G_WID_CPU1_L1D(wid)); 362 } 363 printf("\n"); 364 } 365 366 if (cpu_pass >= K_SYS_REVISION_BCM1250_C0) { 367 /* Read system_manuf register for C0 or greater*/ 368 sysmanuf = SBREADCSR(A_SCD_SYSTEM_MANUF); 369 370 printf("SysManuf: %016llX [X: %d Y: %d] ", sysmanuf, (int)G_SYS_XPOS(sysmanuf), 371 (int)G_SYS_YPOS(sysmanuf)); 372 373 ibm_wid = ((sysmanuf & 0xf000000000LL) >> 4) | (sysmanuf & 0xffffffff); 374 char wid_str[7]; 375 ibm_waferid_str(ibm_wid, wid_str); 376 printf("[Wafer ID: %s]", wid_str); 377 378 printf("\n"); 379 } 380 381 sb1xxx_show_syscfg(syscfg); 382 383 return (revstr); 384} 385 386/* ********************************************************************* 387 * show_cpu_type_bcm112x() 388 * 389 * Display CPU information for BCM112x CPUs 390 * 391 * Input parameters: 392 * revstr: pointer to string pointer, to be filled in with 393 * revision name. 394 * 395 * Return value: 396 * none. fills in revstr. 397 ********************************************************************* */ 398static char * 399show_cpu_type_bcm112x(char *cpuname, uint64_t syscfg, uint64_t sysrev) 400{ 401 char *revstr, *revprintstr; 402 char temp[32]; 403 404 switch (G_SYS_REVISION(sysrev)) { 405 case K_SYS_REVISION_BCM112x_A1: 406 revstr = revprintstr = "A1"; 407 break; 408 case K_SYS_REVISION_BCM112x_A2: 409 revstr = revprintstr = "A2"; 410 break; 411 case K_SYS_REVISION_BCM112x_A3: 412 revstr = revprintstr = "A3"; 413 break; 414 case K_SYS_REVISION_BCM112x_A4: 415 revstr = revprintstr = "A4"; 416 break; 417 default: 418 revstr = NULL; 419 sprintf(temp, "rev 0x%x", (int)G_SYS_REVISION(sysrev)); 420 revprintstr = temp; 421 break; 422 } 423 printf("CPU: %s %s\n", env_getenv("CPU_TYPE"), revprintstr); 424 425 printf("L2 Cache: "); 426 if ((syscfg & M_SYS_L2C_RESET) != 0) 427 printf("disabled via JTAG\n"); 428 else { 429 /*1122 is 128K. same soc type as 1125*/ 430 if (G_SYS_L2C_SIZE(sysrev) == K_SYS_L2C_SIZE_BCM1122) 431 printf("128KB\n"); 432 else 433 printf("256KB\n"); 434 } 435 436 437 sb1xxx_show_syscfg(syscfg); 438 439 return (revstr); 440} 441 442/* Decode IBMs WaferID code */ 443static void ibm_waferid_str(uint64_t wid, char *wid_str) 444{ 445 int i; 446 447 for (i=0; i<6; i++) { 448 unsigned char bits; 449 char code; 450 451 bits = wid & 0x3f; 452 wid >>= 6; 453 if (bits < 0xa) 454 code = bits + '0'; 455 else if (bits < 0x24) 456 code = (bits - 0xa) + 'A'; 457 else if (bits == 0x3d) 458 code = '-'; 459 else if (bits == 0x3e) 460 code = '.'; 461 else if (bits == 0x3f) 462 code = ' '; 463 else 464 code = '?'; 465 wid_str[5-i] = code; 466 } 467 wid_str[6] = '\0'; 468} 469#endif /* SIBYTE_SB1250 */ 470 471 472#ifdef SIBYTE_BCM1480 473static void 474bcm14xx_show_syscfg(uint64_t syscfg) 475{ 476 int plldiv; 477 char temp[32]; 478 479 printf("SysCfg: %016llX [PLL_DIV:%d, SW_DIV:%d, CCNUMA:%s, IOB_DIV:%s]\n", 480 syscfg, 481 (int)G_BCM1480_SYS_PLL_DIV(syscfg), 482 (int)G_BCM1480_SYS_SW_DIV(syscfg), 483 (syscfg & M_BCM1480_SYS_CCNUMA_EN) ? "enable" : "disable", 484 (syscfg & M_BCM1480_SYS_IOB_DIV) ? "CPUCLK/3" : "CPUCLK/4"); 485 486 plldiv = G_BCM1480_SYS_PLL_DIV(syscfg); 487 if (plldiv == 0) { 488 /* XXX: keep in synch with setting of CPU speed, above. */ 489 printf("PLL_DIV of zero found, assuming 6 (300MHz)\n"); 490 plldiv = 6; 491 } 492 493 sprintf(temp, "%d", plldiv * 50); 494 env_setenv("CPU_SPEED", temp, 495 ENV_FLG_BUILTIN | ENV_FLG_READONLY | ENV_FLG_ADMIN); 496} 497 498 499/* ********************************************************************* 500 * show_cpu_type_bcm1480() 501 * 502 * Display CPU information for BCM1480 CPUs 503 * 504 * Input parameters: 505 * revstr: pointer to string pointer, to be filled in with 506 * revision name. 507 * 508 * Return value: 509 * none. fills in revstr. 510 ********************************************************************* */ 511static char * 512show_cpu_type_bcm1480(char *cpuname, uint64_t syscfg, uint64_t sysrev) 513{ 514 int cpu_pass = G_SYS_REVISION(sysrev); 515 int enabled_cpus = bcm1480_num_cpus(); 516 uint64_t l2c_misc0_value; 517 char *revstr, *revprintstr, *cachestr; 518 char temp[32]; 519 int l2_disabled = 0; 520 521#ifdef _BIGSUR_ 522 /* 523 * This is a special hack just for the BCM1480 bringup board. Customers, 524 * please do not include this code in your ports! The BCM1480 has no 525 * way to read whether the L2 cache is being held in reset or not, 526 * so we are using the least significant config bit (M_BCM1480_SYS_CONFIG) 527 * to pass this information from the boot script to the firmware. 528 */ 529 if (syscfg & (1<<S_BCM1480_SYS_CONFIG)) { 530 l2_disabled = 1; 531 } 532#endif 533 534 switch (cpu_pass) { 535 case K_SYS_REVISION_BCM1480_S0: 536 revstr = "S0"; 537 revprintstr = "S0 (pass1)"; 538 break; 539 case K_SYS_REVISION_BCM1480_A1: 540 revstr = "A1"; 541 revprintstr = "A1 (pass1)"; 542 break; 543 case K_SYS_REVISION_BCM1480_A2: 544 revstr = "A2"; 545 revprintstr = "A2 (pass1)"; 546 break; 547 case K_SYS_REVISION_BCM1480_A3: 548 revstr = "A3"; 549 revprintstr = "A3 (pass1)"; 550 break; 551 case K_SYS_REVISION_BCM1480_B0: 552 revstr = "B0"; 553 revprintstr = "B0 (pass2)"; 554 break; 555 default: 556 sprintf(temp, "rev 0x%x", (int)cpu_pass); 557 revprintstr = temp; 558 revstr = NULL; 559 break; 560 } 561 562 printf("CPU: %s %s, %d cpu%s", cpuname, revprintstr, enabled_cpus, 563 enabled_cpus == 1 ? "" : "s"); 564 if (G_SYS_NUM_CPUS(sysrev) != enabled_cpus) 565 printf(" enabled (%d disabled - fused)", 566 G_SYS_NUM_CPUS(sysrev) - enabled_cpus); 567 printf("\n"); 568 569 if (l2_disabled) { 570 /* Must not touch L2 cache registers if L2C is held in reset */ 571 cachestr = "disabled via JTAG"; 572 } 573 else { 574 l2c_misc0_value = SBREADCSR(A_BCM1480_L2_MISC0_VALUE); 575 cachestr = "unknown size"; 576 if (G_SYS_L2C_SIZE(sysrev) == K_SYS_L2C_SIZE_1MB && 577 G_BCM1480_L2C_MISC0_CACHE_DISABLE(l2c_misc0_value) != 0) 578 cachestr = "512KB (512KB disabled by software)"; 579 else if (G_SYS_L2C_SIZE(sysrev) == K_SYS_L2C_SIZE_1MB) 580 cachestr = "1MB"; 581 else if (G_SYS_L2C_SIZE(sysrev) == K_SYS_L2C_SIZE_512KB) 582 cachestr = "512KB"; 583 } 584 585 printf("L2Cache: %s\n", cachestr); 586 587 bcm14xx_show_syscfg(syscfg); 588 589 return revstr; 590} 591#endif /* SIBYTE_BCM1480 */ 592