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