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 uint64_t errors; 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 if (page_retire_check(aflt->flt_addr, &errors) == EINVAL) { 333 CE_XDIAG_SETSKIPCODE(aflt->flt_disp, 334 CE_XDIAG_SKIP_NOPP); 335 } else if (errors != PR_OK) { 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 /*FALLTHRU*/ 343 /* 344 * cases where we just want to report the error and continue. 345 */ 346 case CPU_BPAR: 347 case CPU_UMS: 348 case CPU_FRC: 349 case CPU_FRU: 350 cpu_log_err(aflt); 351 return (CH_ASYNC_LOG_DONE); 352 353 /* 354 * Cases where we want to fall through to handle panicking. 355 */ 356 case CPU_RUE: 357 cpu_log_err(aflt); 358 return (CH_ASYNC_LOG_CONTINUE); 359 360 default: 361 return (CH_ASYNC_LOG_UNKNOWN); 362 } 363 } 364 365 /* 366 * Figure out if Ecache is direct-mapped (Cheetah or Cheetah+ with Ecache 367 * control ECCR_ASSOC bit off or 2-way (Cheetah+ with ECCR_ASSOC on). 368 * We need to do this on the fly because we may have mixed Cheetah+'s with 369 * both direct and 2-way Ecaches. 370 */ 371 int 372 cpu_ecache_nway(void) 373 { 374 return (JP_ECACHE_NWAY); 375 } 376 377 /* 378 * Note that these are entered into the table in the order: 379 * Fatal Errors first, orphaned UCU/UCC, AFAR Overwrite policy, 380 * FRC/FRU, and finally IVPE. 381 * 382 * Afar overwrite policy is: 383 * Jalapeno: 384 * UCU,UCC > RUE,UE,EDU,WDU,CPU,WBP,BP > RCE,CE,EDC,WDC,CPC > 385 * TO,BERR > UMS,OM 386 * Serrano: 387 * UCU,UCC > RUE,UE,EDU,WDU,CPU,WBP,BP > RCE,CE,EDC,WDC,CPC,ETI,ETC > 388 * TO,BERR > UMS,OM 389 */ 390 ecc_type_to_info_t ecc_type_to_info[] = { 391 392 /* Fatal Errors */ 393 C_AFSR_JETO, "JETO ", ECC_ALL_TRAPS, CPU_FATAL, 394 "JETO Fatal", 395 FM_EREPORT_PAYLOAD_SYSTEM1, 396 FM_EREPORT_CPU_USIII_JETO, 397 C_AFSR_SCE, "SCE ", ECC_ALL_TRAPS, CPU_FATAL, 398 "SCE Fatal", 399 FM_EREPORT_PAYLOAD_SYSTEM1, 400 FM_EREPORT_CPU_USIII_SCE, 401 C_AFSR_JEIC, "JEIC ", ECC_ALL_TRAPS, CPU_FATAL, 402 "JEIC Fatal", 403 FM_EREPORT_PAYLOAD_SYSTEM1, 404 FM_EREPORT_CPU_USIII_JEIC, 405 C_AFSR_JEIT, "JEIT ", ECC_ALL_TRAPS, CPU_FATAL, 406 "JEIT Fatal", 407 FM_EREPORT_PAYLOAD_SYSTEM1, 408 FM_EREPORT_CPU_USIII_JEIT, 409 C_AFSR_JEIS, "JEIS ", ECC_ALL_TRAPS, CPU_FATAL, 410 "JEIS Fatal", 411 FM_EREPORT_PAYLOAD_SYSTEM1, 412 FM_EREPORT_CPU_USIII_JEIS, 413 #if defined(JALAPENO) 414 C_AFSR_ETP, "ETP ", ECC_ALL_TRAPS, CPU_FATAL, 415 "ETP Fatal", 416 FM_EREPORT_PAYLOAD_L2_TAG_PE, 417 FM_EREPORT_CPU_USIII_ETP, 418 #elif defined(SERRANO) 419 C_AFSR_ETS, "ETS ", ECC_ASYNC_TRAPS, CPU_FATAL, 420 "ETS Fatal", 421 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 422 FM_EREPORT_CPU_USIII_ETS, 423 C_AFSR_ETU, "ETU ", ECC_ASYNC_TRAPS, CPU_FATAL, 424 "ETU Fatal", 425 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 426 FM_EREPORT_CPU_USIII_ETU, 427 #endif /* SERRANO */ 428 C_AFSR_IERR, "IERR ", ECC_ALL_TRAPS, CPU_FATAL, 429 "IERR Fatal", 430 FM_EREPORT_PAYLOAD_SYSTEM2, 431 FM_EREPORT_CPU_USIII_IERR, 432 C_AFSR_ISAP, "ISAP ", ECC_ALL_TRAPS, CPU_FATAL, 433 "ISAP Fatal", 434 FM_EREPORT_PAYLOAD_SYSTEM1, 435 FM_EREPORT_CPU_USIII_ISAP, 436 437 /* Orphaned UCU/UCC Errors */ 438 C_AFSR_UCU, "OUCU ", ECC_ORPH_TRAPS, CPU_ORPH, 439 "Orphaned UCU", 440 FM_EREPORT_PAYLOAD_L2_DATA, 441 FM_EREPORT_CPU_USIII_UCU, 442 C_AFSR_UCC, "OUCC ", ECC_ORPH_TRAPS, CPU_ORPH, 443 "Orphaned UCC", 444 FM_EREPORT_PAYLOAD_L2_DATA, 445 FM_EREPORT_CPU_USIII_UCC, 446 447 /* UCU, UCC */ 448 C_AFSR_UCU, "UCU ", ECC_F_TRAP, CPU_UE_ECACHE, 449 "UCU", 450 FM_EREPORT_PAYLOAD_L2_DATA, 451 FM_EREPORT_CPU_USIII_UCU, 452 C_AFSR_UCC, "UCC ", ECC_F_TRAP, CPU_CE_ECACHE, 453 "UCC", 454 FM_EREPORT_PAYLOAD_L2_DATA, 455 FM_EREPORT_CPU_USIII_UCC, 456 457 458 /* RUE, UE, EDU:ST, EDU:BLD, WDU, CPU, BP, WBP */ 459 C_AFSR_RUE, "RUE ", ECC_ASYNC_TRAPS, CPU_RUE, 460 "Uncorrectable remote memory/cache (RUE)", 461 FM_EREPORT_PAYLOAD_MEMORY, 462 FM_EREPORT_CPU_USIII_RUE, 463 C_AFSR_UE, "UE ", ECC_ASYNC_TRAPS, CPU_UE, 464 "Uncorrectable memory (UE)", 465 FM_EREPORT_PAYLOAD_MEMORY, 466 FM_EREPORT_CPU_USIII_UE, 467 C_AFSR_EDU, "EDU ", ECC_C_TRAP, CPU_UE_ECACHE_RETIRE, 468 "EDU:ST", 469 FM_EREPORT_PAYLOAD_L2_DATA, 470 FM_EREPORT_CPU_USIII_EDUST, 471 C_AFSR_EDU, "EDU ", ECC_D_TRAP, CPU_UE_ECACHE_RETIRE, 472 "EDU:BLD", 473 FM_EREPORT_PAYLOAD_L2_DATA, 474 FM_EREPORT_CPU_USIII_EDUBL, 475 C_AFSR_WDU, "WDU ", ECC_C_TRAP, CPU_UE_ECACHE_RETIRE, 476 "WDU", 477 FM_EREPORT_PAYLOAD_L2_DATA, 478 FM_EREPORT_CPU_USIII_WDU, 479 C_AFSR_CPU, "CPU ", ECC_C_TRAP, CPU_UE_ECACHE, 480 "CPU", 481 FM_EREPORT_PAYLOAD_L2_DATA, 482 FM_EREPORT_CPU_USIII_CPU, 483 C_AFSR_WBP, "WBP ", ECC_C_TRAP, CPU_BPAR, 484 "JBUS parity error on writeback or block store (WBP)", 485 FM_EREPORT_PAYLOAD_SYSTEM3, 486 FM_EREPORT_CPU_USIII_WBP, 487 C_AFSR_BP, "BP ", ECC_ASYNC_TRAPS, CPU_BPAR, 488 "JBUS parity error on returned read data (BP)", 489 FM_EREPORT_PAYLOAD_SYSTEM3, 490 FM_EREPORT_CPU_USIII_BP, 491 492 /* RCE, CE, EDC, WDC, CPC */ 493 C_AFSR_RCE, "RCE ", ECC_C_TRAP, CPU_RCE, 494 "Corrected remote memory/cache (RCE)", 495 FM_EREPORT_PAYLOAD_MEMORY, 496 FM_EREPORT_CPU_USIII_RCE, 497 C_AFSR_CE, "CE ", ECC_C_TRAP, CPU_CE, 498 "Corrected memory (CE)", 499 FM_EREPORT_PAYLOAD_MEMORY, 500 FM_EREPORT_CPU_USIII_CE, 501 C_AFSR_EDC, "EDC ", ECC_C_TRAP, CPU_CE_ECACHE, 502 "EDC", 503 FM_EREPORT_PAYLOAD_L2_DATA, 504 FM_EREPORT_CPU_USIII_EDC, 505 C_AFSR_WDC, "WDC ", ECC_C_TRAP, CPU_CE_ECACHE, 506 "WDC", 507 FM_EREPORT_PAYLOAD_L2_DATA, 508 FM_EREPORT_CPU_USIII_WDC, 509 C_AFSR_CPC, "CPC ", ECC_C_TRAP, CPU_CE_ECACHE, 510 "CPC", 511 FM_EREPORT_PAYLOAD_L2_DATA, 512 FM_EREPORT_CPU_USIII_CPC, 513 #if defined(SERRANO) 514 /* ETI, ETC */ 515 C_AFSR_ETI, "ETI", ECC_F_TRAP | ECC_C_TRAP, CPU_CE_ECACHE, 516 "ETI", 517 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 518 FM_EREPORT_CPU_USIII_ETI, 519 C_AFSR_ETC, "ETC", ECC_F_TRAP | ECC_C_TRAP, CPU_CE_ECACHE, 520 "ETC", 521 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 522 FM_EREPORT_CPU_USIII_ETC, 523 #endif /* SERRANO */ 524 525 /* TO, BERR */ 526 C_AFSR_TO, "TO ", ECC_ASYNC_TRAPS, CPU_TO, 527 "Timeout (TO)", 528 FM_EREPORT_PAYLOAD_IO, 529 FM_EREPORT_CPU_USIII_TO, 530 C_AFSR_BERR, "BERR ", ECC_ASYNC_TRAPS, CPU_BERR, 531 "Bus Error (BERR)", 532 FM_EREPORT_PAYLOAD_IO, 533 FM_EREPORT_CPU_USIII_BERR, 534 535 /* UMS, OM */ 536 C_AFSR_UMS, "UMS ", ECC_C_TRAP, CPU_UMS, 537 "Unsupported store (UMS)", 538 FM_EREPORT_PAYLOAD_IO, 539 FM_EREPORT_CPU_USIII_UMS, 540 C_AFSR_OM, "OM ", ECC_ASYNC_TRAPS, CPU_BERR, 541 "Out of range memory (OM)", 542 FM_EREPORT_PAYLOAD_IO, 543 FM_EREPORT_CPU_USIII_OM, 544 545 /* FRC, FRU */ 546 C_AFSR_FRC, "FRC ", ECC_C_TRAP, CPU_FRC, 547 "Corrected memory (FRC)", 548 FM_EREPORT_PAYLOAD_MEMORY, 549 FM_EREPORT_CPU_USIII_FRC, 550 C_AFSR_FRU, "FRU ", ECC_C_TRAP, CPU_FRU, 551 "Uncorrectable memory (FRU)", 552 FM_EREPORT_PAYLOAD_MEMORY, 553 FM_EREPORT_CPU_USIII_FRU, 554 555 /* IVPE */ 556 C_AFSR_IVPE, "IVPE ", ECC_C_TRAP, CPU_IV, 557 "IVPE", 558 FM_EREPORT_PAYLOAD_SYSTEM1, 559 FM_EREPORT_CPU_USIII_IVPE, 560 561 0, NULL, 0, 0, 562 NULL, 563 FM_EREPORT_PAYLOAD_UNKNOWN, 564 FM_EREPORT_CPU_USIII_UNKNOWN, 565 }; 566 567 /* 568 * J_REQ overwrite policy (see UltraSPARC-IIIi PRM) 569 * 570 * Class 4: RUE, BP, WBP 571 * Class 3: RCE 572 * Class 2: TO, BERR 573 * Class 1: UMS 574 */ 575 uint64_t jreq_overwrite[] = { 576 C_AFSR_RUE | C_AFSR_BP | C_AFSR_WBP, 577 C_AFSR_RCE, 578 C_AFSR_TO | C_AFSR_BERR, 579 C_AFSR_UMS, 580 0 581 }; 582 583 /* 584 * AGENT ID overwrite policy (see UltraSPARC-IIIi PRM) 585 * 586 * Class 2: CPU, FRU 587 * Class 1: CPC, FRC 588 */ 589 uint64_t jbus_aid_overwrite[] = { 590 C_AFSR_CPU | C_AFSR_FRU, 591 C_AFSR_CPC | C_AFSR_FRC, 592 0 593 }; 594 595 int 596 afsr_to_jaid_status(uint64_t afsr, uint64_t afsr_bit) 597 { 598 return (afsr_to_overw_status(afsr, afsr_bit, jbus_aid_overwrite)); 599 } 600 601 /* 602 * See UltraSPARC-IIIi+ PRM 603 * Class 5: ETS, ETU, EFES 604 * Class 4: UCC, UCU 605 * Class 3: UE, RUE, BP, WBP, EDU, WDU, CPU 606 * Class 2: CE, RCE, EDC, WDC, CPC, ETI, ETC 607 * Class 1: TO, BERR 608 * Class 0: UMS, OM 609 * 610 * See UltraSPARC-IIIi PRM 611 * Class 5: ETP 612 * Class 4: UCC, UCU 613 * Class 3: UE, RUE, BP, WBP, EDU, WDU 614 * Class 2: CE, RCE, EDC, WDC 615 * Class 1: TO, BERR 616 * Class 0: UMS, OM 617 */ 618 uint64_t afar_overwrite[] = { 619 #if defined(JALAPENO) 620 C_AFSR_ETP, 621 #elif defined(SERRANO) 622 C_AFSR_ETS | C_AFSR_ETU | C_AFSR_EFES, 623 #endif /* SERRANO */ 624 C_AFSR_UCC | C_AFSR_UCU, 625 C_AFSR_UE | C_AFSR_RUE | C_AFSR_BP | C_AFSR_WBP | C_AFSR_EDU | 626 C_AFSR_WDU | C_AFSR_CPU, 627 #if defined(SERRANO) 628 C_AFSR_ETI | C_AFSR_ETC | 629 #endif /* SERRANO */ 630 C_AFSR_CE | C_AFSR_RCE | C_AFSR_EDC | C_AFSR_WDC | C_AFSR_CPC, 631 C_AFSR_TO | C_AFSR_BERR, 632 C_AFSR_UMS | C_AFSR_OM, 633 0 634 }; 635 636 #if defined(SERRANO) 637 /* 638 * Serrano has a second AFAR that captures the physical address on 639 * FRC/FRU errors (which Jalapeno does not). This register also 640 * captures the address for UE and CE errors. 641 * 642 * See UltraSPARC-IIIi+ PRM 643 * Class 3: UE 644 * Class 2: FRU 645 * Class 1: CE 646 * Class 0: FRC 647 */ 648 uint64_t afar2_overwrite[] = { 649 C_AFSR_UE, 650 C_AFSR_FRU, 651 C_AFSR_CE, 652 C_AFSR_FRC, 653 0 654 }; 655 #endif /* SERRANO */ 656 657 /* 658 * See UltraSPARC-IIIi PRM 659 * Class 2: UE, FRU, EDU, WDU, UCU, CPU 660 * Class 1: CE, FRC, EDC, WDC, UCC, CPC 661 */ 662 uint64_t esynd_overwrite[] = { 663 #if defined(SERRANO) 664 C_AFSR_ETS | C_AFSR_ETU | 665 #endif /* SERRANO */ 666 C_AFSR_UE | C_AFSR_FRU | C_AFSR_EDU | C_AFSR_WDU | C_AFSR_UCU | 667 C_AFSR_CPU, 668 C_AFSR_CE | C_AFSR_FRC | C_AFSR_EDC | C_AFSR_WDC | C_AFSR_UCC | 669 C_AFSR_CPC, 670 0 671 }; 672 673 /* 674 * Prioritized list of Error bits for BSYND (referred to as 675 * MSYND to share code with CHEETAH & CHEETAH_PLUS) overwrite. 676 * See UltraSPARC-IIIi PRM 677 * Class 3: ISAP 678 * Class 2: BP 679 * Class 1: WBP, IVPE 680 */ 681 uint64_t msynd_overwrite[] = { 682 C_AFSR_ISAP, 683 C_AFSR_BP, 684 C_AFSR_WBP | C_AFSR_IVPE, 685 0 686 }; 687 688 /* 689 * change cpu speed bits -- new speed will be normal-speed/divisor. 690 * 691 * The Jalapeno memory controllers are required to drain outstanding 692 * memory transactions within 32 JBus clocks in order to be ready 693 * to enter Estar mode. In some corner cases however, that time 694 * fell short. 695 * 696 * A safe software solution is to force MCU to act like in Estar mode, 697 * then delay 1us (in ppm code) prior to assert J_CHNG_L signal. 698 * To reverse the effect, upon exiting Estar, software restores the 699 * MCU to its original state. 700 */ 701 /* ARGSUSED1 */ 702 void 703 cpu_change_speed(uint64_t divisor, uint64_t arg2) 704 { 705 bus_config_eclk_t *bceclk; 706 uint64_t reg; 707 uint64_t oldreg; 708 uint64_t mreg; 709 uint64_t val64; 710 int id = (CPU)->cpu_id; 711 712 #if defined(JALAPENO) && defined(JALAPENO_ERRATA_85) 713 /* 714 * ASI Ecache flush in 1/2 or 1/32 speed mode can result 715 * in CPU fatal reset (JETO or IERR/TO on MP). A workaround 716 * is to force the CPU to full speed mode prior to using 717 * ASI Ecache flush opeartion to flush E$. Since we can't 718 * always use cross calls at the time of flushing E$, we 719 * cannot change other CPU speed. Hence, this workaround 720 * is applicable to uniprocessor configuration only and 721 * can't be used in multiprocessor configuration. 722 * 723 * Note that this workaround is activated only when the CPU 724 * has been fully initialized and its speed is lowered by the 725 * ppm for the first time. It can be disabled via /etc/system 726 * by setting jp_errata_85_enable to 0 and rebooting the 727 * system. 728 */ 729 if ((jp_errata_85_active == -1) && 730 jp_errata_85_enable && 731 (divisor != JBUS_CONFIG_ECLK_1_DIV)) { 732 if (ncpus == 1) 733 jp_errata_85_active = 1; 734 else 735 jp_errata_85_active = 0; 736 } 737 if ((!jp_errata_85_allow_slow_scrub) && (CPU_PRIVATE(CPU) != NULL)) { 738 int i; 739 ch_scrub_misc_t *chpr_scrubp = 740 CPU_PRIVATE_PTR(CPU, chpr_scrub_misc); 741 742 /* We're only allowed to run the scrubbers at full speed */ 743 744 for (i = 0; i < CACHE_SCRUBBER_COUNT; i++) { 745 chpr_scrubp->chsm_enable[i] = 746 (divisor == JBUS_CONFIG_ECLK_1_DIV); 747 } 748 } 749 #endif /* JALAPENO && JALAPENO_ERRATA_85 */ 750 751 /* 752 * We're only interested in mcu_ctl_reg1 bit 26 and 25, of which 753 * the value will be stored in the lower half of a byte. The 754 * top bit of this byte is designated as a valid bit - 0 means 755 * invalid, 1 means valid. 756 */ 757 if (!mcu_fsm_init_state[id].valid) { 758 val64 = get_mcu_ctl_reg1() & JP_MCU_FSM_MASK; 759 mcu_fsm_init_state[id].state = val64 >> JP_MCU_FSM_SHIFT; 760 mcu_fsm_init_state[id].valid = 1; 761 } 762 763 for (bceclk = bus_config_eclk; bceclk->divisor; bceclk++) { 764 if (bceclk->divisor != divisor) 765 continue; 766 reg = get_jbus_config(); 767 oldreg = reg; 768 reg &= ~JBUS_CONFIG_ECLK_MASK; 769 reg |= bceclk->mask; 770 set_jbus_config(reg); 771 (void) get_jbus_config(); 772 773 /* 774 * MCU workaround, refer to Jalapeno spec, EnergyStar section 775 * for detail. 776 */ 777 778 /* Upon entering engery star mode, turn off extra MCU FSMs */ 779 if (((oldreg & JBUS_CONFIG_ECLK_MASK) == JBUS_CONFIG_ECLK_1) && 780 ((divisor == JBUS_CONFIG_ECLK_2_DIV) || 781 (divisor == JBUS_CONFIG_ECLK_32_DIV))) { 782 mreg = get_mcu_ctl_reg1(); 783 if ((mreg & JP_MCU_FSM_MASK) != 0) { 784 mreg &= ~JP_MCU_FSM_MASK; 785 set_mcu_ctl_reg1(mreg); 786 (void) get_mcu_ctl_reg1(); 787 } 788 /* Upon exiting energy star mode, restore extra MCU FSMs */ 789 } else if (divisor == JBUS_CONFIG_ECLK_1_DIV) { 790 mreg = get_mcu_ctl_reg1(); 791 val64 = mcu_fsm_init_state[id].state; 792 mreg |= val64 << JP_MCU_FSM_SHIFT; 793 set_mcu_ctl_reg1(mreg); 794 (void) get_mcu_ctl_reg1(); 795 } 796 CPU->cpu_m.divisor = (uchar_t)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