1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/systm.h> 28 #include <sys/ddi.h> 29 #include <sys/sysmacros.h> 30 #include <sys/archsystm.h> 31 #include <sys/vmsystm.h> 32 #include <sys/machparam.h> 33 #include <sys/machsystm.h> 34 #include <sys/machthread.h> 35 #include <sys/cpu.h> 36 #include <sys/cmp.h> 37 #include <sys/elf_SPARC.h> 38 #include <vm/hat_sfmmu.h> 39 #include <vm/seg_kmem.h> 40 #include <sys/cpuvar.h> 41 #include <sys/cheetahregs.h> 42 #include <sys/us3_module.h> 43 #include <sys/async.h> 44 #include <sys/cmn_err.h> 45 #include <sys/debug.h> 46 #include <sys/dditypes.h> 47 #include <sys/prom_debug.h> 48 #include <sys/prom_plat.h> 49 #include <sys/cpu_module.h> 50 #include <sys/sysmacros.h> 51 #include <sys/intreg.h> 52 #include <sys/clock.h> 53 #include <sys/platform_module.h> 54 #include <sys/machtrap.h> 55 #include <sys/ontrap.h> 56 #include <sys/panic.h> 57 #include <sys/memlist.h> 58 #include <sys/bootconf.h> 59 #include <sys/ivintr.h> 60 #include <sys/atomic.h> 61 #include <sys/fm/protocol.h> 62 #include <sys/fm/cpu/UltraSPARC-III.h> 63 #include <sys/errclassify.h> 64 65 #ifdef CHEETAHPLUS_ERRATUM_25 66 #include <sys/cyclic.h> 67 #endif /* CHEETAHPLUS_ERRATUM_25 */ 68 69 /* cpu estar private data */ 70 typedef struct { 71 uint8_t state : 7; 72 uint8_t valid : 1; 73 } mcu_fsm_def_t; 74 mcu_fsm_def_t mcu_fsm_init_state[NCPU]; 75 76 #if defined(JALAPENO) && defined(JALAPENO_ERRATA_85) 77 /* 78 * jp_errata_85_enable can be set to 0 in /etc/system to disable 79 * JP Errata 85 workaround. 80 * 81 * jp_errata_85_allow_slow_scrub is usually set to !jp_errata_85_enable, 82 * but can be overridden in /etc/system. If set, it allows the scrubber 83 * to run in 1/2 or 1/32 mode. If a cpu is vulnerable to errata 85, 84 * this value should be zero. 85 * 86 * jp_errata_85_active is an internal variable and must not be 87 * set/changed via /etc/system or in any other way. 88 */ 89 extern int jp_errata_85_enable; /* for /etc/system use */ 90 extern int jp_errata_85_allow_slow_scrub; /* for /etc/system use */ 91 92 int jp_errata_85_active = -1; /* warn: modified in code ONLY */ 93 uint64_t jp_estar_tl0_data[8]; 94 uint64_t jp_estar_tl1_data[8]; 95 #endif /* JALAPENO && JALAPENO_ERRATA_85 */ 96 97 /* 98 * Setup trap handlers. 99 */ 100 void 101 cpu_init_trap(void) 102 { 103 CH_SET_TRAP(pil15_epilogue, ch_pil15_interrupt_instr); 104 105 CH_SET_TRAP(tt0_fecc, fecc_err_instr); 106 CH_SET_TRAP(tt1_fecc, fecc_err_tl1_instr); 107 CH_SET_TRAP(tt1_swtrap0, fecc_err_tl1_cont_instr); 108 109 CH_SET_TRAP(tt0_dperr, dcache_parity_instr); 110 CH_SET_TRAP(tt1_dperr, dcache_parity_tl1_instr); 111 CH_SET_TRAP(tt1_swtrap1, dcache_parity_tl1_cont_instr); 112 113 CH_SET_TRAP(tt0_iperr, icache_parity_instr); 114 CH_SET_TRAP(tt1_iperr, icache_parity_tl1_instr); 115 CH_SET_TRAP(tt1_swtrap2, icache_parity_tl1_cont_instr); 116 } 117 118 119 static int 120 getintprop(pnode_t node, char *name, int deflt) 121 { 122 int value; 123 124 switch (prom_getproplen(node, name)) { 125 case sizeof (int): 126 (void) prom_getprop(node, name, (caddr_t)&value); 127 break; 128 129 default: 130 value = deflt; 131 break; 132 } 133 134 return (value); 135 } 136 137 /* 138 * Set the magic constants of the implementation. 139 */ 140 /*ARGSUSED*/ 141 void 142 cpu_fiximp(pnode_t dnode) 143 { 144 int i, a; 145 extern int vac_size, vac_shift; 146 extern uint_t vac_mask; 147 148 static struct { 149 char *name; 150 int *var; 151 int defval; 152 } prop[] = { 153 "dcache-size", &dcache_size, CH_DCACHE_SIZE, 154 "dcache-line-size", &dcache_linesize, CH_DCACHE_LSIZE, 155 "icache-size", &icache_size, CH_ICACHE_SIZE, 156 "icache-line-size", &icache_linesize, CH_ICACHE_LSIZE, 157 "ecache-size", &ecache_size, JP_ECACHE_MAX_SIZE, 158 "ecache-line-size", &ecache_alignsize, JP_ECACHE_MAX_LSIZE, 159 "ecache-associativity", &ecache_associativity, JP_ECACHE_NWAY 160 }; 161 162 for (i = 0; i < sizeof (prop) / sizeof (prop[0]); i++) 163 *prop[i].var = getintprop(dnode, prop[i].name, prop[i].defval); 164 165 ecache_setsize = ecache_size / ecache_associativity; 166 167 vac_size = CH_VAC_SIZE; 168 vac_mask = MMU_PAGEMASK & (vac_size - 1); 169 i = 0; a = vac_size; 170 while (a >>= 1) 171 ++i; 172 vac_shift = i; 173 shm_alignment = vac_size; 174 vac = 1; 175 } 176 177 void 178 send_mondo_set(cpuset_t set) 179 { 180 int lo, busy, nack, shipped = 0; 181 uint16_t i, cpuids[IDSR_BN_SETS]; 182 uint64_t idsr, nackmask = 0, busymask, curnack, curbusy; 183 uint64_t starttick, endtick, tick, lasttick; 184 #ifdef CHEETAHPLUS_ERRATUM_25 185 int recovered = 0; 186 int cpuid; 187 #endif 188 189 ASSERT(!CPUSET_ISNULL(set)); 190 starttick = lasttick = gettick(); 191 192 /* 193 * Lower 2 bits of the agent ID determine which BUSY/NACK pair 194 * will be used for dispatching interrupt. For now, assume 195 * there are no more than IDSR_BN_SETS CPUs, hence no aliasing 196 * issues with respect to BUSY/NACK pair usage. 197 */ 198 for (i = 0; i < NCPU; i++) 199 if (CPU_IN_SET(set, i)) { 200 shipit(i, shipped /* ignored */); 201 nackmask |= IDSR_NACK_BIT(CPUID_TO_BN_PAIR(i)); 202 cpuids[CPUID_TO_BN_PAIR(i)] = i; 203 shipped++; 204 CPUSET_DEL(set, i); 205 if (CPUSET_ISNULL(set)) 206 break; 207 } 208 CPU_STATS_ADDQ(CPU, sys, xcalls, shipped); 209 210 busymask = IDSR_NACK_TO_BUSY(nackmask); 211 busy = nack = 0; 212 endtick = starttick + xc_tick_limit; 213 for (;;) { 214 idsr = getidsr(); 215 if (idsr == 0) 216 break; 217 tick = gettick(); 218 /* 219 * If there is a big jump between the current tick 220 * count and lasttick, we have probably hit a break 221 * point. Adjust endtick accordingly to avoid panic. 222 */ 223 if (tick > (lasttick + xc_tick_jump_limit)) 224 endtick += (tick - lasttick); 225 lasttick = tick; 226 if (tick > endtick) { 227 if (panic_quiesce) 228 return; 229 #ifdef CHEETAHPLUS_ERRATUM_25 230 cpuid = -1; 231 for (i = 0; i < IDSR_BN_SETS; i++) { 232 if (idsr & (IDSR_NACK_BIT(i) | 233 IDSR_BUSY_BIT(i))) { 234 cpuid = cpuids[i]; 235 break; 236 } 237 } 238 if (cheetah_sendmondo_recover && cpuid != -1 && 239 recovered == 0) { 240 if (mondo_recover(cpuid, i)) { 241 /* 242 * We claimed the whole memory or 243 * full scan is disabled. 244 */ 245 recovered++; 246 } 247 tick = gettick(); 248 endtick = tick + xc_tick_limit; 249 lasttick = tick; 250 /* 251 * Recheck idsr 252 */ 253 continue; 254 } else 255 #endif /* CHEETAHPLUS_ERRATUM_25 */ 256 { 257 cmn_err(CE_CONT, "send mondo timeout " 258 "[%d NACK %d BUSY]\nIDSR 0x%" 259 "" PRIx64 " cpuids:", nack, busy, idsr); 260 for (i = 0; i < IDSR_BN_SETS; i++) { 261 if (idsr & (IDSR_NACK_BIT(i) | 262 IDSR_BUSY_BIT(i))) { 263 cmn_err(CE_CONT, " 0x%x", 264 cpuids[i]); 265 } 266 } 267 cmn_err(CE_CONT, "\n"); 268 cmn_err(CE_PANIC, "send_mondo_set: timeout"); 269 } 270 } 271 curnack = idsr & nackmask; 272 curbusy = idsr & busymask; 273 if (curbusy) { 274 busy++; 275 continue; 276 } 277 278 #ifdef SEND_MONDO_STATS 279 { 280 int n = gettick() - starttick; 281 if (n < 8192) 282 x_nack_stimes[n >> 7]++; 283 } 284 #endif 285 while (gettick() < (tick + sys_clock_mhz)) 286 ; 287 do { 288 lo = lowbit(curnack) - 1; 289 i = IDSR_NACK_IDX(lo); 290 shipit(cpuids[i], i); 291 curnack &= ~(1ull << lo); 292 } while (curnack); 293 nack++; 294 busy = 0; 295 } 296 #ifdef SEND_MONDO_STATS 297 { 298 int n = gettick() - starttick; 299 if (n < 8192) 300 x_set_stimes[n >> 7]++; 301 else 302 x_set_ltimes[(n >> 13) & 0xf]++; 303 } 304 x_set_cpus[shipped]++; 305 #endif 306 } 307 308 /* 309 * Handles error logging for implementation specific error types 310 */ 311 int 312 cpu_impl_async_log_err(void *flt, errorq_elem_t *eqep) 313 { 314 ch_async_flt_t *ch_flt = (ch_async_flt_t *)flt; 315 struct async_flt *aflt = (struct async_flt *)flt; 316 uint64_t errors; 317 318 switch (ch_flt->flt_type) { 319 320 case CPU_IC_PARITY: 321 cpu_async_log_ic_parity_err(flt); 322 return (CH_ASYNC_LOG_DONE); 323 324 case CPU_DC_PARITY: 325 cpu_async_log_dc_parity_err(flt); 326 return (CH_ASYNC_LOG_DONE); 327 328 case CPU_RCE: 329 if (page_retire_check(aflt->flt_addr, &errors) == EINVAL) { 330 CE_XDIAG_SETSKIPCODE(aflt->flt_disp, 331 CE_XDIAG_SKIP_NOPP); 332 } else if (errors != PR_OK) { 333 CE_XDIAG_SETSKIPCODE(aflt->flt_disp, 334 CE_XDIAG_SKIP_PAGEDET); 335 } else if (ce_scrub_xdiag_recirc(aflt, ce_queue, eqep, 336 offsetof(ch_async_flt_t, cmn_asyncflt))) { 337 return (CH_ASYNC_LOG_RECIRC); 338 } 339 /*FALLTHRU*/ 340 /* 341 * cases where we just want to report the error and continue. 342 */ 343 case CPU_BPAR: 344 case CPU_UMS: 345 case CPU_FRC: 346 case CPU_FRU: 347 cpu_log_err(aflt); 348 return (CH_ASYNC_LOG_DONE); 349 350 /* 351 * Cases where we want to fall through to handle panicking. 352 */ 353 case CPU_RUE: 354 cpu_log_err(aflt); 355 return (CH_ASYNC_LOG_CONTINUE); 356 357 default: 358 return (CH_ASYNC_LOG_UNKNOWN); 359 } 360 } 361 362 /* 363 * Figure out if Ecache is direct-mapped (Cheetah or Cheetah+ with Ecache 364 * control ECCR_ASSOC bit off or 2-way (Cheetah+ with ECCR_ASSOC on). 365 * We need to do this on the fly because we may have mixed Cheetah+'s with 366 * both direct and 2-way Ecaches. 367 */ 368 int 369 cpu_ecache_nway(void) 370 { 371 return (JP_ECACHE_NWAY); 372 } 373 374 /* 375 * Note that these are entered into the table in the order: 376 * Fatal Errors first, orphaned UCU/UCC, AFAR Overwrite policy, 377 * FRC/FRU, and finally IVPE. 378 * 379 * Afar overwrite policy is: 380 * Jalapeno: 381 * UCU,UCC > RUE,UE,EDU,WDU,CPU,WBP,BP > RCE,CE,EDC,WDC,CPC > 382 * TO,BERR > UMS,OM 383 * Serrano: 384 * UCU,UCC > RUE,UE,EDU,WDU,CPU,WBP,BP > RCE,CE,EDC,WDC,CPC,ETI,ETC > 385 * TO,BERR > UMS,OM 386 */ 387 ecc_type_to_info_t ecc_type_to_info[] = { 388 389 /* Fatal Errors */ 390 C_AFSR_JETO, "JETO ", ECC_ALL_TRAPS, CPU_FATAL, 391 "JETO Fatal", 392 FM_EREPORT_PAYLOAD_SYSTEM1, 393 FM_EREPORT_CPU_USIII_JETO, 394 C_AFSR_SCE, "SCE ", ECC_ALL_TRAPS, CPU_FATAL, 395 "SCE Fatal", 396 FM_EREPORT_PAYLOAD_SYSTEM1, 397 FM_EREPORT_CPU_USIII_SCE, 398 C_AFSR_JEIC, "JEIC ", ECC_ALL_TRAPS, CPU_FATAL, 399 "JEIC Fatal", 400 FM_EREPORT_PAYLOAD_SYSTEM1, 401 FM_EREPORT_CPU_USIII_JEIC, 402 C_AFSR_JEIT, "JEIT ", ECC_ALL_TRAPS, CPU_FATAL, 403 "JEIT Fatal", 404 FM_EREPORT_PAYLOAD_SYSTEM1, 405 FM_EREPORT_CPU_USIII_JEIT, 406 C_AFSR_JEIS, "JEIS ", ECC_ALL_TRAPS, CPU_FATAL, 407 "JEIS Fatal", 408 FM_EREPORT_PAYLOAD_SYSTEM1, 409 FM_EREPORT_CPU_USIII_JEIS, 410 #if defined(JALAPENO) 411 C_AFSR_ETP, "ETP ", ECC_ALL_TRAPS, CPU_FATAL, 412 "ETP Fatal", 413 FM_EREPORT_PAYLOAD_L2_TAG_PE, 414 FM_EREPORT_CPU_USIII_ETP, 415 #elif defined(SERRANO) 416 C_AFSR_ETS, "ETS ", ECC_ASYNC_TRAPS, CPU_FATAL, 417 "ETS Fatal", 418 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 419 FM_EREPORT_CPU_USIII_ETS, 420 C_AFSR_ETU, "ETU ", ECC_ASYNC_TRAPS, CPU_FATAL, 421 "ETU Fatal", 422 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 423 FM_EREPORT_CPU_USIII_ETU, 424 #endif /* SERRANO */ 425 C_AFSR_IERR, "IERR ", ECC_ALL_TRAPS, CPU_FATAL, 426 "IERR Fatal", 427 FM_EREPORT_PAYLOAD_SYSTEM2, 428 FM_EREPORT_CPU_USIII_IERR, 429 C_AFSR_ISAP, "ISAP ", ECC_ALL_TRAPS, CPU_FATAL, 430 "ISAP Fatal", 431 FM_EREPORT_PAYLOAD_SYSTEM1, 432 FM_EREPORT_CPU_USIII_ISAP, 433 434 /* Orphaned UCU/UCC Errors */ 435 C_AFSR_UCU, "OUCU ", ECC_ORPH_TRAPS, CPU_ORPH, 436 "Orphaned UCU", 437 FM_EREPORT_PAYLOAD_L2_DATA, 438 FM_EREPORT_CPU_USIII_UCU, 439 C_AFSR_UCC, "OUCC ", ECC_ORPH_TRAPS, CPU_ORPH, 440 "Orphaned UCC", 441 FM_EREPORT_PAYLOAD_L2_DATA, 442 FM_EREPORT_CPU_USIII_UCC, 443 444 /* UCU, UCC */ 445 C_AFSR_UCU, "UCU ", ECC_F_TRAP, CPU_UE_ECACHE, 446 "UCU", 447 FM_EREPORT_PAYLOAD_L2_DATA, 448 FM_EREPORT_CPU_USIII_UCU, 449 C_AFSR_UCC, "UCC ", ECC_F_TRAP, CPU_CE_ECACHE, 450 "UCC", 451 FM_EREPORT_PAYLOAD_L2_DATA, 452 FM_EREPORT_CPU_USIII_UCC, 453 454 455 /* RUE, UE, EDU:ST, EDU:BLD, WDU, CPU, BP, WBP */ 456 C_AFSR_RUE, "RUE ", ECC_ASYNC_TRAPS, CPU_RUE, 457 "Uncorrectable remote memory/cache (RUE)", 458 FM_EREPORT_PAYLOAD_MEMORY, 459 FM_EREPORT_CPU_USIII_RUE, 460 C_AFSR_UE, "UE ", ECC_ASYNC_TRAPS, CPU_UE, 461 "Uncorrectable memory (UE)", 462 FM_EREPORT_PAYLOAD_MEMORY, 463 FM_EREPORT_CPU_USIII_UE, 464 C_AFSR_EDU, "EDU ", ECC_C_TRAP, CPU_UE_ECACHE_RETIRE, 465 "EDU:ST", 466 FM_EREPORT_PAYLOAD_L2_DATA, 467 FM_EREPORT_CPU_USIII_EDUST, 468 C_AFSR_EDU, "EDU ", ECC_D_TRAP, CPU_UE_ECACHE_RETIRE, 469 "EDU:BLD", 470 FM_EREPORT_PAYLOAD_L2_DATA, 471 FM_EREPORT_CPU_USIII_EDUBL, 472 C_AFSR_WDU, "WDU ", ECC_C_TRAP, CPU_UE_ECACHE_RETIRE, 473 "WDU", 474 FM_EREPORT_PAYLOAD_L2_DATA, 475 FM_EREPORT_CPU_USIII_WDU, 476 C_AFSR_CPU, "CPU ", ECC_C_TRAP, CPU_UE_ECACHE, 477 "CPU", 478 FM_EREPORT_PAYLOAD_L2_DATA, 479 FM_EREPORT_CPU_USIII_CPU, 480 C_AFSR_WBP, "WBP ", ECC_C_TRAP, CPU_BPAR, 481 "JBUS parity error on writeback or block store (WBP)", 482 FM_EREPORT_PAYLOAD_SYSTEM3, 483 FM_EREPORT_CPU_USIII_WBP, 484 C_AFSR_BP, "BP ", ECC_ASYNC_TRAPS, CPU_BPAR, 485 "JBUS parity error on returned read data (BP)", 486 FM_EREPORT_PAYLOAD_SYSTEM3, 487 FM_EREPORT_CPU_USIII_BP, 488 489 /* RCE, CE, EDC, WDC, CPC */ 490 C_AFSR_RCE, "RCE ", ECC_C_TRAP, CPU_RCE, 491 "Corrected remote memory/cache (RCE)", 492 FM_EREPORT_PAYLOAD_MEMORY, 493 FM_EREPORT_CPU_USIII_RCE, 494 C_AFSR_CE, "CE ", ECC_C_TRAP, CPU_CE, 495 "Corrected memory (CE)", 496 FM_EREPORT_PAYLOAD_MEMORY, 497 FM_EREPORT_CPU_USIII_CE, 498 C_AFSR_EDC, "EDC ", ECC_C_TRAP, CPU_CE_ECACHE, 499 "EDC", 500 FM_EREPORT_PAYLOAD_L2_DATA, 501 FM_EREPORT_CPU_USIII_EDC, 502 C_AFSR_WDC, "WDC ", ECC_C_TRAP, CPU_CE_ECACHE, 503 "WDC", 504 FM_EREPORT_PAYLOAD_L2_DATA, 505 FM_EREPORT_CPU_USIII_WDC, 506 C_AFSR_CPC, "CPC ", ECC_C_TRAP, CPU_CE_ECACHE, 507 "CPC", 508 FM_EREPORT_PAYLOAD_L2_DATA, 509 FM_EREPORT_CPU_USIII_CPC, 510 #if defined(SERRANO) 511 /* ETI, ETC */ 512 C_AFSR_ETI, "ETI", ECC_F_TRAP | ECC_C_TRAP, CPU_CE_ECACHE, 513 "ETI", 514 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 515 FM_EREPORT_CPU_USIII_ETI, 516 C_AFSR_ETC, "ETC", ECC_F_TRAP | ECC_C_TRAP, CPU_CE_ECACHE, 517 "ETC", 518 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 519 FM_EREPORT_CPU_USIII_ETC, 520 #endif /* SERRANO */ 521 522 /* TO, BERR */ 523 C_AFSR_TO, "TO ", ECC_ASYNC_TRAPS, CPU_TO, 524 "Timeout (TO)", 525 FM_EREPORT_PAYLOAD_IO, 526 FM_EREPORT_CPU_USIII_TO, 527 C_AFSR_BERR, "BERR ", ECC_ASYNC_TRAPS, CPU_BERR, 528 "Bus Error (BERR)", 529 FM_EREPORT_PAYLOAD_IO, 530 FM_EREPORT_CPU_USIII_BERR, 531 532 /* UMS, OM */ 533 C_AFSR_UMS, "UMS ", ECC_C_TRAP, CPU_UMS, 534 "Unsupported store (UMS)", 535 FM_EREPORT_PAYLOAD_IO, 536 FM_EREPORT_CPU_USIII_UMS, 537 C_AFSR_OM, "OM ", ECC_ASYNC_TRAPS, CPU_BERR, 538 "Out of range memory (OM)", 539 FM_EREPORT_PAYLOAD_IO, 540 FM_EREPORT_CPU_USIII_OM, 541 542 /* FRC, FRU */ 543 C_AFSR_FRC, "FRC ", ECC_C_TRAP, CPU_FRC, 544 "Corrected memory (FRC)", 545 FM_EREPORT_PAYLOAD_MEMORY, 546 FM_EREPORT_CPU_USIII_FRC, 547 C_AFSR_FRU, "FRU ", ECC_C_TRAP, CPU_FRU, 548 "Uncorrectable memory (FRU)", 549 FM_EREPORT_PAYLOAD_MEMORY, 550 FM_EREPORT_CPU_USIII_FRU, 551 552 /* IVPE */ 553 C_AFSR_IVPE, "IVPE ", ECC_C_TRAP, CPU_IV, 554 "IVPE", 555 FM_EREPORT_PAYLOAD_SYSTEM1, 556 FM_EREPORT_CPU_USIII_IVPE, 557 558 0, NULL, 0, 0, 559 NULL, 560 FM_EREPORT_PAYLOAD_UNKNOWN, 561 FM_EREPORT_CPU_USIII_UNKNOWN, 562 }; 563 564 /* 565 * J_REQ overwrite policy (see UltraSPARC-IIIi PRM) 566 * 567 * Class 4: RUE, BP, WBP 568 * Class 3: RCE 569 * Class 2: TO, BERR 570 * Class 1: UMS 571 */ 572 uint64_t jreq_overwrite[] = { 573 C_AFSR_RUE | C_AFSR_BP | C_AFSR_WBP, 574 C_AFSR_RCE, 575 C_AFSR_TO | C_AFSR_BERR, 576 C_AFSR_UMS, 577 0 578 }; 579 580 /* 581 * AGENT ID overwrite policy (see UltraSPARC-IIIi PRM) 582 * 583 * Class 2: CPU, FRU 584 * Class 1: CPC, FRC 585 */ 586 uint64_t jbus_aid_overwrite[] = { 587 C_AFSR_CPU | C_AFSR_FRU, 588 C_AFSR_CPC | C_AFSR_FRC, 589 0 590 }; 591 592 int 593 afsr_to_jaid_status(uint64_t afsr, uint64_t afsr_bit) 594 { 595 return (afsr_to_overw_status(afsr, afsr_bit, jbus_aid_overwrite)); 596 } 597 598 /* 599 * See UltraSPARC-IIIi+ PRM 600 * Class 5: ETS, ETU, EFES 601 * Class 4: UCC, UCU 602 * Class 3: UE, RUE, BP, WBP, EDU, WDU, CPU 603 * Class 2: CE, RCE, EDC, WDC, CPC, ETI, ETC 604 * Class 1: TO, BERR 605 * Class 0: UMS, OM 606 * 607 * See UltraSPARC-IIIi PRM 608 * Class 5: ETP 609 * Class 4: UCC, UCU 610 * Class 3: UE, RUE, BP, WBP, EDU, WDU 611 * Class 2: CE, RCE, EDC, WDC 612 * Class 1: TO, BERR 613 * Class 0: UMS, OM 614 */ 615 uint64_t afar_overwrite[] = { 616 #if defined(JALAPENO) 617 C_AFSR_ETP, 618 #elif defined(SERRANO) 619 C_AFSR_ETS | C_AFSR_ETU | C_AFSR_EFES, 620 #endif /* SERRANO */ 621 C_AFSR_UCC | C_AFSR_UCU, 622 C_AFSR_UE | C_AFSR_RUE | C_AFSR_BP | C_AFSR_WBP | C_AFSR_EDU | 623 C_AFSR_WDU | C_AFSR_CPU, 624 #if defined(SERRANO) 625 C_AFSR_ETI | C_AFSR_ETC | 626 #endif /* SERRANO */ 627 C_AFSR_CE | C_AFSR_RCE | C_AFSR_EDC | C_AFSR_WDC | C_AFSR_CPC, 628 C_AFSR_TO | C_AFSR_BERR, 629 C_AFSR_UMS | C_AFSR_OM, 630 0 631 }; 632 633 #if defined(SERRANO) 634 /* 635 * Serrano has a second AFAR that captures the physical address on 636 * FRC/FRU errors (which Jalapeno does not). This register also 637 * captures the address for UE and CE errors. 638 * 639 * See UltraSPARC-IIIi+ PRM 640 * Class 3: UE 641 * Class 2: FRU 642 * Class 1: CE 643 * Class 0: FRC 644 */ 645 uint64_t afar2_overwrite[] = { 646 C_AFSR_UE, 647 C_AFSR_FRU, 648 C_AFSR_CE, 649 C_AFSR_FRC, 650 0 651 }; 652 #endif /* SERRANO */ 653 654 /* 655 * See UltraSPARC-IIIi PRM 656 * Class 2: UE, FRU, EDU, WDU, UCU, CPU 657 * Class 1: CE, FRC, EDC, WDC, UCC, CPC 658 */ 659 uint64_t esynd_overwrite[] = { 660 #if defined(SERRANO) 661 C_AFSR_ETS | C_AFSR_ETU | 662 #endif /* SERRANO */ 663 C_AFSR_UE | C_AFSR_FRU | C_AFSR_EDU | C_AFSR_WDU | C_AFSR_UCU | 664 C_AFSR_CPU, 665 C_AFSR_CE | C_AFSR_FRC | C_AFSR_EDC | C_AFSR_WDC | C_AFSR_UCC | 666 C_AFSR_CPC, 667 0 668 }; 669 670 /* 671 * Prioritized list of Error bits for BSYND (referred to as 672 * MSYND to share code with CHEETAH & CHEETAH_PLUS) overwrite. 673 * See UltraSPARC-IIIi PRM 674 * Class 3: ISAP 675 * Class 2: BP 676 * Class 1: WBP, IVPE 677 */ 678 uint64_t msynd_overwrite[] = { 679 C_AFSR_ISAP, 680 C_AFSR_BP, 681 C_AFSR_WBP | C_AFSR_IVPE, 682 0 683 }; 684 685 /* 686 * change cpu speed bits -- new speed will be normal-speed/divisor. 687 * 688 * The Jalapeno memory controllers are required to drain outstanding 689 * memory transactions within 32 JBus clocks in order to be ready 690 * to enter Estar mode. In some corner cases however, that time 691 * fell short. 692 * 693 * A safe software solution is to force MCU to act like in Estar mode, 694 * then delay 1us (in ppm code) prior to assert J_CHNG_L signal. 695 * To reverse the effect, upon exiting Estar, software restores the 696 * MCU to its original state. 697 */ 698 /* ARGSUSED1 */ 699 void 700 cpu_change_speed(uint64_t divisor, uint64_t arg2) 701 { 702 bus_config_eclk_t *bceclk; 703 uint64_t reg; 704 uint64_t oldreg; 705 uint64_t mreg; 706 uint64_t val64; 707 int id = (CPU)->cpu_id; 708 processor_info_t *pi = &(CPU->cpu_type_info); 709 710 #if defined(JALAPENO) && defined(JALAPENO_ERRATA_85) 711 /* 712 * ASI Ecache flush in 1/2 or 1/32 speed mode can result 713 * in CPU fatal reset (JETO or IERR/TO on MP). A workaround 714 * is to force the CPU to full speed mode prior to using 715 * ASI Ecache flush opeartion to flush E$. Since we can't 716 * always use cross calls at the time of flushing E$, we 717 * cannot change other CPU speed. Hence, this workaround 718 * is applicable to uniprocessor configuration only and 719 * can't be used in multiprocessor configuration. 720 * 721 * Note that this workaround is activated only when the CPU 722 * has been fully initialized and its speed is lowered by the 723 * ppm for the first time. It can be disabled via /etc/system 724 * by setting jp_errata_85_enable to 0 and rebooting the 725 * system. 726 */ 727 if ((jp_errata_85_active == -1) && 728 jp_errata_85_enable && 729 (divisor != JBUS_CONFIG_ECLK_1_DIV)) { 730 if (ncpus == 1) 731 jp_errata_85_active = 1; 732 else 733 jp_errata_85_active = 0; 734 } 735 if ((!jp_errata_85_allow_slow_scrub) && (CPU_PRIVATE(CPU) != NULL)) { 736 int i; 737 ch_scrub_misc_t *chpr_scrubp = 738 CPU_PRIVATE_PTR(CPU, chpr_scrub_misc); 739 740 /* We're only allowed to run the scrubbers at full speed */ 741 742 for (i = 0; i < CACHE_SCRUBBER_COUNT; i++) { 743 chpr_scrubp->chsm_enable[i] = 744 (divisor == JBUS_CONFIG_ECLK_1_DIV); 745 } 746 } 747 #endif /* JALAPENO && JALAPENO_ERRATA_85 */ 748 749 /* 750 * We're only interested in mcu_ctl_reg1 bit 26 and 25, of which 751 * the value will be stored in the lower half of a byte. The 752 * top bit of this byte is designated as a valid bit - 0 means 753 * invalid, 1 means valid. 754 */ 755 if (!mcu_fsm_init_state[id].valid) { 756 val64 = get_mcu_ctl_reg1() & JP_MCU_FSM_MASK; 757 mcu_fsm_init_state[id].state = val64 >> JP_MCU_FSM_SHIFT; 758 mcu_fsm_init_state[id].valid = 1; 759 } 760 761 for (bceclk = bus_config_eclk; bceclk->divisor; bceclk++) { 762 if (bceclk->divisor != divisor) 763 continue; 764 reg = get_jbus_config(); 765 oldreg = reg; 766 reg &= ~JBUS_CONFIG_ECLK_MASK; 767 reg |= bceclk->mask; 768 set_jbus_config(reg); 769 (void) get_jbus_config(); 770 771 /* 772 * MCU workaround, refer to Jalapeno spec, EnergyStar section 773 * for detail. 774 */ 775 776 /* Upon entering engery star mode, turn off extra MCU FSMs */ 777 if (((oldreg & JBUS_CONFIG_ECLK_MASK) == JBUS_CONFIG_ECLK_1) && 778 ((divisor == JBUS_CONFIG_ECLK_2_DIV) || 779 (divisor == JBUS_CONFIG_ECLK_32_DIV))) { 780 mreg = get_mcu_ctl_reg1(); 781 if ((mreg & JP_MCU_FSM_MASK) != 0) { 782 mreg &= ~JP_MCU_FSM_MASK; 783 set_mcu_ctl_reg1(mreg); 784 (void) get_mcu_ctl_reg1(); 785 } 786 /* Upon exiting energy star mode, restore extra MCU FSMs */ 787 } else if (divisor == JBUS_CONFIG_ECLK_1_DIV) { 788 mreg = get_mcu_ctl_reg1(); 789 val64 = mcu_fsm_init_state[id].state; 790 mreg |= val64 << JP_MCU_FSM_SHIFT; 791 set_mcu_ctl_reg1(mreg); 792 (void) get_mcu_ctl_reg1(); 793 } 794 CPU->cpu_m.divisor = (uchar_t)divisor; 795 CPU->cpu_curr_clock = 796 (((uint64_t)pi->pi_clock * 1000000) / divisor); 797 return; 798 } 799 /* 800 * We will reach here only if OBP and kernel don't agree on 801 * the speeds supported by the CPU. 802 */ 803 cmn_err(CE_WARN, "cpu_change_speed: bad divisor %" PRIu64, divisor); 804 } 805 806 /* 807 * Cpu private initialization. This includes allocating the cpu_private 808 * data structure, initializing it, and initializing the scrubber for this 809 * cpu. This function calls cpu_init_ecache_scrub_dr to init the scrubber. 810 * We use kmem_cache_create for the cheetah private data structure because 811 * it needs to be allocated on a PAGESIZE (8192) byte boundary. 812 */ 813 void 814 cpu_init_private(struct cpu *cp) 815 { 816 cheetah_private_t *chprp; 817 int i; 818 819 ASSERT(CPU_PRIVATE(cp) == NULL); 820 821 /* LINTED: E_TRUE_LOGICAL_EXPR */ 822 ASSERT((offsetof(cheetah_private_t, chpr_tl1_err_data) + 823 sizeof (ch_err_tl1_data_t) * CH_ERR_TL1_TLMAX) <= PAGESIZE); 824 825 #if defined(SERRANO) 826 if (!IS_SERRANO(cpunodes[cp->cpu_id].implementation)) { 827 cmn_err(CE_PANIC, "CPU%d: implementation 0x%x not supported" 828 " on UltraSPARC-IIIi+ code\n", cp->cpu_id, 829 cpunodes[cp->cpu_id].implementation); 830 } 831 #else /* SERRANO */ 832 if (!IS_JALAPENO(cpunodes[cp->cpu_id].implementation)) { 833 cmn_err(CE_PANIC, "CPU%d: implementation 0x%x not supported" 834 " on UltraSPARC-IIIi code\n", cp->cpu_id, 835 cpunodes[cp->cpu_id].implementation); 836 } 837 #endif /* SERRANO */ 838 839 /* 840 * If the ch_private_cache has not been created, create it. 841 */ 842 if (ch_private_cache == NULL) { 843 ch_private_cache = kmem_cache_create("ch_private_cache", 844 sizeof (cheetah_private_t), PAGESIZE, NULL, NULL, 845 NULL, NULL, static_arena, 0); 846 } 847 848 chprp = CPU_PRIVATE(cp) = kmem_cache_alloc(ch_private_cache, KM_SLEEP); 849 850 bzero(chprp, sizeof (cheetah_private_t)); 851 chprp->chpr_fecctl0_logout.clo_data.chd_afar = LOGOUT_INVALID; 852 chprp->chpr_cecc_logout.clo_data.chd_afar = LOGOUT_INVALID; 853 chprp->chpr_async_logout.clo_data.chd_afar = LOGOUT_INVALID; 854 for (i = 0; i < CH_ERR_TL1_TLMAX; i++) 855 chprp->chpr_tl1_err_data[i].ch_err_tl1_logout.clo_data.chd_afar 856 = LOGOUT_INVALID; 857 858 chprp->chpr_icache_size = CH_ICACHE_SIZE; 859 chprp->chpr_icache_linesize = CH_ICACHE_LSIZE; 860 861 cpu_init_ecache_scrub_dr(cp); 862 863 chprp->chpr_ec_set_size = cpunodes[cp->cpu_id].ecache_size / 864 cpu_ecache_nway(); 865 866 adjust_hw_copy_limits(cpunodes[cp->cpu_id].ecache_size); 867 ch_err_tl1_paddrs[cp->cpu_id] = va_to_pa(chprp); 868 ASSERT(ch_err_tl1_paddrs[cp->cpu_id] != -1); 869 } 870 871 /* 872 * Clear the error state registers for this CPU. 873 * For Jalapeno, just clear the AFSR 874 */ 875 void 876 set_cpu_error_state(ch_cpu_errors_t *cpu_error_regs) 877 { 878 set_asyncflt(cpu_error_regs->afsr & ~C_AFSR_FATAL_ERRS); 879 } 880 881 /* 882 * Update cpu_offline_set so the scrubber knows which cpus are offline 883 */ 884 /*ARGSUSED*/ 885 int 886 cpu_scrub_cpu_setup(cpu_setup_t what, int cpuid, void *arg) 887 { 888 switch (what) { 889 case CPU_ON: 890 case CPU_INIT: 891 CPUSET_DEL(cpu_offline_set, cpuid); 892 break; 893 case CPU_OFF: 894 CPUSET_ADD(cpu_offline_set, cpuid); 895 break; 896 default: 897 break; 898 } 899 return (0); 900 } 901