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/fm/util.h> 64 #include <sys/pghw.h> 65 66 #ifdef CHEETAHPLUS_ERRATUM_25 67 #include <sys/cyclic.h> 68 #endif /* CHEETAHPLUS_ERRATUM_25 */ 69 70 /* 71 * See comment above cpu_scrub_cpu_setup() for description 72 */ 73 #define SCRUBBER_NEITHER_CORE_ONLINE 0x0 74 #define SCRUBBER_CORE_0_ONLINE 0x1 75 #define SCRUBBER_CORE_1_ONLINE 0x2 76 #define SCRUBBER_BOTH_CORES_ONLINE (SCRUBBER_CORE_0_ONLINE | \ 77 SCRUBBER_CORE_1_ONLINE) 78 79 static int pn_matching_valid_l2_line(uint64_t faddr, ch_ec_data_t *clo_l2_data); 80 static void cpu_async_log_tlb_parity_err(void *flt); 81 static cpu_t *cpu_get_sibling_core(cpu_t *cpup); 82 83 84 /* 85 * Setup trap handlers. 86 */ 87 void 88 cpu_init_trap(void) 89 { 90 CH_SET_TRAP(pil15_epilogue, ch_pil15_interrupt_instr); 91 92 CH_SET_TRAP(tt0_fecc, fecc_err_instr); 93 CH_SET_TRAP(tt1_fecc, fecc_err_tl1_instr); 94 CH_SET_TRAP(tt1_swtrap0, fecc_err_tl1_cont_instr); 95 96 CH_SET_TRAP(tt0_dperr, dcache_parity_instr); 97 CH_SET_TRAP(tt1_dperr, dcache_parity_tl1_instr); 98 CH_SET_TRAP(tt1_swtrap1, dcache_parity_tl1_cont_instr); 99 100 CH_SET_TRAP(tt0_iperr, icache_parity_instr); 101 CH_SET_TRAP(tt1_iperr, icache_parity_tl1_instr); 102 CH_SET_TRAP(tt1_swtrap2, icache_parity_tl1_cont_instr); 103 } 104 105 /* 106 * Set the magic constants of the implementation. 107 */ 108 /*ARGSUSED*/ 109 void 110 cpu_fiximp(pnode_t dnode) 111 { 112 int i, a; 113 extern int vac_size, vac_shift; 114 extern uint_t vac_mask; 115 116 dcache_size = CH_DCACHE_SIZE; 117 dcache_linesize = CH_DCACHE_LSIZE; 118 119 icache_size = CHP_ICACHE_MAX_SIZE; 120 icache_linesize = CHP_ICACHE_MIN_LSIZE; 121 122 ecache_size = CH_ECACHE_MAX_SIZE; 123 ecache_alignsize = CH_ECACHE_MAX_LSIZE; 124 ecache_associativity = CHP_ECACHE_MIN_NWAY; 125 126 /* 127 * ecache_setsize needs to maximum of all cpu ecache setsizes 128 */ 129 ecache_setsize = CHP_ECACHE_MAX_SETSIZE; 130 ASSERT(ecache_setsize >= (ecache_size / ecache_associativity)); 131 132 vac_size = CH_VAC_SIZE; 133 vac_mask = MMU_PAGEMASK & (vac_size - 1); 134 i = 0; a = vac_size; 135 while (a >>= 1) 136 ++i; 137 vac_shift = i; 138 shm_alignment = vac_size; 139 vac = 1; 140 } 141 142 /* 143 * Use Panther values for Panther-only domains. 144 * See Panther PRM, 1.5.4 Cache Hierarchy 145 */ 146 void 147 cpu_fix_allpanther(void) 148 { 149 /* dcache same as Ch+ */ 150 icache_size = PN_ICACHE_SIZE; 151 icache_linesize = PN_ICACHE_LSIZE; 152 ecache_size = PN_L3_SIZE; 153 ecache_alignsize = PN_L3_LINESIZE; 154 ecache_associativity = PN_L3_NWAYS; 155 ecache_setsize = PN_L3_SET_SIZE; 156 ASSERT(ecache_setsize >= (ecache_size / ecache_associativity)); 157 /* vac same as Ch+ */ 158 /* fix hwcaps for USIV+-only domains */ 159 cpu_hwcap_flags |= AV_SPARC_POPC; 160 } 161 162 void 163 send_mondo_set(cpuset_t set) 164 { 165 int lo, busy, nack, shipped = 0; 166 uint16_t i, cpuids[IDSR_BN_SETS]; 167 uint64_t idsr, nackmask = 0, busymask, curnack, curbusy; 168 uint64_t starttick, endtick, tick, lasttick; 169 #if (NCPU > IDSR_BN_SETS) 170 int index = 0; 171 int ncpuids = 0; 172 #endif 173 #ifdef CHEETAHPLUS_ERRATUM_25 174 int recovered = 0; 175 int cpuid; 176 #endif 177 178 ASSERT(!CPUSET_ISNULL(set)); 179 starttick = lasttick = gettick(); 180 181 #if (NCPU <= IDSR_BN_SETS) 182 for (i = 0; i < NCPU; i++) 183 if (CPU_IN_SET(set, i)) { 184 shipit(i, shipped); 185 nackmask |= IDSR_NACK_BIT(shipped); 186 cpuids[shipped++] = i; 187 CPUSET_DEL(set, i); 188 if (CPUSET_ISNULL(set)) 189 break; 190 } 191 CPU_STATS_ADDQ(CPU, sys, xcalls, shipped); 192 #else 193 for (i = 0; i < NCPU; i++) 194 if (CPU_IN_SET(set, i)) { 195 ncpuids++; 196 197 /* 198 * Ship only to the first (IDSR_BN_SETS) CPUs. If we 199 * find we have shipped to more than (IDSR_BN_SETS) 200 * CPUs, set "index" to the highest numbered CPU in 201 * the set so we can ship to other CPUs a bit later on. 202 */ 203 if (shipped < IDSR_BN_SETS) { 204 shipit(i, shipped); 205 nackmask |= IDSR_NACK_BIT(shipped); 206 cpuids[shipped++] = i; 207 CPUSET_DEL(set, i); 208 if (CPUSET_ISNULL(set)) 209 break; 210 } else 211 index = (int)i; 212 } 213 214 CPU_STATS_ADDQ(CPU, sys, xcalls, ncpuids); 215 #endif 216 217 busymask = IDSR_NACK_TO_BUSY(nackmask); 218 busy = nack = 0; 219 endtick = starttick + xc_tick_limit; 220 for (;;) { 221 idsr = getidsr(); 222 #if (NCPU <= IDSR_BN_SETS) 223 if (idsr == 0) 224 break; 225 #else 226 if (idsr == 0 && shipped == ncpuids) 227 break; 228 #endif 229 tick = gettick(); 230 /* 231 * If there is a big jump between the current tick 232 * count and lasttick, we have probably hit a break 233 * point. Adjust endtick accordingly to avoid panic. 234 */ 235 if (tick > (lasttick + xc_tick_jump_limit)) 236 endtick += (tick - lasttick); 237 lasttick = tick; 238 if (tick > endtick) { 239 if (panic_quiesce) 240 return; 241 #ifdef CHEETAHPLUS_ERRATUM_25 242 cpuid = -1; 243 for (i = 0; i < IDSR_BN_SETS; i++) { 244 if (idsr & (IDSR_NACK_BIT(i) | 245 IDSR_BUSY_BIT(i))) { 246 cpuid = cpuids[i]; 247 break; 248 } 249 } 250 if (cheetah_sendmondo_recover && cpuid != -1 && 251 recovered == 0) { 252 if (mondo_recover(cpuid, i)) { 253 /* 254 * We claimed the whole memory or 255 * full scan is disabled. 256 */ 257 recovered++; 258 } 259 tick = gettick(); 260 endtick = tick + xc_tick_limit; 261 lasttick = tick; 262 /* 263 * Recheck idsr 264 */ 265 continue; 266 } else 267 #endif /* CHEETAHPLUS_ERRATUM_25 */ 268 { 269 cmn_err(CE_CONT, "send mondo timeout " 270 "[%d NACK %d BUSY]\nIDSR 0x%" 271 "" PRIx64 " cpuids:", nack, busy, idsr); 272 for (i = 0; i < IDSR_BN_SETS; i++) { 273 if (idsr & (IDSR_NACK_BIT(i) | 274 IDSR_BUSY_BIT(i))) { 275 cmn_err(CE_CONT, " 0x%x", 276 cpuids[i]); 277 } 278 } 279 cmn_err(CE_CONT, "\n"); 280 cmn_err(CE_PANIC, "send_mondo_set: timeout"); 281 } 282 } 283 curnack = idsr & nackmask; 284 curbusy = idsr & busymask; 285 #if (NCPU > IDSR_BN_SETS) 286 if (shipped < ncpuids) { 287 uint64_t cpus_left; 288 uint16_t next = (uint16_t)index; 289 290 cpus_left = ~(IDSR_NACK_TO_BUSY(curnack) | curbusy) & 291 busymask; 292 293 if (cpus_left) { 294 do { 295 /* 296 * Sequence through and ship to the 297 * remainder of the CPUs in the system 298 * (e.g. other than the first 299 * (IDSR_BN_SETS)) in reverse order. 300 */ 301 lo = lowbit(cpus_left) - 1; 302 i = IDSR_BUSY_IDX(lo); 303 shipit(next, i); 304 shipped++; 305 cpuids[i] = next; 306 307 /* 308 * If we've processed all the CPUs, 309 * exit the loop now and save 310 * instructions. 311 */ 312 if (shipped == ncpuids) 313 break; 314 315 for ((index = ((int)next - 1)); 316 index >= 0; index--) 317 if (CPU_IN_SET(set, index)) { 318 next = (uint16_t)index; 319 break; 320 } 321 322 cpus_left &= ~(1ull << lo); 323 } while (cpus_left); 324 #ifdef CHEETAHPLUS_ERRATUM_25 325 /* 326 * Clear recovered because we are sending to 327 * a new set of targets. 328 */ 329 recovered = 0; 330 #endif 331 continue; 332 } 333 } 334 #endif 335 if (curbusy) { 336 busy++; 337 continue; 338 } 339 340 #ifdef SEND_MONDO_STATS 341 { 342 int n = gettick() - starttick; 343 if (n < 8192) 344 x_nack_stimes[n >> 7]++; 345 } 346 #endif 347 while (gettick() < (tick + sys_clock_mhz)) 348 ; 349 do { 350 lo = lowbit(curnack) - 1; 351 i = IDSR_NACK_IDX(lo); 352 shipit(cpuids[i], i); 353 curnack &= ~(1ull << lo); 354 } while (curnack); 355 nack++; 356 busy = 0; 357 } 358 #ifdef SEND_MONDO_STATS 359 { 360 int n = gettick() - starttick; 361 if (n < 8192) 362 x_set_stimes[n >> 7]++; 363 else 364 x_set_ltimes[(n >> 13) & 0xf]++; 365 } 366 x_set_cpus[shipped]++; 367 #endif 368 } 369 370 /* 371 * Handles error logging for implementation specific error types 372 */ 373 /*ARGSUSED1*/ 374 int 375 cpu_impl_async_log_err(void *flt, errorq_elem_t *eqep) 376 { 377 ch_async_flt_t *ch_flt = (ch_async_flt_t *)flt; 378 struct async_flt *aflt = (struct async_flt *)flt; 379 380 switch (ch_flt->flt_type) { 381 382 case CPU_IC_PARITY: 383 cpu_async_log_ic_parity_err(flt); 384 return (CH_ASYNC_LOG_DONE); 385 386 case CPU_DC_PARITY: 387 cpu_async_log_dc_parity_err(flt); 388 return (CH_ASYNC_LOG_DONE); 389 390 case CPU_DUE: 391 cpu_log_err(aflt); 392 cpu_page_retire(ch_flt); 393 return (CH_ASYNC_LOG_DONE); 394 395 case CPU_ITLB_PARITY: 396 case CPU_DTLB_PARITY: 397 cpu_async_log_tlb_parity_err(flt); 398 return (CH_ASYNC_LOG_DONE); 399 400 /* report the error and continue */ 401 case CPU_L3_ADDR_PE: 402 cpu_log_err(aflt); 403 return (CH_ASYNC_LOG_DONE); 404 405 default: 406 return (CH_ASYNC_LOG_UNKNOWN); 407 } 408 } 409 410 /* 411 * Figure out if Ecache is direct-mapped (Cheetah or Cheetah+ with Ecache 412 * control ECCR_ASSOC bit off or 2-way (Cheetah+ with ECCR_ASSOC on). 413 * We need to do this on the fly because we may have mixed Cheetah+'s with 414 * both direct and 2-way Ecaches. Panther only supports 4-way L3$. 415 */ 416 int 417 cpu_ecache_nway(void) 418 { 419 if (IS_PANTHER(cpunodes[CPU->cpu_id].implementation)) 420 return (PN_L3_NWAYS); 421 return ((get_ecache_ctrl() & ECCR_ASSOC) ? 2 : 1); 422 } 423 424 /* 425 * Note that these are entered into the table: Fatal Errors (PERR, IERR, ISAP, 426 * EMU, IMU) first, orphaned UCU/UCC, AFAR Overwrite policy, finally IVU, IVC. 427 * Afar overwrite policy is: 428 * Class 4: 429 * AFSR -- UCC, UCU, TUE, TSCE, TUE_SH 430 * AFSR_EXT -- L3_UCC, L3_UCU, L3_TUE, L3_TUE_SH 431 * Class 3: 432 * AFSR -- UE, DUE, EDU, WDU, CPU 433 * AFSR_EXT -- L3_EDU, L3_WDU, L3_CPU 434 * Class 2: 435 * AFSR -- CE, EDC, EMC, WDC, CPC, THCE 436 * AFSR_EXT -- L3_EDC, L3_WDC, L3_CPC, L3_THCE 437 * Class 1: 438 * AFSR -- TO, DTO, BERR, DBERR 439 */ 440 ecc_type_to_info_t ecc_type_to_info[] = { 441 442 /* Fatal Errors */ 443 C_AFSR_PERR, "PERR ", ECC_ALL_TRAPS, 444 CPU_FATAL, "PERR Fatal", 445 FM_EREPORT_PAYLOAD_SYSTEM2, 446 FM_EREPORT_CPU_USIII_PERR, 447 C_AFSR_IERR, "IERR ", ECC_ALL_TRAPS, 448 CPU_FATAL, "IERR Fatal", 449 FM_EREPORT_PAYLOAD_SYSTEM2, 450 FM_EREPORT_CPU_USIII_IERR, 451 C_AFSR_ISAP, "ISAP ", ECC_ALL_TRAPS, 452 CPU_FATAL, "ISAP Fatal", 453 FM_EREPORT_PAYLOAD_SYSTEM1, 454 FM_EREPORT_CPU_USIII_ISAP, 455 C_AFSR_L3_TUE_SH, "L3_TUE_SH ", ECC_C_TRAP, 456 CPU_FATAL, "L3_TUE_SH Fatal", 457 FM_EREPORT_PAYLOAD_L3_TAG_ECC, 458 FM_EREPORT_CPU_USIII_L3_TUE_SH, 459 C_AFSR_L3_TUE, "L3_TUE ", ECC_C_TRAP, 460 CPU_FATAL, "L3_TUE Fatal", 461 FM_EREPORT_PAYLOAD_L3_TAG_ECC, 462 FM_EREPORT_CPU_USIII_L3_TUE, 463 C_AFSR_TUE_SH, "TUE_SH ", ECC_C_TRAP, 464 CPU_FATAL, "TUE_SH Fatal", 465 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 466 FM_EREPORT_CPU_USIII_TUE_SH, 467 C_AFSR_TUE, "TUE ", ECC_ALL_TRAPS, 468 CPU_FATAL, "TUE Fatal", 469 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 470 FM_EREPORT_CPU_USIII_TUE, 471 C_AFSR_EMU, "EMU ", ECC_ASYNC_TRAPS, 472 CPU_FATAL, "EMU Fatal", 473 FM_EREPORT_PAYLOAD_MEMORY, 474 FM_EREPORT_CPU_USIII_EMU, 475 C_AFSR_IMU, "IMU ", ECC_C_TRAP, 476 CPU_FATAL, "IMU Fatal", 477 FM_EREPORT_PAYLOAD_SYSTEM1, 478 FM_EREPORT_CPU_USIII_IMU, 479 480 /* L3$ Address parity errors are reported via the MECC bit */ 481 C_AFSR_L3_MECC, "L3_MECC ", ECC_MECC_TRAPS, 482 CPU_L3_ADDR_PE, "L3 Address Parity", 483 FM_EREPORT_PAYLOAD_L3_DATA, 484 FM_EREPORT_CPU_USIII_L3_MECC, 485 486 /* Orphaned UCC/UCU Errors */ 487 C_AFSR_L3_UCU, "L3_OUCU ", ECC_ORPH_TRAPS, 488 CPU_ORPH, "Orphaned L3_UCU", 489 FM_EREPORT_PAYLOAD_L3_DATA, 490 FM_EREPORT_CPU_USIII_L3_UCU, 491 C_AFSR_L3_UCC, "L3_OUCC ", ECC_ORPH_TRAPS, 492 CPU_ORPH, "Orphaned L3_UCC", 493 FM_EREPORT_PAYLOAD_L3_DATA, 494 FM_EREPORT_CPU_USIII_L3_UCC, 495 C_AFSR_UCU, "OUCU ", ECC_ORPH_TRAPS, 496 CPU_ORPH, "Orphaned UCU", 497 FM_EREPORT_PAYLOAD_L2_DATA, 498 FM_EREPORT_CPU_USIII_UCU, 499 C_AFSR_UCC, "OUCC ", ECC_ORPH_TRAPS, 500 CPU_ORPH, "Orphaned UCC", 501 FM_EREPORT_PAYLOAD_L2_DATA, 502 FM_EREPORT_CPU_USIII_UCC, 503 504 /* UCU, UCC */ 505 C_AFSR_L3_UCU, "L3_UCU ", ECC_F_TRAP, 506 CPU_UE_ECACHE, "L3_UCU", 507 FM_EREPORT_PAYLOAD_L3_DATA, 508 FM_EREPORT_CPU_USIII_L3_UCU, 509 C_AFSR_L3_UCC, "L3_UCC ", ECC_F_TRAP, 510 CPU_CE_ECACHE, "L3_UCC", 511 FM_EREPORT_PAYLOAD_L3_DATA, 512 FM_EREPORT_CPU_USIII_L3_UCC, 513 C_AFSR_UCU, "UCU ", ECC_F_TRAP, 514 CPU_UE_ECACHE, "UCU", 515 FM_EREPORT_PAYLOAD_L2_DATA, 516 FM_EREPORT_CPU_USIII_UCU, 517 C_AFSR_UCC, "UCC ", ECC_F_TRAP, 518 CPU_CE_ECACHE, "UCC", 519 FM_EREPORT_PAYLOAD_L2_DATA, 520 FM_EREPORT_CPU_USIII_UCC, 521 C_AFSR_TSCE, "TSCE ", ECC_F_TRAP, 522 CPU_CE_ECACHE, "TSCE", 523 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 524 FM_EREPORT_CPU_USIII_TSCE, 525 526 /* UE, EDU:ST, EDU:BLD, WDU, CPU */ 527 C_AFSR_UE, "UE ", ECC_ASYNC_TRAPS, 528 CPU_UE, "Uncorrectable system bus (UE)", 529 FM_EREPORT_PAYLOAD_MEMORY, 530 FM_EREPORT_CPU_USIII_UE, 531 C_AFSR_L3_EDU, "L3_EDU ", ECC_C_TRAP, 532 CPU_UE_ECACHE_RETIRE, "L3_EDU:ST", 533 FM_EREPORT_PAYLOAD_L3_DATA, 534 FM_EREPORT_CPU_USIII_L3_EDUST, 535 C_AFSR_L3_EDU, "L3_EDU ", ECC_D_TRAP, 536 CPU_UE_ECACHE_RETIRE, "L3_EDU:BLD", 537 FM_EREPORT_PAYLOAD_L3_DATA, 538 FM_EREPORT_CPU_USIII_L3_EDUBL, 539 C_AFSR_L3_WDU, "L3_WDU ", ECC_C_TRAP, 540 CPU_UE_ECACHE_RETIRE, "L3_WDU", 541 FM_EREPORT_PAYLOAD_L3_DATA, 542 FM_EREPORT_CPU_USIII_L3_WDU, 543 C_AFSR_L3_CPU, "L3_CPU ", ECC_C_TRAP, 544 CPU_UE_ECACHE, "L3_CPU", 545 FM_EREPORT_PAYLOAD_L3_DATA, 546 FM_EREPORT_CPU_USIII_L3_CPU, 547 C_AFSR_EDU, "EDU ", ECC_C_TRAP, 548 CPU_UE_ECACHE_RETIRE, "EDU:ST", 549 FM_EREPORT_PAYLOAD_L2_DATA, 550 FM_EREPORT_CPU_USIII_EDUST, 551 C_AFSR_EDU, "EDU ", ECC_D_TRAP, 552 CPU_UE_ECACHE_RETIRE, "EDU:BLD", 553 FM_EREPORT_PAYLOAD_L2_DATA, 554 FM_EREPORT_CPU_USIII_EDUBL, 555 C_AFSR_WDU, "WDU ", ECC_C_TRAP, 556 CPU_UE_ECACHE_RETIRE, "WDU", 557 FM_EREPORT_PAYLOAD_L2_DATA, 558 FM_EREPORT_CPU_USIII_WDU, 559 C_AFSR_CPU, "CPU ", ECC_C_TRAP, 560 CPU_UE_ECACHE, "CPU", 561 FM_EREPORT_PAYLOAD_L2_DATA, 562 FM_EREPORT_CPU_USIII_CPU, 563 C_AFSR_DUE, "DUE ", ECC_C_TRAP, 564 CPU_DUE, "DUE", 565 FM_EREPORT_PAYLOAD_MEMORY, 566 FM_EREPORT_CPU_USIII_DUE, 567 568 /* CE, EDC, EMC, WDC, CPC */ 569 C_AFSR_CE, "CE ", ECC_C_TRAP, 570 CPU_CE, "Corrected system bus (CE)", 571 FM_EREPORT_PAYLOAD_MEMORY, 572 FM_EREPORT_CPU_USIII_CE, 573 C_AFSR_L3_EDC, "L3_EDC ", ECC_C_TRAP, 574 CPU_CE_ECACHE, "L3_EDC", 575 FM_EREPORT_PAYLOAD_L3_DATA, 576 FM_EREPORT_CPU_USIII_L3_EDC, 577 C_AFSR_EDC, "EDC ", ECC_C_TRAP, 578 CPU_CE_ECACHE, "EDC", 579 FM_EREPORT_PAYLOAD_L2_DATA, 580 FM_EREPORT_CPU_USIII_EDC, 581 C_AFSR_EMC, "EMC ", ECC_C_TRAP, 582 CPU_EMC, "EMC", 583 FM_EREPORT_PAYLOAD_MEMORY, 584 FM_EREPORT_CPU_USIII_EMC, 585 C_AFSR_L3_WDC, "L3_WDC ", ECC_C_TRAP, 586 CPU_CE_ECACHE, "L3_WDC", 587 FM_EREPORT_PAYLOAD_L3_DATA, 588 FM_EREPORT_CPU_USIII_L3_WDC, 589 C_AFSR_L3_CPC, "L3_CPC ", ECC_C_TRAP, 590 CPU_CE_ECACHE, "L3_CPC", 591 FM_EREPORT_PAYLOAD_L3_DATA, 592 FM_EREPORT_CPU_USIII_L3_CPC, 593 C_AFSR_L3_THCE, "L3_THCE ", ECC_C_TRAP, 594 CPU_CE_ECACHE, "L3_THCE", 595 FM_EREPORT_PAYLOAD_L3_TAG_ECC, 596 FM_EREPORT_CPU_USIII_L3_THCE, 597 C_AFSR_WDC, "WDC ", ECC_C_TRAP, 598 CPU_CE_ECACHE, "WDC", 599 FM_EREPORT_PAYLOAD_L2_DATA, 600 FM_EREPORT_CPU_USIII_WDC, 601 C_AFSR_CPC, "CPC ", ECC_C_TRAP, 602 CPU_CE_ECACHE, "CPC", 603 FM_EREPORT_PAYLOAD_L2_DATA, 604 FM_EREPORT_CPU_USIII_CPC, 605 C_AFSR_THCE, "THCE ", ECC_C_TRAP, 606 CPU_CE_ECACHE, "THCE", 607 FM_EREPORT_PAYLOAD_L2_TAG_ECC, 608 FM_EREPORT_CPU_USIII_THCE, 609 610 /* TO, BERR */ 611 C_AFSR_TO, "TO ", ECC_ASYNC_TRAPS, 612 CPU_TO, "Timeout (TO)", 613 FM_EREPORT_PAYLOAD_IO, 614 FM_EREPORT_CPU_USIII_TO, 615 C_AFSR_BERR, "BERR ", ECC_ASYNC_TRAPS, 616 CPU_BERR, "Bus Error (BERR)", 617 FM_EREPORT_PAYLOAD_IO, 618 FM_EREPORT_CPU_USIII_BERR, 619 C_AFSR_DTO, "DTO ", ECC_C_TRAP, 620 CPU_TO, "Disrupting Timeout (DTO)", 621 FM_EREPORT_PAYLOAD_IO, 622 FM_EREPORT_CPU_USIII_DTO, 623 C_AFSR_DBERR, "DBERR ", ECC_C_TRAP, 624 CPU_BERR, "Disrupting Bus Error (DBERR)", 625 FM_EREPORT_PAYLOAD_IO, 626 FM_EREPORT_CPU_USIII_DBERR, 627 628 /* IVU, IVC, IMC */ 629 C_AFSR_IVU, "IVU ", ECC_C_TRAP, 630 CPU_IV, "IVU", 631 FM_EREPORT_PAYLOAD_SYSTEM1, 632 FM_EREPORT_CPU_USIII_IVU, 633 C_AFSR_IVC, "IVC ", ECC_C_TRAP, 634 CPU_IV, "IVC", 635 FM_EREPORT_PAYLOAD_SYSTEM1, 636 FM_EREPORT_CPU_USIII_IVC, 637 C_AFSR_IMC, "IMC ", ECC_C_TRAP, 638 CPU_IV, "IMC", 639 FM_EREPORT_PAYLOAD_SYSTEM1, 640 FM_EREPORT_CPU_USIII_IMC, 641 642 0, NULL, 0, 643 0, NULL, 644 FM_EREPORT_PAYLOAD_UNKNOWN, 645 FM_EREPORT_CPU_USIII_UNKNOWN, 646 }; 647 648 /* 649 * See Cheetah+ Delta PRM 10.9 and section P.6.1 of the Panther PRM 650 * Class 4: 651 * AFSR -- UCC, UCU, TUE, TSCE, TUE_SH 652 * AFSR_EXT -- L3_UCC, L3_UCU, L3_TUE, L3_TUE_SH 653 * Class 3: 654 * AFSR -- UE, DUE, EDU, EMU, WDU, CPU 655 * AFSR_EXT -- L3_EDU, L3_WDU, L3_CPU 656 * Class 2: 657 * AFSR -- CE, EDC, EMC, WDC, CPC, THCE 658 * AFSR_EXT -- L3_EDC, L3_WDC, L3_CPC, L3_THCE 659 * Class 1: 660 * AFSR -- TO, DTO, BERR, DBERR 661 * AFSR_EXT -- 662 */ 663 uint64_t afar_overwrite[] = { 664 /* class 4: */ 665 C_AFSR_UCC | C_AFSR_UCU | C_AFSR_TUE | C_AFSR_TSCE | C_AFSR_TUE_SH | 666 C_AFSR_L3_UCC | C_AFSR_L3_UCU | C_AFSR_L3_TUE | C_AFSR_L3_TUE_SH, 667 /* class 3: */ 668 C_AFSR_UE | C_AFSR_DUE | C_AFSR_EDU | C_AFSR_EMU | C_AFSR_WDU | 669 C_AFSR_CPU | C_AFSR_L3_EDU | C_AFSR_L3_WDU | C_AFSR_L3_CPU, 670 /* class 2: */ 671 C_AFSR_CE | C_AFSR_EDC | C_AFSR_EMC | C_AFSR_WDC | C_AFSR_CPC | 672 C_AFSR_THCE | C_AFSR_L3_EDC | C_AFSR_L3_WDC | C_AFSR_L3_CPC | 673 C_AFSR_L3_THCE, 674 /* class 1: */ 675 C_AFSR_TO | C_AFSR_DTO | C_AFSR_BERR | C_AFSR_DBERR, 676 677 0 678 }; 679 680 /* 681 * For Cheetah+, the E_SYND and M_SYND overwrite priorities are combined. 682 * See Cheetah+ Delta PRM 10.9 and Cheetah+ PRM 11.6.2 683 * Class 2: UE, DUE, IVU, EDU, EMU, WDU, UCU, CPU 684 * Class 1: CE, IVC, EDC, EMC, WDC, UCC, CPC 685 */ 686 uint64_t esynd_overwrite[] = { 687 /* class 2: */ 688 C_AFSR_UE | C_AFSR_DUE | C_AFSR_IVU | C_AFSR_EDU | C_AFSR_EMU | 689 C_AFSR_WDU | C_AFSR_UCU | C_AFSR_CPU, 690 /* class 1: */ 691 C_AFSR_CE | C_AFSR_IVC | C_AFSR_EDC | C_AFSR_EMC | C_AFSR_WDC | 692 C_AFSR_UCC | C_AFSR_CPC, 693 0 694 }; 695 696 /* 697 * In panther, the E_SYND overwrite policy changed a little bit 698 * by adding one more level. 699 * See Panther PRM P.6.2 700 * class 3: 701 * AFSR -- UCU, UCC 702 * AFSR_EXT -- L3_UCU, L3_UCC 703 * Class 2: 704 * AFSR -- UE, DUE, IVU, EDU, WDU, CPU 705 * AFSR_EXT -- L3_EDU, L3_WDU, L3_CPU 706 * Class 1: 707 * AFSR -- CE, IVC, EDC, WDC, CPC 708 * AFSR_EXT -- L3_EDC, L3_WDC, L3_CPC 709 */ 710 uint64_t pn_esynd_overwrite[] = { 711 /* class 3: */ 712 C_AFSR_UCU | C_AFSR_UCC | 713 C_AFSR_L3_UCU | C_AFSR_L3_UCC, 714 /* class 2: */ 715 C_AFSR_UE | C_AFSR_DUE | C_AFSR_IVU | C_AFSR_EDU | C_AFSR_WDU | 716 C_AFSR_CPU | 717 C_AFSR_L3_EDU | C_AFSR_L3_WDU | C_AFSR_L3_CPU, 718 /* class 1: */ 719 C_AFSR_CE | C_AFSR_IVC | C_AFSR_EDC | C_AFSR_WDC | C_AFSR_CPC | 720 C_AFSR_L3_EDC | C_AFSR_L3_WDC | C_AFSR_L3_CPC, 721 722 0 723 }; 724 725 int 726 afsr_to_pn_esynd_status(uint64_t afsr, uint64_t afsr_bit) 727 { 728 return (afsr_to_overw_status(afsr, afsr_bit, pn_esynd_overwrite)); 729 } 730 731 /* 732 * Prioritized list of Error bits for MSYND overwrite. 733 * See Panther PRM P.6.2 (For Cheetah+, see esynd_overwrite classes) 734 * Class 2: EMU, IMU 735 * Class 1: EMC, IMC 736 * 737 * Panther adds IMU and IMC. 738 */ 739 uint64_t msynd_overwrite[] = { 740 /* class 2: */ 741 C_AFSR_EMU | C_AFSR_IMU, 742 /* class 1: */ 743 C_AFSR_EMC | C_AFSR_IMC, 744 745 0 746 }; 747 748 /* 749 * change cpu speed bits -- new speed will be normal-speed/divisor. 750 * 751 * The Jalapeno memory controllers are required to drain outstanding 752 * memory transactions within 32 JBus clocks in order to be ready 753 * to enter Estar mode. In some corner cases however, that time 754 * fell short. 755 * 756 * A safe software solution is to force MCU to act like in Estar mode, 757 * then delay 1us (in ppm code) prior to assert J_CHNG_L signal. 758 * To reverse the effect, upon exiting Estar, software restores the 759 * MCU to its original state. 760 */ 761 /* ARGSUSED1 */ 762 void 763 cpu_change_speed(uint64_t divisor, uint64_t arg2) 764 { 765 bus_config_eclk_t *bceclk; 766 uint64_t reg; 767 processor_info_t *pi = &(CPU->cpu_type_info); 768 769 for (bceclk = bus_config_eclk; bceclk->divisor; bceclk++) { 770 if (bceclk->divisor != divisor) 771 continue; 772 reg = get_safari_config(); 773 reg &= ~SAFARI_CONFIG_ECLK_MASK; 774 reg |= bceclk->mask; 775 set_safari_config(reg); 776 CPU->cpu_m.divisor = (uchar_t)divisor; 777 cpu_set_curr_clock(((uint64_t)pi->pi_clock * 1000000) / 778 divisor); 779 return; 780 } 781 /* 782 * We will reach here only if OBP and kernel don't agree on 783 * the speeds supported by the CPU. 784 */ 785 cmn_err(CE_WARN, "cpu_change_speed: bad divisor %" PRIu64, divisor); 786 } 787 788 /* 789 * Cpu private initialization. This includes allocating the cpu_private 790 * data structure, initializing it, and initializing the scrubber for this 791 * cpu. This function calls cpu_init_ecache_scrub_dr to init the scrubber. 792 * We use kmem_cache_create for the cheetah private data structure because 793 * it needs to be allocated on a PAGESIZE (8192) byte boundary. 794 */ 795 void 796 cpu_init_private(struct cpu *cp) 797 { 798 cheetah_private_t *chprp; 799 int i; 800 801 ASSERT(CPU_PRIVATE(cp) == NULL); 802 803 /* LINTED: E_TRUE_LOGICAL_EXPR */ 804 ASSERT((offsetof(cheetah_private_t, chpr_tl1_err_data) + 805 sizeof (ch_err_tl1_data_t) * CH_ERR_TL1_TLMAX) <= PAGESIZE); 806 807 /* 808 * Running with Cheetah CPUs in a Cheetah+, Jaguar, Panther or 809 * mixed Cheetah+/Jaguar/Panther machine is not a supported 810 * configuration. Attempting to do so may result in unpredictable 811 * failures (e.g. running Cheetah+ CPUs with Cheetah E$ disp flush) 812 * so don't allow it. 813 * 814 * This is just defensive code since this configuration mismatch 815 * should have been caught prior to OS execution. 816 */ 817 if (!(IS_CHEETAH_PLUS(cpunodes[cp->cpu_id].implementation) || 818 IS_JAGUAR(cpunodes[cp->cpu_id].implementation) || 819 IS_PANTHER(cpunodes[cp->cpu_id].implementation))) { 820 cmn_err(CE_PANIC, "CPU%d: UltraSPARC-III not supported" 821 " on UltraSPARC-III+/IV/IV+ code\n", cp->cpu_id); 822 } 823 824 /* 825 * If the ch_private_cache has not been created, create it. 826 */ 827 if (ch_private_cache == NULL) { 828 ch_private_cache = kmem_cache_create("ch_private_cache", 829 sizeof (cheetah_private_t), PAGESIZE, NULL, NULL, 830 NULL, NULL, static_arena, 0); 831 } 832 833 chprp = CPU_PRIVATE(cp) = kmem_cache_alloc(ch_private_cache, KM_SLEEP); 834 835 bzero(chprp, sizeof (cheetah_private_t)); 836 chprp->chpr_fecctl0_logout.clo_data.chd_afar = LOGOUT_INVALID; 837 chprp->chpr_cecc_logout.clo_data.chd_afar = LOGOUT_INVALID; 838 chprp->chpr_async_logout.clo_data.chd_afar = LOGOUT_INVALID; 839 chprp->chpr_tlb_logout.tlo_addr = LOGOUT_INVALID; 840 for (i = 0; i < CH_ERR_TL1_TLMAX; i++) 841 chprp->chpr_tl1_err_data[i].ch_err_tl1_logout.clo_data.chd_afar 842 = LOGOUT_INVALID; 843 844 /* Panther has a larger Icache compared to cheetahplus or Jaguar */ 845 if (IS_PANTHER(cpunodes[cp->cpu_id].implementation)) { 846 chprp->chpr_icache_size = PN_ICACHE_SIZE; 847 chprp->chpr_icache_linesize = PN_ICACHE_LSIZE; 848 } else { 849 chprp->chpr_icache_size = CH_ICACHE_SIZE; 850 chprp->chpr_icache_linesize = CH_ICACHE_LSIZE; 851 } 852 853 cpu_init_ecache_scrub_dr(cp); 854 855 /* 856 * Panther's L2$ and E$ are shared between cores, so the scrubber is 857 * only needed on one of the cores. At this point, we assume all cores 858 * are online, and we only enable the scrubber on core 0. 859 */ 860 if (IS_PANTHER(cpunodes[cp->cpu_id].implementation)) { 861 chprp->chpr_scrub_misc.chsm_core_state = 862 SCRUBBER_BOTH_CORES_ONLINE; 863 if (cp->cpu_id != (processorid_t)cmp_cpu_to_chip(cp->cpu_id)) { 864 chprp->chpr_scrub_misc.chsm_enable[ 865 CACHE_SCRUBBER_INFO_E] = 0; 866 } 867 } 868 869 chprp->chpr_ec_set_size = cpunodes[cp->cpu_id].ecache_size / 870 cpu_ecache_nway(); 871 872 adjust_hw_copy_limits(cpunodes[cp->cpu_id].ecache_size); 873 ch_err_tl1_paddrs[cp->cpu_id] = va_to_pa(chprp); 874 ASSERT(ch_err_tl1_paddrs[cp->cpu_id] != -1); 875 } 876 877 /* 878 * Clear the error state registers for this CPU. 879 * For Cheetah+/Jaguar, just clear the AFSR but 880 * for Panther we also have to clear the AFSR_EXT. 881 */ 882 void 883 set_cpu_error_state(ch_cpu_errors_t *cpu_error_regs) 884 { 885 set_asyncflt(cpu_error_regs->afsr & ~C_AFSR_FATAL_ERRS); 886 if (IS_PANTHER(cpunodes[CPU->cpu_id].implementation)) { 887 set_afsr_ext(cpu_error_regs->afsr_ext & ~C_AFSR_EXT_FATAL_ERRS); 888 } 889 } 890 891 void 892 pn_cpu_log_diag_l2_info(ch_async_flt_t *ch_flt) { 893 struct async_flt *aflt = (struct async_flt *)ch_flt; 894 ch_ec_data_t *l2_data = &ch_flt->flt_diag_data.chd_l2_data[0]; 895 uint64_t faddr = aflt->flt_addr; 896 uint8_t log_way_mask = 0; 897 int i; 898 899 /* 900 * Only Panther CPUs have the additional L2$ data that needs 901 * to be logged here 902 */ 903 if (!IS_PANTHER(cpunodes[aflt->flt_inst].implementation)) 904 return; 905 906 /* 907 * We'll use a simple bit mask to keep track of which way(s) 908 * of the stored cache line we want to log. The idea is to 909 * log the entry if it is a valid line and it matches our 910 * fault AFAR. If no match is found, we will simply log all 911 * the ways. 912 */ 913 for (i = 0; i < PN_L2_NWAYS; i++) 914 if (pn_matching_valid_l2_line(faddr, &l2_data[i])) 915 log_way_mask |= (1 << i); 916 917 /* If no matching valid lines were found, we log all ways */ 918 if (log_way_mask == 0) 919 log_way_mask = (1 << PN_L2_NWAYS) - 1; 920 921 /* Log the cache lines */ 922 for (i = 0; i < PN_L2_NWAYS; i++) 923 if (log_way_mask & (1 << i)) 924 l2_data[i].ec_logflag = EC_LOGFLAG_MAGIC; 925 } 926 927 /* 928 * For this routine to return true, the L2 tag in question must be valid 929 * and the tag PA must match the fault address (faddr) assuming the correct 930 * index is being used. 931 */ 932 static int 933 pn_matching_valid_l2_line(uint64_t faddr, ch_ec_data_t *clo_l2_data) { 934 if ((!PN_L2_LINE_INVALID(clo_l2_data->ec_tag)) && 935 ((faddr & P2ALIGN(C_AFAR_PA, PN_L2_SET_SIZE)) == 936 PN_L2TAG_TO_PA(clo_l2_data->ec_tag))) 937 return (1); 938 return (0); 939 } 940 941 /* 942 * This array is used to convert the 3 digit PgSz encoding (as used in 943 * various MMU registers such as MMU_TAG_ACCESS_EXT) into the corresponding 944 * page size. 945 */ 946 static uint64_t tlb_pgsz_to_size[] = { 947 /* 000 = 8KB: */ 948 0x2000, 949 /* 001 = 64KB: */ 950 0x10000, 951 /* 010 = 512KB: */ 952 0x80000, 953 /* 011 = 4MB: */ 954 0x400000, 955 /* 100 = 32MB: */ 956 0x2000000, 957 /* 101 = 256MB: */ 958 0x10000000, 959 /* undefined for encodings 110 and 111: */ 960 0, 0 961 }; 962 963 /* 964 * The itlb_parity_trap and dtlb_parity_trap handlers transfer control here 965 * after collecting logout information related to the TLB parity error and 966 * flushing the offending TTE entries from the ITLB or DTLB. 967 * 968 * DTLB traps which occur at TL>0 are not recoverable because we will most 969 * likely be corrupting some other trap handler's alternate globals. As 970 * such, we simply panic here when that happens. ITLB parity errors are 971 * not expected to happen at TL>0. 972 */ 973 void 974 cpu_tlb_parity_error(struct regs *rp, ulong_t trap_va, ulong_t tlb_info) { 975 ch_async_flt_t ch_flt; 976 struct async_flt *aflt; 977 pn_tlb_logout_t *tlop = NULL; 978 int immu_parity = (tlb_info & PN_TLO_INFO_IMMU) != 0; 979 int tl1_trap = (tlb_info & PN_TLO_INFO_TL1) != 0; 980 char *error_class; 981 982 bzero(&ch_flt, sizeof (ch_async_flt_t)); 983 984 /* 985 * Get the CPU log out info. If we can't find our CPU private 986 * pointer, or if the logout information does not correspond to 987 * this error, then we will have to make due without detailed 988 * logout information. 989 */ 990 if (CPU_PRIVATE(CPU)) { 991 tlop = CPU_PRIVATE_PTR(CPU, chpr_tlb_logout); 992 if ((tlop->tlo_addr != trap_va) || 993 (tlop->tlo_info != tlb_info)) 994 tlop = NULL; 995 } 996 997 if (tlop) { 998 ch_flt.tlb_diag_data = *tlop; 999 1000 /* Zero out + invalidate TLB logout. */ 1001 bzero(tlop, sizeof (pn_tlb_logout_t)); 1002 tlop->tlo_addr = LOGOUT_INVALID; 1003 } else { 1004 /* 1005 * Copy what logout information we have and mark 1006 * it incomplete. 1007 */ 1008 ch_flt.flt_data_incomplete = 1; 1009 ch_flt.tlb_diag_data.tlo_info = tlb_info; 1010 ch_flt.tlb_diag_data.tlo_addr = trap_va; 1011 } 1012 1013 /* 1014 * Log the error. 1015 */ 1016 aflt = (struct async_flt *)&ch_flt; 1017 aflt->flt_id = gethrtime_waitfree(); 1018 aflt->flt_bus_id = getprocessorid(); 1019 aflt->flt_inst = CPU->cpu_id; 1020 aflt->flt_pc = (caddr_t)rp->r_pc; 1021 aflt->flt_addr = trap_va; 1022 aflt->flt_prot = AFLT_PROT_NONE; 1023 aflt->flt_class = CPU_FAULT; 1024 aflt->flt_priv = (rp->r_tstate & TSTATE_PRIV) ? 1 : 0; 1025 aflt->flt_tl = tl1_trap ? 1 : 0; 1026 aflt->flt_panic = tl1_trap ? 1 : 0; 1027 1028 if (immu_parity) { 1029 aflt->flt_status = ECC_ITLB_TRAP; 1030 ch_flt.flt_type = CPU_ITLB_PARITY; 1031 error_class = FM_EREPORT_CPU_USIII_ITLBPE; 1032 aflt->flt_payload = FM_EREPORT_PAYLOAD_ITLB_PE; 1033 } else { 1034 aflt->flt_status = ECC_DTLB_TRAP; 1035 ch_flt.flt_type = CPU_DTLB_PARITY; 1036 error_class = FM_EREPORT_CPU_USIII_DTLBPE; 1037 aflt->flt_payload = FM_EREPORT_PAYLOAD_DTLB_PE; 1038 } 1039 1040 /* 1041 * The TLB entries have already been flushed by the TL1 trap 1042 * handler so at this point the only thing left to do is log 1043 * the error message. 1044 */ 1045 if (aflt->flt_panic) { 1046 cpu_errorq_dispatch(error_class, (void *)&ch_flt, 1047 sizeof (ch_async_flt_t), ue_queue, aflt->flt_panic); 1048 /* 1049 * Panic here if aflt->flt_panic has been set. Enqueued 1050 * errors will be logged as part of the panic flow. 1051 */ 1052 fm_panic("%sError(s)", immu_parity ? "ITLBPE " : "DTLBPE "); 1053 } else { 1054 cpu_errorq_dispatch(error_class, (void *)&ch_flt, 1055 sizeof (ch_async_flt_t), ce_queue, aflt->flt_panic); 1056 } 1057 } 1058 1059 /* 1060 * This routine is called when a TLB parity error event is 'ue_drain'ed 1061 * or 'ce_drain'ed from the errorq. 1062 */ 1063 void 1064 cpu_async_log_tlb_parity_err(void *flt) { 1065 ch_async_flt_t *ch_flt = (ch_async_flt_t *)flt; 1066 struct async_flt *aflt = (struct async_flt *)flt; 1067 #ifdef lint 1068 aflt = aflt; 1069 #endif 1070 1071 /* 1072 * We only capture TLB information if we encountered 1073 * a TLB parity error and Panther is the only CPU which 1074 * can detect a TLB parity error. 1075 */ 1076 ASSERT(IS_PANTHER(cpunodes[aflt->flt_inst].implementation)); 1077 ASSERT((ch_flt->flt_type == CPU_ITLB_PARITY) || 1078 (ch_flt->flt_type == CPU_DTLB_PARITY)); 1079 1080 if (ch_flt->flt_data_incomplete == 0) { 1081 if (ch_flt->flt_type == CPU_ITLB_PARITY) 1082 ch_flt->tlb_diag_data.tlo_logflag = IT_LOGFLAG_MAGIC; 1083 else /* parity error is in DTLB */ 1084 ch_flt->tlb_diag_data.tlo_logflag = DT_LOGFLAG_MAGIC; 1085 } 1086 } 1087 1088 /* 1089 * Add L1 Prefetch cache data to the ereport payload. 1090 */ 1091 void 1092 cpu_payload_add_pcache(struct async_flt *aflt, nvlist_t *nvl) 1093 { 1094 ch_async_flt_t *ch_flt = (ch_async_flt_t *)aflt; 1095 ch_pc_data_t *pcp; 1096 ch_pc_data_t pcdata[CH_PCACHE_NWAY]; 1097 uint_t nelem; 1098 int i, ways_logged = 0; 1099 1100 /* 1101 * We only capture P$ information if we encountered 1102 * a P$ parity error and Panther is the only CPU which 1103 * can detect a P$ parity error. 1104 */ 1105 ASSERT(IS_PANTHER(cpunodes[aflt->flt_inst].implementation)); 1106 for (i = 0; i < CH_PCACHE_NWAY; i++) { 1107 pcp = &ch_flt->parity_data.dpe.cpl_pc[i]; 1108 if (pcp->pc_logflag == PC_LOGFLAG_MAGIC) { 1109 bcopy(pcp, &pcdata[ways_logged], 1110 sizeof (ch_pc_data_t)); 1111 ways_logged++; 1112 } 1113 } 1114 1115 /* 1116 * Add the pcache data to the payload. 1117 */ 1118 fm_payload_set(nvl, FM_EREPORT_PAYLOAD_NAME_L1P_WAYS, 1119 DATA_TYPE_UINT8, (uint8_t)ways_logged, NULL); 1120 if (ways_logged != 0) { 1121 nelem = sizeof (ch_pc_data_t) / sizeof (uint64_t) * ways_logged; 1122 fm_payload_set(nvl, FM_EREPORT_PAYLOAD_NAME_L1P_DATA, 1123 DATA_TYPE_UINT64_ARRAY, nelem, (uint64_t *)pcdata, NULL); 1124 } 1125 } 1126 1127 /* 1128 * Add TLB diagnostic data to the ereport payload. 1129 */ 1130 void 1131 cpu_payload_add_tlb(struct async_flt *aflt, nvlist_t *nvl) 1132 { 1133 ch_async_flt_t *ch_flt = (ch_async_flt_t *)aflt; 1134 uint8_t num_entries, tlb_data_words; 1135 1136 /* 1137 * We only capture TLB information if we encountered 1138 * a TLB parity error and Panther is the only CPU which 1139 * can detect a TLB parity error. 1140 */ 1141 ASSERT(IS_PANTHER(cpunodes[aflt->flt_inst].implementation)); 1142 ASSERT((ch_flt->flt_type == CPU_ITLB_PARITY) || 1143 (ch_flt->flt_type == CPU_DTLB_PARITY)); 1144 1145 if (ch_flt->flt_type == CPU_ITLB_PARITY) { 1146 num_entries = (uint8_t)(PN_ITLB_NWAYS * PN_NUM_512_ITLBS); 1147 tlb_data_words = sizeof (ch_tte_entry_t) / sizeof (uint64_t) * 1148 num_entries; 1149 1150 /* 1151 * Add the TLB diagnostic data to the payload 1152 * if it was collected. 1153 */ 1154 if (ch_flt->tlb_diag_data.tlo_logflag == IT_LOGFLAG_MAGIC) { 1155 fm_payload_set(nvl, 1156 FM_EREPORT_PAYLOAD_NAME_ITLB_ENTRIES, 1157 DATA_TYPE_UINT8, num_entries, NULL); 1158 fm_payload_set(nvl, FM_EREPORT_PAYLOAD_NAME_ITLB_DATA, 1159 DATA_TYPE_UINT64_ARRAY, tlb_data_words, 1160 (uint64_t *)ch_flt->tlb_diag_data.tlo_itlb_tte, 1161 NULL); 1162 } 1163 } else { 1164 num_entries = (uint8_t)(PN_DTLB_NWAYS * PN_NUM_512_DTLBS); 1165 tlb_data_words = sizeof (ch_tte_entry_t) / sizeof (uint64_t) * 1166 num_entries; 1167 1168 fm_payload_set(nvl, FM_EREPORT_PAYLOAD_NAME_VA, 1169 DATA_TYPE_UINT64, ch_flt->tlb_diag_data.tlo_addr, NULL); 1170 1171 /* 1172 * Add the TLB diagnostic data to the payload 1173 * if it was collected. 1174 */ 1175 if (ch_flt->tlb_diag_data.tlo_logflag == DT_LOGFLAG_MAGIC) { 1176 fm_payload_set(nvl, 1177 FM_EREPORT_PAYLOAD_NAME_DTLB_ENTRIES, 1178 DATA_TYPE_UINT8, num_entries, NULL); 1179 fm_payload_set(nvl, FM_EREPORT_PAYLOAD_NAME_DTLB_DATA, 1180 DATA_TYPE_UINT64_ARRAY, tlb_data_words, 1181 (uint64_t *)ch_flt->tlb_diag_data.tlo_dtlb_tte, 1182 NULL); 1183 } 1184 } 1185 } 1186 1187 /* 1188 * Panther Cache Scrubbing: 1189 * 1190 * In Jaguar, the E$ was split between cores, so the scrubber must run on both 1191 * cores. For Panther, however, the L2$ and L3$ are shared across cores. 1192 * Therefore, the E$ scrubber only needs to run on one of the two cores. 1193 * 1194 * There are four possible states for the E$ scrubber: 1195 * 1196 * 0. If both cores are offline, add core 0 to cpu_offline_set so that 1197 * the offline scrubber will run on it. 1198 * 1. If core 0 is online and core 1 off, we run the scrubber on core 0. 1199 * 2. If core 1 is online and core 0 off, we move the scrubber to run 1200 * on core 1. 1201 * 3. If both cores are online, only run the scrubber on core 0. 1202 * 1203 * These states are enumerated by the SCRUBBER_[BOTH|CORE|NEITHER]_* defines 1204 * above. One of those values is stored in 1205 * chpr_scrub_misc->chsm_core_state on each core. 1206 * 1207 * Also note that, for Panther, ecache_flush_line() will flush out the L2$ 1208 * before the E$, so the L2$ will be scrubbed by the E$ scrubber. No 1209 * additional code is necessary to scrub the L2$. 1210 * 1211 * For all cpu types, whenever a cpu or core is offlined, add it to 1212 * cpu_offline_set so the necessary scrubbers can still run. This is still 1213 * necessary on Panther so the D$ scrubber can still run. 1214 */ 1215 /*ARGSUSED*/ 1216 int 1217 cpu_scrub_cpu_setup(cpu_setup_t what, int cpuid, void *arg) 1218 { 1219 processorid_t core_0_id; 1220 cpu_t *core_cpus[2]; 1221 ch_scrub_misc_t *core_scrub[2]; 1222 int old_state, i; 1223 int new_state = SCRUBBER_NEITHER_CORE_ONLINE; 1224 1225 switch (what) { 1226 case CPU_ON: 1227 case CPU_INIT: 1228 CPUSET_DEL(cpu_offline_set, cpuid); 1229 break; 1230 case CPU_OFF: 1231 CPUSET_ADD(cpu_offline_set, cpuid); 1232 break; 1233 default: 1234 return (0); 1235 } 1236 1237 if (!IS_PANTHER(cpunodes[cpuid].implementation)) { 1238 return (0); 1239 } 1240 1241 /* 1242 * Update the chsm_enable[CACHE_SCRUBBER_INFO_E] value 1243 * if necessary 1244 */ 1245 core_0_id = cmp_cpu_to_chip(cpuid); 1246 core_cpus[0] = cpu_get(core_0_id); 1247 core_cpus[1] = cpu_get_sibling_core(core_cpus[0]); 1248 1249 for (i = 0; i < 2; i++) { 1250 if (core_cpus[i] == NULL) { 1251 /* 1252 * This may happen during DR - one core is offlined 1253 * and completely unconfigured before the second 1254 * core is offlined. Give up and return quietly, 1255 * since the second core should quickly be removed 1256 * anyways. 1257 */ 1258 return (0); 1259 } 1260 core_scrub[i] = CPU_PRIVATE_PTR(core_cpus[i], chpr_scrub_misc); 1261 } 1262 1263 if (cpuid == (processorid_t)cmp_cpu_to_chip(cpuid)) { 1264 /* cpuid is core 0 */ 1265 if (cpu_is_active(core_cpus[1])) { 1266 new_state |= SCRUBBER_CORE_1_ONLINE; 1267 } 1268 if (what != CPU_OFF) { 1269 new_state |= SCRUBBER_CORE_0_ONLINE; 1270 } 1271 } else { 1272 /* cpuid is core 1 */ 1273 if (cpu_is_active(core_cpus[0])) { 1274 new_state |= SCRUBBER_CORE_0_ONLINE; 1275 } 1276 if (what != CPU_OFF) { 1277 new_state |= SCRUBBER_CORE_1_ONLINE; 1278 } 1279 } 1280 1281 old_state = core_scrub[0]->chsm_core_state; 1282 1283 if (old_state == new_state) { 1284 return (0); 1285 } 1286 1287 if (old_state == SCRUBBER_CORE_1_ONLINE) { 1288 /* 1289 * We need to move the scrubber state from core 1 1290 * back to core 0. This data is not protected by 1291 * locks, but the worst that can happen is some 1292 * lines are scrubbed multiple times. chsm_oustanding is 1293 * set to 0 to make sure an interrupt is scheduled the 1294 * first time through do_scrub(). 1295 */ 1296 core_scrub[0]->chsm_flush_index[CACHE_SCRUBBER_INFO_E] = 1297 core_scrub[1]->chsm_flush_index[CACHE_SCRUBBER_INFO_E]; 1298 core_scrub[0]->chsm_outstanding[CACHE_SCRUBBER_INFO_E] = 0; 1299 } 1300 1301 switch (new_state) { 1302 case SCRUBBER_NEITHER_CORE_ONLINE: 1303 case SCRUBBER_BOTH_CORES_ONLINE: 1304 case SCRUBBER_CORE_0_ONLINE: 1305 core_scrub[1]->chsm_enable[CACHE_SCRUBBER_INFO_E] = 0; 1306 core_scrub[0]->chsm_enable[CACHE_SCRUBBER_INFO_E] = 1; 1307 break; 1308 1309 case SCRUBBER_CORE_1_ONLINE: 1310 default: 1311 /* 1312 * We need to move the scrubber state from core 0 1313 * to core 1. 1314 */ 1315 core_scrub[1]->chsm_flush_index[CACHE_SCRUBBER_INFO_E] = 1316 core_scrub[0]->chsm_flush_index[CACHE_SCRUBBER_INFO_E]; 1317 core_scrub[1]->chsm_outstanding[CACHE_SCRUBBER_INFO_E] = 0; 1318 1319 core_scrub[0]->chsm_enable[CACHE_SCRUBBER_INFO_E] = 0; 1320 core_scrub[1]->chsm_enable[CACHE_SCRUBBER_INFO_E] = 1; 1321 break; 1322 } 1323 1324 core_scrub[0]->chsm_core_state = new_state; 1325 core_scrub[1]->chsm_core_state = new_state; 1326 return (0); 1327 } 1328 1329 /* 1330 * Returns a pointer to the cpu structure of the argument's sibling core. 1331 * If no sibling core can be found, return NULL. 1332 */ 1333 static cpu_t * 1334 cpu_get_sibling_core(cpu_t *cpup) 1335 { 1336 cpu_t *nextp; 1337 pg_t *pg; 1338 pg_cpu_itr_t i; 1339 1340 if ((cpup == NULL) || (!cmp_cpu_is_cmp(cpup->cpu_id))) 1341 return (NULL); 1342 pg = (pg_t *)pghw_find_pg(cpup, PGHW_CHIP); 1343 if (pg == NULL) 1344 return (NULL); 1345 1346 /* 1347 * Iterate over the CPUs in the chip PG looking 1348 * for a CPU that isn't cpup 1349 */ 1350 PG_CPU_ITR_INIT(pg, i); 1351 while ((nextp = pg_cpu_next(&i)) != NULL) { 1352 if (nextp != cpup) 1353 break; 1354 } 1355 1356 if (nextp == NULL) 1357 return (NULL); 1358 1359 return (nextp); 1360 } 1361