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 (c) 1996 by Sun Microsystems, Inc. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/sysmacros.h> 30 #include <sys/open.h> 31 #include <sys/param.h> 32 #include <sys/vm_machparam.h> 33 #include <sys/machparam.h> 34 #include <sys/systm.h> 35 #include <sys/signal.h> 36 #include <sys/cred.h> 37 #include <sys/user.h> 38 #include <sys/proc.h> 39 #include <sys/vnode.h> 40 #include <sys/uio.h> 41 #include <sys/buf.h> 42 #include <sys/file.h> 43 #include <sys/kmem.h> 44 #include <sys/stat.h> 45 #include <sys/stream.h> 46 #include <sys/stropts.h> 47 #include <sys/strsubr.h> 48 #include <sys/poll.h> 49 #include <sys/debug.h> 50 #include <sys/conf.h> 51 #include <sys/ddi.h> 52 #include <sys/sunddi.h> 53 #include <sys/errno.h> 54 #include <sys/modctl.h> 55 #include <sys/x_call.h> 56 #include <sys/cpuvar.h> 57 #include <sys/machcpuvar.h> 58 #include <sys/machsystm.h> 59 60 #include <sys/pda.h> 61 #include <sys/starfire.h> 62 #include <sys/idn.h> 63 #include <sys/idn_xf.h> 64 65 kmutex_t idn_xf_mutex; /* to serialize hardware access */ 66 /* 67 * This data structure is referenced during the cross-call 68 * update of the CICs. The semaphore is used for synchronization 69 * when waiting for completion of the respective operation. 70 * We want IDNCIC_TIMEOUT ticks for all the cpus to check-in 71 * before we bail out and fail the operation. 72 */ 73 #define IDNCIC_TIMEOUT (30*hz) 74 #define IDNCIC_TIMECHK (hz/3) 75 #define IDNCIC_UNKNOWN 0 76 #define IDNCIC_OK 1 /* values for xf_errcic */ 77 #define IDNCIC_ERR 2 78 #define IDNCIC_BUSY 3 79 80 #ifdef DEBUG 81 #define NCICREGS 3 /* smmask, smbar, smlar */ 82 #define CICREG_SMMASK 0 83 #define CICREG_SMBAR 1 84 #define CICREG_SMLAR 2 85 86 #define RESET_CIC_HISTORY() \ 87 (xf_cicboards = xf_cicbuses = 0, \ 88 bzero(xf_cicregs, sizeof (xf_cicregs))) 89 90 #define UPDATE_CIC_HISTORY(reg, brd, bus, val) \ 91 (BOARDSET_ADD(xf_cicboards, (brd)), \ 92 BOARDSET_ADD(xf_cicbuses, (bus)), \ 93 xf_cicregs[brd][bus][reg] = (val)) 94 95 #define DUMP_CIC_HISTORY() \ 96 { \ 97 if (idn_debug & IDNDBG_XF) { \ 98 int _bd, _bs; \ 99 procname_t _proc = "dump_cic_history"; \ 100 for (_bd = 0; _bd < MAX_BOARDS; _bd++) { \ 101 if (!BOARD_IN_SET(xf_cicboards, _bd)) \ 102 continue; \ 103 for (_bs = 0; _bs < MAX_ABUSES; _bs++) { \ 104 if (!BOARD_IN_SET(xf_cicbuses, _bs)) \ 105 continue; \ 106 printf("%s: (bd.bs = %d.%d) m/b/l = " \ 107 "%x/%x/%x\n", _proc, _bd, _bs, \ 108 xf_cicregs[_bd][_bs][CICREG_SMMASK], \ 109 xf_cicregs[_bd][_bs][CICREG_SMBAR], \ 110 xf_cicregs[_bd][_bs][CICREG_SMLAR]); \ 111 } \ 112 } \ 113 DEBUG_DELAY(); \ 114 } \ 115 } 116 117 /* 118 * Globally updated during CIC reg updates. Everybody has 119 * a unique location, so no concern about updates stepping 120 * on each other. 121 */ 122 static ushort_t xf_cicboards, xf_cicbuses; 123 static uint_t xf_cicregs[MAX_BOARDS][MAX_ABUSES][NCICREGS]; 124 #else /* DEBUG */ 125 #define RESET_CIC_HISTORY() 126 #define UPDATE_CIC_HISTORY(reg, brd, bus, val) 127 #define DUMP_CIC_HISTORY() 128 #endif /* DEBUG */ 129 130 struct idnxf_cic_info { /* protected by idn_xf_mutex */ 131 /* 0 */ short xf_abus_mask; 132 /* 2 */ boardset_t xf_boardset; 133 /* 4 */ uint_t xf_smbase; 134 /* 8 */ uint_t xf_smlimit; 135 /* c */ int xf_doadd; 136 137 /* 10 */ int xf_count; /* atomically updated */ 138 /* 14 */ time_t xf_start_time; 139 /* 18 */ kcondvar_t xf_cv; 140 /* 1a */ short xf_errtimer; 141 /* 1c */ int xf_errcnt; /* atomically updated */ 142 143 /* 20 */ uchar_t xf_errcic[MAX_BOARDS][MAX_ABUSES]; 144 145 /* 60 */ kmutex_t xf_mutex; 146 }; /* sizeof = 0x68 = 104 (26X) */ 147 148 static struct idnxf_cic_info idnxf_cic_info; 149 #ifdef DEBUG 150 static uint_t o_idn_debug; 151 #endif /* DEBUG */ 152 153 int idn_check_cpu_per_board = 1; 154 155 static int pc_prep_cic_buffer(int cpuid, uint_t cicdata); 156 static int cic_write_sm_mask(int board, int bus, boardset_t sm_mask); 157 static int cic_write_sm_bar(int board, int bus, uint_t sm_bar); 158 static int cic_write_sm_lar(int board, int bus, uint_t sm_lar); 159 static int cic_get_smmask_bit(void); 160 static int pc_write_madr(pda_handle_t ph, 161 int lboard, int rboard, uint_t madr); 162 static boardset_t get_boardset(pda_handle_t ph, int *nboards); 163 static int verify_smregs(int brd, int bus, boardset_t smmask, 164 uint_t smbase, uint_t smlimit); 165 static void idnxf_shmem_wakeup(void *arg); 166 static void idnxf_shmem_update_one(uint64_t arg1, uint64_t arg2); 167 static int idnxf_shmem_update_all(pda_handle_t ph, 168 boardset_t boardset, uint_t smbase, 169 uint_t smlimit, int doadd); 170 171 #define PHYSIO_ST(paddr, val) (stphysio((paddr), (val))) 172 #define PHYSIO_LD(paddr) (ldphysio(paddr)) 173 #define PHYSIO_STH(paddr, val) (sthphysio((paddr), (val))) 174 #define PHYSIO_LDH(paddr) (ldhphysio(paddr)) 175 176 #ifdef DEBUG 177 #define DEBUG_DELAY() (drv_usecwait(5000)) /* 5 ms */ 178 #else /* DEBUG */ 179 #define DEBUG_DELAY() 180 #endif /* DEBUG */ 181 182 183 /* 184 * --------------------------------------------------------------------- 185 */ 186 boardset_t 187 cic_read_domain_mask(int board, int bus) 188 { 189 u_longlong_t csr_addr; 190 boardset_t domain_mask; 191 procname_t proc = "cic_read_domain_mask"; 192 193 ASSERT(CPUID_TO_BOARDID(CPU->cpu_id) == board); 194 195 csr_addr = MAKE_CIC_CSR_PA(board, 196 CSR_TYPE_CIC, 197 CIC_DOMAIN_MASK_ADDR, 198 bus); 199 PR_XF("%s: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 200 proc, board, bus, csr_addr); 201 202 domain_mask = (boardset_t)PHYSIO_LDH(csr_addr); 203 204 return (domain_mask); 205 } 206 207 boardset_t 208 cic_read_sm_mask(int board, int bus) 209 { 210 u_longlong_t csr_addr; 211 boardset_t sm_mask; 212 procname_t proc = "cic_read_sm_mask"; 213 214 ASSERT(CPUID_TO_BOARDID(CPU->cpu_id) == board); 215 216 csr_addr = MAKE_CIC_CSR_PA(board, 217 CSR_TYPE_CIC, 218 CIC_SM_MASK_ADDR, 219 bus); 220 PR_XF("%s: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 221 proc, board, bus, csr_addr); 222 223 sm_mask = (boardset_t)PHYSIO_LDH(csr_addr); 224 225 return (sm_mask); 226 } 227 228 static int 229 cic_write_sm_mask(int board, int bus, boardset_t sm_mask) 230 { 231 u_longlong_t csr_addr; 232 int cnt; 233 procname_t proc = "cic_write_sm_mask"; 234 235 ASSERT(CPUID_TO_BOARDID(CPU->cpu_id) == board); 236 237 sm_mask &= 0xffff; 238 /* 239 * Before we can write to the CIC, we need to set 240 * up the CIC write data buffer in the PC. 241 */ 242 if (pc_prep_cic_buffer(CPU->cpu_id, (uint_t)sm_mask) < 0) 243 return (-1); 244 245 /* 246 * Now we can write to the CIC. 247 */ 248 csr_addr = MAKE_CIC_CSR_PA(board, 249 CSR_TYPE_CIC, 250 CIC_SM_MASK_ADDR, 251 bus); 252 PR_XF("%s: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 253 proc, board, bus, csr_addr); 254 PR_XF("%s: writing sm_mask = 0x%x\n", 255 proc, (ushort_t)sm_mask); 256 257 UPDATE_CIC_HISTORY(CICREG_SMMASK, board, bus, sm_mask); 258 259 PHYSIO_STH(csr_addr, (ushort_t)sm_mask); 260 /* 261 * Read back for verification. 262 */ 263 for (cnt = 0; (PHYSIO_LDH(csr_addr) != sm_mask) && (cnt < 10); cnt++) 264 ; 265 266 return ((cnt == 10) ? -1 : 0); 267 } 268 269 uint_t 270 cic_read_sm_bar(int board, int bus) 271 { 272 u_longlong_t csr_addr; 273 uint_t sm_bar; 274 procname_t proc = "cic_read_sm_bar"; 275 276 ASSERT(CPUID_TO_BOARDID(CPU->cpu_id) == board); 277 278 csr_addr = MAKE_CIC_CSR_PA(board, 279 CSR_TYPE_CIC, 280 CIC_SM_BAR_MSB_ADDR, 281 bus); 282 PR_XF("%s:MSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 283 proc, board, bus, csr_addr); 284 285 sm_bar = (uint_t)PHYSIO_LDH(csr_addr); 286 sm_bar <<= 16; 287 288 csr_addr = MAKE_CIC_CSR_PA(board, 289 CSR_TYPE_CIC, 290 CIC_SM_BAR_LSB_ADDR, 291 bus); 292 PR_XF("%s:LSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 293 proc, board, bus, csr_addr); 294 295 sm_bar |= (uint_t)PHYSIO_LDH(csr_addr); 296 297 return (sm_bar); 298 } 299 300 static int 301 cic_write_sm_bar(int board, int bus, uint_t sm_bar) 302 { 303 int cnt; 304 u_longlong_t csr_addr; 305 uint_t sm_bar_lsb, sm_bar_msb; 306 procname_t proc = "cic_write_sm_bar"; 307 308 ASSERT(CPUID_TO_BOARDID(CPU->cpu_id) == board); 309 310 sm_bar_lsb = sm_bar & 0xffff; 311 sm_bar_msb = (sm_bar >> 16) & 0xffff; 312 313 /* 314 * Before we can write to the CIC, we need to set 315 * up the CIC write data buffer in the PC. 316 */ 317 if (pc_prep_cic_buffer(CPU->cpu_id, sm_bar_msb) < 0) 318 return (-1); 319 320 csr_addr = MAKE_CIC_CSR_PA(board, 321 CSR_TYPE_CIC, 322 CIC_SM_BAR_MSB_ADDR, 323 bus); 324 PR_XF("%s:MSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 325 proc, board, bus, csr_addr); 326 PR_XF("%s:MSB: sm_bar[31:16] = 0x%x\n", 327 proc, (ushort_t)sm_bar_msb); 328 329 UPDATE_CIC_HISTORY(CICREG_SMBAR, board, bus, sm_bar); 330 331 PHYSIO_STH(csr_addr, (ushort_t)sm_bar_msb); 332 for (cnt = 0; 333 ((uint_t)PHYSIO_LDH(csr_addr) != sm_bar_msb) && (cnt < 10); 334 cnt++) 335 ; 336 if (cnt == 10) { 337 cmn_err(CE_WARN, 338 "IDN: 500: failed to write sm_bar (msb) (0x%x)", 339 (uint_t)sm_bar_msb); 340 return (-1); 341 } 342 343 /* 344 * Now to LSB portion. 345 */ 346 if (pc_prep_cic_buffer(CPU->cpu_id, sm_bar_lsb) < 0) 347 return (-1); 348 349 csr_addr = MAKE_CIC_CSR_PA(board, 350 CSR_TYPE_CIC, 351 CIC_SM_BAR_LSB_ADDR, 352 bus); 353 PR_XF("%s:LSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 354 proc, board, bus, csr_addr); 355 PR_XF("%s:LSB: sm_bar[15:0] = 0x%x\n", 356 proc, (ushort_t)sm_bar_lsb); 357 358 PHYSIO_STH(csr_addr, (ushort_t)sm_bar_lsb); 359 for (cnt = 0; 360 ((uint_t)PHYSIO_LDH(csr_addr) != sm_bar_lsb) && (cnt < 10); 361 cnt++) 362 ; 363 if (cnt == 10) { 364 cmn_err(CE_WARN, 365 "IDN: 500: failed to write sm_bar (lsb) (0x%x)", 366 (uint_t)sm_bar_lsb); 367 return (-1); 368 } 369 370 return (0); 371 } 372 373 uint_t 374 cic_read_sm_lar(int board, int bus) 375 { 376 u_longlong_t csr_addr; 377 uint_t sm_lar; 378 procname_t proc = "cic_read_sm_lar"; 379 380 ASSERT(CPUID_TO_BOARDID(CPU->cpu_id) == board); 381 382 csr_addr = MAKE_CIC_CSR_PA(board, 383 CSR_TYPE_CIC, 384 CIC_SM_LAR_MSB_ADDR, 385 bus); 386 PR_XF("%s:MSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 387 proc, board, bus, csr_addr); 388 389 sm_lar = (uint_t)PHYSIO_LDH(csr_addr); 390 sm_lar <<= 16; 391 392 csr_addr = MAKE_CIC_CSR_PA(board, 393 CSR_TYPE_CIC, 394 CIC_SM_LAR_LSB_ADDR, 395 bus); 396 PR_XF("%s:LSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 397 proc, board, bus, csr_addr); 398 399 sm_lar |= (uint_t)PHYSIO_LDH(csr_addr); 400 401 return (sm_lar); 402 } 403 404 static int 405 cic_write_sm_lar(int board, int bus, uint_t sm_lar) 406 { 407 int cnt; 408 u_longlong_t csr_addr; 409 uint_t sm_lar_lsb, sm_lar_msb; 410 procname_t proc = "cic_write_sm_lar"; 411 412 ASSERT(CPUID_TO_BOARDID(CPU->cpu_id) == board); 413 414 sm_lar_lsb = sm_lar & 0xffff; 415 sm_lar_msb = (sm_lar >> 16) & 0xffff; 416 417 /* 418 * Before we can write to the CIC, we need to set 419 * up the CIC write data buffer in the PC. 420 */ 421 if (pc_prep_cic_buffer(CPU->cpu_id, sm_lar_msb) < 0) 422 return (-1); 423 424 csr_addr = MAKE_CIC_CSR_PA(board, 425 CSR_TYPE_CIC, 426 CIC_SM_LAR_MSB_ADDR, 427 bus); 428 PR_XF("%s:MSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 429 proc, board, bus, csr_addr); 430 PR_XF("%s:MSB: sm_lar[31:16] = 0x%x\n", 431 proc, (ushort_t)sm_lar_msb); 432 433 UPDATE_CIC_HISTORY(CICREG_SMLAR, board, bus, sm_lar); 434 435 PHYSIO_STH(csr_addr, (ushort_t)sm_lar_msb); 436 for (cnt = 0; 437 ((uint_t)PHYSIO_LDH(csr_addr) != sm_lar_msb) && (cnt < 10); 438 cnt++) 439 ; 440 if (cnt == 10) { 441 cmn_err(CE_WARN, 442 "IDN: 501: failed to write sm_lar (msb) (0x%x)", 443 (uint_t)sm_lar_msb); 444 return (-1); 445 } 446 447 /* 448 * Now to LSB portion. 449 */ 450 if (pc_prep_cic_buffer(CPU->cpu_id, sm_lar_lsb) < 0) 451 return (-1); 452 453 csr_addr = MAKE_CIC_CSR_PA(board, 454 CSR_TYPE_CIC, 455 CIC_SM_LAR_LSB_ADDR, 456 bus); 457 PR_XF("%s:LSB: (bd=%d, bs=%d) csr_addr = 0x%llx\n", 458 proc, board, bus, csr_addr); 459 PR_XF("%s:LSB: sm_lar[15:0] = 0x%x\n", 460 proc, (ushort_t)sm_lar_lsb); 461 462 PHYSIO_STH(csr_addr, (ushort_t)sm_lar_lsb); 463 for (cnt = 0; 464 ((uint_t)PHYSIO_LDH(csr_addr) != sm_lar_lsb) && (cnt < 10); 465 cnt++) 466 ; 467 if (cnt == 10) { 468 cmn_err(CE_WARN, 469 "IDN: 501: failed to write sm_lar (lsb) (0x%x)", 470 (uint_t)sm_lar_lsb); 471 return (-1); 472 } 473 474 return (0); 475 } 476 477 static int 478 cic_get_smmask_bit(void) 479 { 480 u_longlong_t csr_addr; 481 int board; 482 uint_t config1; 483 procname_t proc = "cic_get_smmask_bit"; 484 485 affinity_set(CPU_CURRENT); 486 487 board = CPUID_TO_BOARDID(CPU->cpu_id); 488 /* 489 * Now that I'm stuck on this cpu I can go look at this 490 * board's CIC registers. 491 */ 492 csr_addr = MAKE_CIC_CSR_PA(board, 493 CSR_TYPE_CIC, 494 CIC_CONFIG1_ADDR, 495 0); 496 PR_XF("%s: (bd=%d) csr_addr = 0x%llx (via cpu %d)\n", 497 proc, board, csr_addr, (int)CPU->cpu_id); 498 499 config1 = (uint_t)PHYSIO_LDH(csr_addr); 500 501 config1 = CIC_CONFIG1_SMMASK_BIT(config1); 502 503 affinity_clear(); 504 505 return (config1); 506 } 507 508 static int 509 pc_prep_cic_buffer(int cpuid, uint_t cicdata) 510 { 511 int rv; 512 int brd, port; 513 u_longlong_t csr_addr; 514 register int cnt; 515 procname_t proc = "pc_prep_cic_buffer"; 516 517 518 ASSERT(CPU->cpu_id == cpuid); 519 520 port = cpuid % plat_max_cpu_units_per_board(); 521 brd = CPUID_TO_BOARDID(cpuid); 522 523 csr_addr = STARFIRE_PC_CICBUF_ADDR(brd, port); 524 525 /* 526 * csr_addr now points to CIC write buffer which resides 527 * in PC register space. 528 */ 529 PR_XF("%s: (cpu=%d) csr_addr = 0x%llx\n", proc, cpuid, csr_addr); 530 531 PHYSIO_ST(csr_addr, cicdata); 532 533 /* 534 * Now we need to read back the data to guarantee 535 * it got there. Part of the PC protocol. 536 */ 537 for (cnt = 0; (PHYSIO_LD(csr_addr) != cicdata) && (cnt < 10); 538 cnt++) 539 ; 540 541 rv = 0; 542 if (cnt == 10) { 543 cmn_err(CE_WARN, 544 "IDN: 502: unable to store data (0x%x) to " 545 "CIC buffer (0x%llx)", 546 cicdata, csr_addr); 547 rv = -1; 548 } else if (cnt >= 1) { 549 PR_XF("%s: MULTIPLE READS (cpu=%d) cnt = %d\n", 550 proc, cpuid, cnt); 551 } 552 553 return (rv); 554 } 555 556 /* 557 * -------------------------------------------------- 558 * Write the given MC address decoding register contents (madr) of 559 * the respective remote board (rboard) into all the PCs located on 560 * the local board (lboard). 561 * -------------------------------------------------- 562 */ 563 static int 564 pc_write_madr(pda_handle_t ph, int lboard, int rboard, uint_t madr) 565 { 566 u_longlong_t pc_madr_addr; 567 register int p, ioc; 568 register ushort_t procset, iocset; 569 int rv = 0; 570 uint_t rd_madr; 571 board_desc_t *lbp; 572 procname_t proc = "pc_write_madr"; 573 574 lbp = pda_get_board_info(ph, lboard); 575 576 ASSERT(lbp); 577 ASSERT((lbp->bda_board & BDAN_MASK) == BDAN_GOOD); 578 579 procset = lbp->bda_proc; 580 iocset = lbp->bda_ioc; 581 582 /* 583 * Update the PCs for the cpus. 584 */ 585 for (p = 0; p < MAX_PROCMODS; procset >>= 4, p++) { 586 int i; 587 588 if (!((procset & BDAN_MASK) == BDAN_GOOD)) 589 continue; 590 591 pc_madr_addr = (u_longlong_t)STARFIRE_PC_MADR_ADDR(lboard, 592 rboard, p); 593 594 /* 595 * On this first iteration of updating the PC 596 * we need to turn off the MADR VALID bit so that 597 * there's no accidental usage of the entry before 598 * all four bytes have been updated in the PC. 599 */ 600 if (madr != 0) { 601 /* 602 * Need to clear valid bit on first 603 * go around. 604 */ 605 madr &= ~STARFIRE_PC_MADR_VALIDBIT; 606 } 607 PR_XF("%s: write madr(0x%x) to pc_addr(0x%llx) " 608 "[lb=%d, rb=%d, cpu=%d]\n", 609 proc, madr, pc_madr_addr, lboard, rboard, p); 610 DEBUG_DELAY(); 611 612 for (i = 0; i < 20; i++) { 613 PHYSIO_ST(pc_madr_addr, madr); 614 /* 615 * Read back for sanity check. 616 */ 617 rd_madr = PHYSIO_LD(pc_madr_addr); 618 if (madr == rd_madr) 619 break; 620 } 621 if (i > 0) { 622 PR_XF("%s: WARNING: (1) lb=%d, rb=%d, " 623 "madr=0x%x (i=%d)\n", 624 proc, lboard, rboard, madr, i); 625 } 626 if (rd_madr != madr) { 627 cmn_err(CE_WARN, 628 "IDN: 503: (invalidate) failed to update " 629 "PC madr (expected 0x%x, actual 0x%x)", 630 madr, rd_madr); 631 rv++; 632 continue; 633 } 634 if (madr == 0) { 635 continue; 636 } else { 637 /* 638 * Turn the valid bit back on. 639 */ 640 madr |= STARFIRE_PC_MADR_VALIDBIT; 641 } 642 PR_XF("%s: write madr(0x%x) to pc_addr(0x%llx) " 643 "[lb=%d, rb=%d, cpu=%d]\n", 644 proc, madr, pc_madr_addr, lboard, rboard, p); 645 DEBUG_DELAY(); 646 647 for (i = 0; i < 20; i++) { 648 PHYSIO_ST(pc_madr_addr, madr); 649 /* 650 * Read back for sanity check. 651 */ 652 rd_madr = PHYSIO_LD(pc_madr_addr); 653 if (madr == rd_madr) 654 break; 655 } 656 if (i > 0) { 657 PR_XF("%s: WARNING: (2) lb=%d, rb=%d, " 658 "madr=0x%x (i=%d)\n", 659 proc, lboard, rboard, madr, i); 660 } 661 if (rd_madr != madr) { 662 cmn_err(CE_WARN, 663 "IDN: 503: (validate) failed to update " 664 "PC madr (expected 0x%x, actual 0x%x)", 665 madr, rd_madr); 666 rv++; 667 } 668 } 669 /* 670 * Update the PCs for the iocs. 671 */ 672 for (ioc = 0; ioc < MAX_IOCS; iocset >>= 4, ioc++) { 673 int i; 674 675 if (!((iocset & BDAN_MASK) == BDAN_GOOD)) 676 continue; 677 678 pc_madr_addr = (u_longlong_t)STARFIRE_PC_MADR_ADDR(lboard, 679 rboard, ioc + 4); 680 681 if (madr != 0) { 682 /* 683 * Need to clear valid bit on first 684 * go around. 685 */ 686 madr &= ~STARFIRE_PC_MADR_VALIDBIT; 687 } 688 PR_XF("%s: write madr(0x%x) to iopc_madr_addr(0x%llx) " 689 "[lb=%d, rb=%d, ioc=%d]\n", 690 proc, madr, pc_madr_addr, lboard, rboard, ioc); 691 DEBUG_DELAY(); 692 693 for (i = 0; i < 20; i++) { 694 PHYSIO_ST(pc_madr_addr, madr); 695 /* 696 * Read back for sanity check. 697 */ 698 rd_madr = PHYSIO_LD(pc_madr_addr); 699 if (madr == rd_madr) 700 break; 701 } 702 if (i > 0) { 703 PR_XF("%s: WARNING: (3) lb=%d, rb=%d, " 704 "madr=0x%x (i=%d)\n", 705 proc, lboard, rboard, madr, i); 706 } 707 if (rd_madr != madr) { 708 cmn_err(CE_WARN, 709 "IDN: 504: (invalidate) failed to update " 710 "IOPC madr (expected 0x%x, actual 0x%x)", 711 madr, rd_madr); 712 rv++; 713 continue; 714 } 715 716 if (madr == 0) { 717 continue; 718 } else { 719 /* 720 * Turn the valid bit back on. 721 */ 722 madr |= STARFIRE_PC_MADR_VALIDBIT; 723 } 724 725 PR_XF("%s: write madr(0x%x) to iopc_madr_addr(0x%llx) " 726 "[lb=%d, rb=%d, ioc=%d]\n", 727 proc, madr, pc_madr_addr, lboard, rboard, ioc); 728 DEBUG_DELAY(); 729 730 for (i = 0; i < 20; i++) { 731 PHYSIO_ST(pc_madr_addr, madr); 732 /* 733 * Read back for sanity check. 734 */ 735 rd_madr = PHYSIO_LD(pc_madr_addr); 736 if (madr == rd_madr) 737 break; 738 } 739 if (i > 0) { 740 PR_XF("%s: WARNING: (4) lb=%d, rb=%d, " 741 "madr=0x%x (i=%d)\n", 742 proc, lboard, rboard, madr, i); 743 } 744 if (rd_madr != madr) { 745 cmn_err(CE_WARN, 746 "IDN: 504: (validate) failed to update " 747 "IOPC madr (expected 0x%x, actual 0x%x)", 748 madr, rd_madr); 749 rv++; 750 } 751 } 752 753 return (rv ? -1 : 0); 754 } 755 756 /* 757 * -------------------------------------------------- 758 * Read the array of MC address decoding registers from one of the 759 * PCs on the local board (lboard) into the given in array (mc_adr). 760 * -------------------------------------------------- 761 */ 762 void 763 pc_read_madr(pda_handle_t ph, int lboard, uint_t mc_adr[], int local_only) 764 { 765 u_longlong_t pc_madr_addr; 766 register int p, ioc; 767 register ushort_t procset, iocset; 768 int brd; 769 board_desc_t *lbp; 770 771 lbp = pda_get_board_info(ph, lboard); 772 773 ASSERT(lbp); 774 ASSERT((lbp->bda_board & BDAN_MASK) == BDAN_GOOD); 775 776 procset = lbp->bda_proc; 777 iocset = lbp->bda_ioc; 778 779 for (p = 0; p < MAX_PROCMODS; procset >>= 4, p++) 780 if ((procset & BDAN_MASK) == BDAN_GOOD) 781 break; 782 783 if (p == MAX_PROCMODS) { 784 /* 785 * Couldn't find a PC off a cpu, let's check the 786 * IOCs. 787 */ 788 for (ioc = 0; ioc < MAX_IOCS; iocset >>= 4, ioc++) 789 if ((iocset & BDAN_MASK) == BDAN_GOOD) 790 break; 791 if (ioc == MAX_IOCS) { 792 cmn_err(CE_WARN, 793 "IDN: 505: board %d missing any valid PCs", 794 lboard); 795 return; 796 } 797 p = ioc + 4; 798 } 799 800 pc_madr_addr = (u_longlong_t)STARFIRE_PC_MADR_ADDR(lboard, 0, p); 801 /* 802 * pc_madr_addr = Starts at entry for board 0. 803 */ 804 for (brd = 0; brd < MAX_BOARDS; brd++) { 805 /* 806 * It's possible our local PC may have old entries to 807 * AWOL domains. Only want to pay attention to PC 808 * entries corresponding to our boards. 809 */ 810 lbp = pda_get_board_info(ph, brd); 811 if (!local_only || 812 ((lbp->bda_board & BDAN_MASK) == BDAN_GOOD)) 813 mc_adr[brd] = PHYSIO_LD(pc_madr_addr); 814 else 815 mc_adr[brd] = 0; 816 817 pc_madr_addr += ((u_longlong_t)1 << 818 STARFIRE_PC_MADR_BOARD_SHIFT); 819 } 820 } 821 822 /* 823 * -------------------------------------------------- 824 * Read the MC address decoding register contents for all 825 * possible boards and store the results in their respective 826 * slot in mc_adr. Keep a count of non-zero MC ADRs and 827 * return that. 828 * -------------------------------------------------- 829 */ 830 void 831 mc_get_adr_all(pda_handle_t ph, uint_t mc_adr[], int *nmcadr) 832 { 833 int brd; 834 uint_t madr[MAX_BOARDS]; 835 836 /* 837 * Note that each PC has a complete copy of all MC contents 838 * and so all we have to do is read one PC rather than 839 * each of the MCs in the system. 840 */ 841 brd = CPUID_TO_BOARDID(CPU->cpu_id); 842 pc_read_madr(ph, brd, madr, 1); 843 844 *nmcadr = 0; 845 for (brd = 0; brd < MAX_BOARDS; brd++) 846 if ((mc_adr[brd] = madr[brd]) != 0) 847 (*nmcadr)++; 848 } 849 850 static boardset_t 851 get_boardset(pda_handle_t ph, int *nboards) 852 { 853 int brd; 854 int nbrds = 0; 855 boardset_t bmask; 856 857 if (nboards != NULL) 858 *nboards = 0; 859 860 bmask = 0; 861 for (brd = 0; brd < MAX_BOARDS; brd++) { 862 if (pda_board_present(ph, brd)) { 863 bmask |= 1 << brd; 864 nbrds++; 865 } 866 } 867 if (nboards != NULL) 868 *nboards = (short)nbrds; 869 870 return (bmask); 871 } 872 873 int 874 update_local_hw_config(idn_domain_t *ldp, struct hwconfig *loc_hw) 875 { 876 procname_t proc = "update_local_hw_config"; 877 878 ASSERT(IDN_DLOCK_IS_EXCL(ldp->domid)); 879 ASSERT(IDN_GLOCK_IS_EXCL()); 880 ASSERT(ldp == &idn_domain[idn.localid]); 881 882 if (ldp->dhw.dh_boardset != loc_hw->dh_boardset) { 883 int c; 884 885 PR_PROTO("%s: NEW HW CONFIG (old_bset = 0x%x, " 886 "new_bset = 0x%x)\n", 887 proc, ldp->dhw.dh_boardset, loc_hw->dh_boardset); 888 889 PR_PROTO("%s: clearing boardset 0x%x\n", proc, 890 ldp->dhw.dh_boardset & ~loc_hw->dh_boardset); 891 PR_PROTO("%s: setting boardset 0x%x\n", proc, 892 loc_hw->dh_boardset & ~ldp->dhw.dh_boardset); 893 894 idn.dc_boardset &= ~ldp->dhw.dh_boardset; 895 idn.dc_boardset |= loc_hw->dh_boardset; 896 for (c = 0; c < NCPU; c++) { 897 if (CPU_IN_SET(ldp->dcpuset, c)) { 898 CPUSET_DEL(idn.dc_cpuset, c); 899 } 900 } 901 CPUSET_OR(idn.dc_cpuset, cpu_ready_set); 902 903 bcopy(loc_hw, &ldp->dhw, sizeof (ldp->dhw)); 904 ldp->dcpuset = cpu_ready_set; 905 ldp->dcpu = cpu0.cpu_id; 906 ldp->dncpus = (int)ncpus; 907 ldp->dvote.v.nmembrds = ldp->dhw.dh_nmcadr - 1; 908 ldp->dvote.v.ncpus = (int)ldp->dncpus - 1; 909 ldp->dvote.v.board = CPUID_TO_BOARDID(CPU->cpu_id); 910 911 return (1); 912 } else { 913 PR_PROTO("%s: NO change detected\n", proc); 914 return (0); 915 } 916 } 917 918 int 919 get_hw_config(struct hwconfig *loc_hw) 920 { 921 pda_handle_t ph; 922 boardset_t domainset; 923 int bd; 924 int nmcadr; 925 int nboards; 926 procname_t proc = "get_hw_config"; 927 928 ASSERT(loc_hw != NULL); 929 930 bzero(loc_hw, sizeof (*loc_hw)); 931 /* 932 * See if sm_mask is writable. 933 * XXX - Should be the same for all CIC's. Do we 934 * we need to verify? 935 */ 936 if (cic_get_smmask_bit() == 0) { 937 /* 938 * If smmask is not writable, we can not allow 939 * IDN operations. 940 */ 941 cmn_err(CE_WARN, 942 "IDN: 506: cic sm_mask is not writeable"); 943 return (-1); 944 } 945 /* 946 * Map in the post2obp structure so we can find 947 * valid boards and hardware asics. 948 */ 949 ph = pda_open(); 950 if (ph == (pda_handle_t)NULL) { 951 cmn_err(CE_WARN, 952 "IDN: 507: failed to map-in post2obp structure"); 953 return (-1); 954 } else if (!pda_is_valid(ph)) { 955 cmn_err(CE_WARN, "IDN: 508: post2obp checksum invalid"); 956 pda_close(ph); 957 return (-1); 958 } 959 /* 960 * Need to read the MC address decoding registers 961 * so that they can be given to other domains. 962 */ 963 loc_hw->dh_boardset = get_boardset(ph, &nboards); 964 loc_hw->dh_nboards = (short)nboards; 965 ASSERT(loc_hw->dh_boardset & (1 << CPUID_TO_BOARDID(CPU->cpu_id))); 966 967 mc_get_adr_all(ph, loc_hw->dh_mcadr, &nmcadr); 968 loc_hw->dh_nmcadr = (short)nmcadr; 969 970 affinity_set(CPU_CURRENT); 971 /* 972 * There will always be a bus 0 (logical). 973 */ 974 bd = CPUID_TO_BOARDID(CPU->cpu_id); 975 domainset = (boardset_t)cic_read_domain_mask(bd, 0); 976 affinity_clear(); 977 978 if (!idn_cpu_per_board(ph, cpu_ready_set, loc_hw)) { 979 pda_close(ph); 980 return (-1); 981 } 982 983 pda_close(ph); 984 985 986 #ifdef DEBUG 987 { 988 int brd; 989 990 for (brd = 0; brd < MAX_BOARDS; brd++) 991 if (loc_hw->dh_mcadr[brd] != 0) { 992 PR_XF("%s: brd %d, mc = 0x%x\n", 993 proc, brd, loc_hw->dh_mcadr[brd]); 994 } 995 } 996 #endif /* DEBUG */ 997 998 if ((loc_hw->dh_boardset != domainset) || (loc_hw->dh_nmcadr < 1)) 999 return (-1); 1000 else 1001 return (0); 1002 } 1003 1004 /* 1005 * Function called via timeout() to wakeup a possibly stuck 1006 * idnxf_shmem_update_all() should not all cpus check-in after a 1007 * x-call to update their respective CICs. 1008 */ 1009 /*ARGSUSED0*/ 1010 static void 1011 idnxf_shmem_wakeup(void *arg) 1012 { 1013 struct idnxf_cic_info *idnxfp = (struct idnxf_cic_info *)arg; 1014 int count; 1015 int expired; 1016 procname_t proc = "idnxf_shmem_wakeup"; 1017 1018 expired = ((lbolt - idnxfp->xf_start_time) >= IDNCIC_TIMEOUT) ? 1 : 0; 1019 1020 if ((count = idnxfp->xf_count) == 0) { 1021 /* 1022 * Everybody has finished. Wakeup the requester. 1023 */ 1024 mutex_enter(&idnxfp->xf_mutex); 1025 cv_signal(&idnxfp->xf_cv); 1026 mutex_exit(&idnxfp->xf_mutex); 1027 1028 } else if ((count > 0) && expired) { 1029 /* 1030 * There are still active cic updaters and time 1031 * has expired. Bail on them. 1032 */ 1033 idnxfp->xf_errtimer = 1; 1034 #ifdef DEBUG 1035 /* 1036 * Special debug case since idn_debug 1037 * may have been temporarily cleared 1038 * during xc_some. 1039 */ 1040 if ((idn_debug | o_idn_debug) & IDNDBG_REGS) 1041 printf("%s: TIMEOUT...bailing on %d lost CIC " 1042 "updates...\n", proc, count); 1043 #endif /* DEBUG */ 1044 1045 ATOMIC_SUB(idnxfp->xf_count, count); 1046 1047 mutex_enter(&idnxfp->xf_mutex); 1048 cv_signal(&idnxfp->xf_cv); 1049 mutex_exit(&idnxfp->xf_mutex); 1050 1051 } else { 1052 (void) timeout(idnxf_shmem_wakeup, (caddr_t)idnxfp, 1053 (clock_t)IDNCIC_TIMECHK); 1054 } 1055 } 1056 1057 /* 1058 * Called indirectly from idnxf_shmem_update_all() via a xcall 1059 * for the recepient cpu to update the CICs on its respective 1060 * board. 1061 * IMPORTANT: NO console output from this routine!! 1062 */ 1063 static void 1064 idnxf_shmem_update_one(uint64_t arg1, uint64_t arg2) 1065 { 1066 struct idnxf_cic_info *idnxfp = (struct idnxf_cic_info *)arg1; 1067 time_t start_time = (time_t)arg2; 1068 int rv, cpuid, brd, bus; 1069 boardset_t smmask; 1070 1071 1072 cpuid = CPU->cpu_id; 1073 brd = CPUID_TO_BOARDID(cpuid); 1074 1075 if (idnxfp->xf_start_time != start_time) { 1076 /* 1077 * Ooops! Not my place to intrude. 1078 */ 1079 idnxf_cic_info.xf_errcic[brd][0] = IDNCIC_BUSY; 1080 ATOMIC_INC(idnxf_cic_info.xf_errcnt); 1081 1082 goto done; 1083 } 1084 1085 /* 1086 * We're executing out of the context of a cross-call 1087 * so we're effectively bound! :) 1088 */ 1089 for (bus = 0; bus < MAX_ABUSES; bus++) { 1090 /* 1091 * XXX - need to worry about shuffle?? 1092 */ 1093 if (!(idnxfp->xf_abus_mask & (1 << bus))) 1094 continue; 1095 smmask = cic_read_sm_mask(brd, bus); 1096 1097 if (idnxfp->xf_doadd) { 1098 smmask |= idnxfp->xf_boardset; 1099 (void) cic_write_sm_mask(brd, bus, smmask); 1100 1101 if (idnxfp->xf_smbase != (uint_t)-1) { 1102 (void) cic_write_sm_bar(brd, bus, 1103 idnxfp->xf_smbase); 1104 (void) cic_write_sm_lar(brd, bus, 1105 idnxfp->xf_smlimit); 1106 } 1107 /* 1108 * Verify data got there! 1109 */ 1110 rv = verify_smregs(brd, bus, smmask, idnxfp->xf_smbase, 1111 idnxfp->xf_smlimit); 1112 } else { 1113 smmask &= ~idnxfp->xf_boardset; 1114 (void) cic_write_sm_mask(brd, bus, smmask); 1115 1116 if (!smmask) { 1117 /* 1118 * Update the LAR first so that we effectively 1119 * disable the register without possibly 1120 * opening the window to transaction we 1121 * don't care about. Updating the LAR first 1122 * will guarantee we effectively turn it 1123 * off immediately. 1124 */ 1125 (void) cic_write_sm_lar(brd, bus, 0); 1126 (void) cic_write_sm_bar(brd, bus, 1); 1127 1128 rv = verify_smregs(brd, bus, smmask, 1, 0); 1129 } else { 1130 rv = verify_smregs(brd, bus, smmask, 1131 (uint_t)-1, (uint_t)-1); 1132 } 1133 } 1134 if (rv) { 1135 idnxf_cic_info.xf_errcic[brd][bus] = IDNCIC_ERR; 1136 ATOMIC_INC(idnxf_cic_info.xf_errcnt); 1137 } else { 1138 idnxf_cic_info.xf_errcic[brd][bus] = IDNCIC_OK; 1139 } 1140 } 1141 1142 done: 1143 ATOMIC_DEC(idnxf_cic_info.xf_count); 1144 } 1145 1146 static int 1147 idnxf_shmem_update_all(pda_handle_t ph, boardset_t boardset, 1148 uint_t smbase, uint_t smlimit, int doadd) 1149 { 1150 cpuset_t target_cpuset; 1151 int target_count; 1152 int rv = 0; 1153 int c, brd, bus; 1154 short abus_mask; 1155 time_t start_time; 1156 procname_t proc = "idnxf_shmem_update_all"; 1157 1158 1159 ASSERT(MUTEX_HELD(&idn_xf_mutex)); 1160 1161 pda_get_busmask(ph, &abus_mask, NULL); 1162 1163 CPUSET_ZERO(target_cpuset); 1164 target_count = 0; 1165 /* 1166 * Build a cpuset of target cpus (one per board) to 1167 * be used to send the CIC update xcall. 1168 */ 1169 for (brd = 0; brd < MAX_BOARDS; brd++) { 1170 /* 1171 * Need to target an available cpu on the target board 1172 * so that we can look at the CICs on that board. 1173 */ 1174 c = board_to_ready_cpu(brd, cpu_ready_set); 1175 1176 if (c == -1) { 1177 /* 1178 * If there's no cpu on this board, no 1179 * need to update the CICs. 1180 */ 1181 continue; 1182 } 1183 CPUSET_ADD(target_cpuset, c); 1184 target_count++; 1185 } 1186 1187 if (CPUSET_ISNULL(target_cpuset)) { 1188 PR_REGS("%s: NO target cpus to update!!\n", proc); 1189 return (0); 1190 } 1191 1192 RESET_CIC_HISTORY(); 1193 1194 /* 1195 * Broadcast out the CIC update request and then 1196 * sit back and wait for dinner to arrive! 1197 * Let's set up the global structure all the xcall 1198 * recepients will read. 1199 */ 1200 start_time = lbolt; 1201 /* 1202 * Set the start time. Make sure it's different 1203 * then the previous run. 1204 */ 1205 if (start_time <= idnxf_cic_info.xf_start_time) 1206 start_time++; 1207 idnxf_cic_info.xf_start_time = start_time; 1208 1209 idnxf_cic_info.xf_abus_mask = abus_mask; 1210 idnxf_cic_info.xf_boardset = boardset; 1211 idnxf_cic_info.xf_smbase = smbase; 1212 idnxf_cic_info.xf_smlimit = smlimit; 1213 idnxf_cic_info.xf_doadd = doadd; 1214 idnxf_cic_info.xf_count = target_count; 1215 idnxf_cic_info.xf_errcnt = 0; 1216 idnxf_cic_info.xf_errtimer = 0; 1217 bzero(&idnxf_cic_info.xf_errcic, sizeof (idnxf_cic_info.xf_errcic)); 1218 1219 /* 1220 * Broadcast out the xcall to do the task. 1221 */ 1222 #ifdef DEBUG 1223 { 1224 uint_t tu32, tl32; 1225 1226 tu32 = UPPER32_CPUMASK(target_cpuset); 1227 tl32 = LOWER32_CPUMASK(target_cpuset); 1228 PR_REGS("%s: (start %ld) broadcasting CIC - " 1229 "%s to cpus 0x%x.%0x\n", 1230 proc, start_time, doadd ? "LINK" : "UNLINK", 1231 tu32, tl32); 1232 } 1233 1234 /* 1235 * Can't dump debug during cross-calls. 1236 */ 1237 o_idn_debug = idn_debug; 1238 idn_debug = 0; 1239 #endif /* DEBUG */ 1240 1241 xc_attention(target_cpuset); 1242 1243 xc_some(target_cpuset, idnxf_shmem_update_one, 1244 (uint64_t)&idnxf_cic_info, (uint64_t)start_time); 1245 1246 xc_dismissed(target_cpuset); 1247 1248 ASSERT(idnxf_cic_info.xf_count == 0); 1249 1250 #ifdef DEBUG 1251 idn_debug = o_idn_debug; 1252 o_idn_debug = 0; 1253 #endif /* DEBUG */ 1254 1255 PR_REGS("%s: waiting for completion of %d CIC - %s...\n", 1256 proc, idnxf_cic_info.xf_count, doadd ? "LINKS" : "UNLINKS"); 1257 PR_REGS("%s: CIC - %s have checked IN.\n", 1258 proc, doadd ? "LINKS" : "UNLINKS"); 1259 1260 /* 1261 * Modifying xf_start_time effectively disables any 1262 * possible outstanding xcall's since they don't touch 1263 * idnxf_cic_info unless their given start_time matches 1264 * that in the idnxf_cic_info structure. 1265 */ 1266 idnxf_cic_info.xf_start_time++; 1267 1268 PR_REGS("%s: xf_errcnt = %d, xf_errtimer = %d\n", 1269 proc, idnxf_cic_info.xf_errcnt, idnxf_cic_info.xf_errtimer); 1270 DUMP_CIC_HISTORY(); 1271 /* 1272 * Should errors be fatal? (panic). 1273 */ 1274 rv = 0; 1275 for (c = 0; c < NCPU; c++) { 1276 if (!CPU_IN_SET(target_cpuset, c)) 1277 continue; 1278 brd = CPUID_TO_BOARDID(c); 1279 1280 for (bus = 0; bus < MAX_ABUSES; bus++) { 1281 1282 if (!(abus_mask & (1 << bus))) 1283 continue; 1284 1285 switch (idnxf_cic_info.xf_errcic[brd][bus]) { 1286 case IDNCIC_UNKNOWN: 1287 /* 1288 * Unknown is only an error if the 1289 * timer expired. 1290 */ 1291 if (!idnxf_cic_info.xf_errtimer) 1292 break; 1293 cmn_err(CE_WARN, 1294 "IDN: 509: CPU %d never responded " 1295 "to CIC update", c); 1296 /*FALLTHROUGH*/ 1297 1298 case IDNCIC_ERR: 1299 cmn_err(CE_WARN, 1300 "IDN: 510: failed write-smregs " 1301 "(bd=%d, bs=%d, sm(bar=0x%x, " 1302 "lar=0x%x))", 1303 brd, bus, smbase, smlimit); 1304 rv++; 1305 break; 1306 1307 case IDNCIC_BUSY: 1308 cmn_err(CE_WARN, "IDN: 511: update-one " 1309 "(cpu=%d, bd=%d) time conflict", 1310 c, brd); 1311 /* 1312 * Should never occur. Not fatal, 1313 * just continue. 1314 */ 1315 break; 1316 1317 default: 1318 PR_REGS("%s: board %d, bus %d " 1319 "(bar=0x%x,lar=0x%x) - update OK\n", 1320 proc, brd, bus, smbase, smlimit); 1321 break; 1322 } 1323 } 1324 } 1325 1326 return (rv ? -1 : 0); 1327 } 1328 1329 /* 1330 * Add the respective boardset/base/limit/mcadr's to the local 1331 * domain's hardware configuration with respect to the SMR. 1332 * 1333 * is_master Indicates remote domain is a master. 1334 */ 1335 int 1336 idnxf_shmem_add(int is_master, boardset_t boardset, 1337 pfn_t pfnbase, pfn_t pfnlimit, 1338 uint_t *mcadr) 1339 { 1340 int rv = 0; 1341 register int brd, rbrd; 1342 register boardset_t localboardset; 1343 uint_t madr; 1344 uint_t smbase, smlimit; 1345 pda_handle_t ph; 1346 procname_t proc = "idnxf_shmem_add"; 1347 1348 1349 localboardset = idn_domain[idn.localid].dhw.dh_boardset; 1350 1351 ASSERT(localboardset && boardset && ((localboardset & boardset) == 0)); 1352 ASSERT(is_master ? (pfnbase && pfnlimit && mcadr) : 1); 1353 1354 if (pfnbase != PFN_INVALID) { 1355 smbase = (uint_t)PFN_TO_SMADDR(pfnbase); 1356 smlimit = (uint_t)PFN_TO_SMADDR(pfnlimit); 1357 } else { 1358 smbase = smlimit = (uint_t)-1; 1359 } 1360 PR_REGS("%s: is_master=%d, boardset=0x%x, smbase=0x%x, smlimit=%x\n", 1361 proc, is_master, boardset, smbase, smlimit); 1362 1363 /* 1364 * Need to serialize hardware access so we don't have multiple 1365 * threads attempting to access hardware regs simulataneously. 1366 * This should not be a significant performance penalty since 1367 * the hardware is only touched when domains are linking or 1368 * unlinking. 1369 */ 1370 mutex_enter(&idn_xf_mutex); 1371 1372 /* 1373 * Map in the post2obp structure so we can find 1374 * bus config information. 1375 */ 1376 ph = pda_open(); 1377 if (ph == (pda_handle_t)NULL) { 1378 cmn_err(CE_WARN, 1379 "IDN: 507: failed to map-in post2obp structure"); 1380 rv = -1; 1381 goto done; 1382 1383 } else if (!pda_is_valid(ph)) { 1384 cmn_err(CE_WARN, "IDN: 508: post2obp checksum invalid"); 1385 rv = -1; 1386 goto done; 1387 } 1388 /* 1389 * Take a checkpoint in bbsram for diagnostic purposes. 1390 */ 1391 CHECKPOINT_OPENED(IDNSB_CHKPT_SMR, boardset, 1); 1392 1393 rv = idnxf_shmem_update_all(ph, boardset, smbase, smlimit, 1); 1394 1395 if (rv || (is_master == 0)) 1396 goto done; 1397 1398 /* 1399 * If this is a slave (i.e. remote domain is_master), 1400 * then we need to deprogram our PCs. 1401 */ 1402 PR_REGS("%s: updating PC regs (lboardset=0x%x, rboardset=0x%x)\n", 1403 proc, localboardset, boardset); 1404 1405 for (brd = 0; brd < MAX_BOARDS; brd++) { 1406 1407 if (!BOARD_IN_SET(localboardset, brd)) 1408 continue; 1409 /* 1410 * If this is a slave (i.e. remote domain is_master), 1411 * then we need to program our PCs. 1412 */ 1413 for (rbrd = 0; rbrd < MAX_BOARDS; rbrd++) { 1414 1415 if ((madr = mcadr[rbrd]) == 0) 1416 continue; 1417 1418 ASSERT(BOARD_IN_SET(boardset, rbrd)); 1419 /* 1420 * Write the MC adr for the respective 1421 * remote board (rbrd) into the PCs of 1422 * the given local board (brd). 1423 */ 1424 if (pc_write_madr(ph, brd, rbrd, madr) < 0) { 1425 cmn_err(CE_WARN, 1426 "IDN: 512: failed [add] write-madr " 1427 "(bd=%d, rbd=%d, madr=0x%x)", 1428 brd, rbrd, madr); 1429 rv = -1; 1430 goto done; 1431 } 1432 } 1433 } 1434 1435 done: 1436 if (ph) 1437 pda_close(ph); 1438 1439 mutex_exit(&idn_xf_mutex); 1440 /* 1441 * XXX 1442 * 1443 * Failure here is fatal. Disable IDN? 1444 * NOn-zero return value will at least prevent 1445 * linkage with domain - probably sufficient. 1446 */ 1447 return (rv); 1448 } 1449 1450 /* 1451 * Remove the respective boardset from the local domain's 1452 * hardware configuration with respect to the SMR. 1453 * 1454 * is_master Indicates remote domain is a master. 1455 */ 1456 int 1457 idnxf_shmem_sub(int is_master, boardset_t boardset) 1458 { 1459 int rv = 0; 1460 register int brd, rbrd; 1461 register boardset_t localboardset; 1462 pda_handle_t ph; 1463 procname_t proc = "idnxf_shmem_sub"; 1464 1465 localboardset = idn_domain[idn.localid].dhw.dh_boardset; 1466 1467 ASSERT(localboardset && boardset && ((localboardset & boardset) == 0)); 1468 1469 PR_REGS("%s: is_master=%d, boardset=0x%x\n", 1470 proc, is_master, boardset); 1471 1472 /* 1473 * Need to serialize hardware access so we don't have multiple 1474 * threads attempting to access hardware regs simulataneously. 1475 * This should not be a significant performance penalty since 1476 * the hardware is only touched when domains are linking or 1477 * unlinking. 1478 */ 1479 mutex_enter(&idn_xf_mutex); 1480 1481 /* 1482 * Map in the post2obp structure so we can find 1483 * bus config information. 1484 */ 1485 ph = pda_open(); 1486 if (ph == (pda_handle_t)NULL) { 1487 cmn_err(CE_WARN, 1488 "IDN: 507: failed to map-in post2obp structure"); 1489 rv = -1; 1490 goto done; 1491 1492 } else if (!pda_is_valid(ph)) { 1493 cmn_err(CE_WARN, "IDN: 508: post2obp checksum invalid"); 1494 rv = -1; 1495 goto done; 1496 } 1497 /* 1498 * Take a checkpoint in bbsram for diagnostic purposes. 1499 */ 1500 CHECKPOINT_CLOSED(IDNSB_CHKPT_SMR, boardset, 2); 1501 1502 rv = idnxf_shmem_update_all(ph, boardset, (uint_t)-1, (uint_t)-1, 0); 1503 1504 if (rv || (is_master == 0)) 1505 goto done; 1506 1507 /* 1508 * If this is a slave (i.e. remote domain is_master), 1509 * then we need to deprogram our PCs. 1510 */ 1511 PR_REGS("%s: reseting PC regs (lboardset=0x%x, rboardset=0x%x)\n", 1512 proc, localboardset, boardset); 1513 1514 for (brd = 0; brd < MAX_BOARDS; brd++) { 1515 1516 if (!BOARD_IN_SET(localboardset, brd)) 1517 continue; 1518 1519 for (rbrd = 0; rbrd < MAX_BOARDS; rbrd++) { 1520 1521 if (!BOARD_IN_SET(boardset, rbrd)) 1522 continue; 1523 /* 1524 * Clear the MC adr for the respective 1525 * remote board (rbrd) into the PCs of 1526 * the given local board (brd). 1527 */ 1528 if (pc_write_madr(ph, brd, rbrd, 0) < 0) { 1529 cmn_err(CE_WARN, 1530 "IDN: 512: failed [del] write-madr " 1531 "(bd=%d, rbd=%d, madr=0x%x)", 1532 brd, rbrd, 0); 1533 rv = -1; 1534 goto done; 1535 } 1536 } 1537 } 1538 1539 done: 1540 if (ph) 1541 pda_close(ph); 1542 mutex_exit(&idn_xf_mutex); 1543 1544 return (rv); 1545 } 1546 1547 /* 1548 * We cannot cross-trap cpu_flush_ecache since it references 1549 * %g7 via CPU. It's possible that %g7 may not be set up 1550 * when the trap comes in, and could thus cause a crash. 1551 * Well...at least that's what has been happening when I 1552 * tried x-calls within an xc_attention (KMISS) panic. 1553 * Instead we use cross-calls. However, since we can't 1554 * xc_attention around a cross-call, we have not guaranteed 1555 * way of knowing the operation succeeded. To synchronize 1556 * this flush operation across cpus, we use a semaphore 1557 * which is V'd by the receiving cpus and P'd by the caller 1558 * initiating the all-cpus flush. 1559 */ 1560 /*ARGSUSED0*/ 1561 void 1562 idn_flush_ecache(uint64_t arg1, uint64_t arg2) 1563 { 1564 extern void cpu_flush_ecache(void); 1565 1566 cpu_flush_ecache(); 1567 /* 1568 * Paranoia...Give things a chance to drain. 1569 */ 1570 drv_usecwait(500000); /* 500 msec */ 1571 } 1572 /* 1573 * Flush the ecache's of all the cpus within this domain of 1574 * any possible SMR references. 1575 * This logic is borrowed from ecc.c:cpu_flush_ecache(). 1576 */ 1577 void 1578 idnxf_flushall_ecache() 1579 { 1580 cpuset_t local_cpuset; 1581 procname_t proc = "idnxf_flushall_ecache"; 1582 1583 1584 PR_XF("%s: flushing ecache (cpu_ready_set = 0x%x.%x)\n", 1585 proc, UPPER32_CPUMASK(cpu_ready_set), 1586 LOWER32_CPUMASK(cpu_ready_set)); 1587 1588 CHECKPOINT_CACHE_CLEAR_DEBUG(1); 1589 CHECKPOINT_CACHE_STEP_DEBUG(0x1, 2); 1590 1591 local_cpuset = cpu_ready_set; 1592 1593 xc_attention(local_cpuset); 1594 1595 /* 1596 * We tell each cpu to do a flush and then we hit 1597 * a semaphore to synchronize with all of them 1598 * to guarantee they have completed the flush before 1599 * we continue on. We have to do this type of 1600 * sychronization since we can't xc_attention around 1601 * a cross-call. 1602 */ 1603 CHECKPOINT_CACHE_STEP_DEBUG(0x2, 3); 1604 1605 xc_all(idn_flush_ecache, 0, 0); 1606 1607 CHECKPOINT_CACHE_STEP_DEBUG(0x4, 4); 1608 1609 xc_dismissed(local_cpuset); 1610 1611 CHECKPOINT_CACHE_STEP_DEBUG(0x8, 5); 1612 } 1613 1614 /* 1615 * -------------------------------------------------- 1616 */ 1617 static int 1618 verify_smregs(int brd, int bus, boardset_t smmask, 1619 uint_t smbase, uint_t smlimit) 1620 { 1621 int rv = 0; 1622 uint_t smreg; 1623 1624 if (smmask != (boardset_t)-1) { 1625 smreg = (uint_t)cic_read_sm_mask(brd, bus); 1626 if (smreg != (uint_t)smmask) { 1627 cmn_err(CE_WARN, 1628 "IDN: 513: sm-mask error " 1629 "(expected = 0x%x, actual = 0x%x)", 1630 (uint_t)smmask, smreg); 1631 rv++; 1632 } 1633 } 1634 1635 if (smbase != (uint_t)-1) { 1636 smreg = cic_read_sm_bar(brd, bus); 1637 if (smreg != smbase) { 1638 cmn_err(CE_WARN, 1639 "IDN: 514: sm-base error " 1640 "(expected = 0x%x, actual = 0x%x)", 1641 smbase, smreg); 1642 rv++; 1643 } 1644 } 1645 1646 if (smlimit != (uint_t)-1) { 1647 smreg = cic_read_sm_lar(brd, bus); 1648 if (smreg != smlimit) { 1649 cmn_err(CE_WARN, 1650 "IDN: 515: sm-limit error " 1651 "(expected = 0x%x, actual = 0x%x)", 1652 smlimit, smreg); 1653 rv++; 1654 } 1655 } 1656 1657 return (rv ? -1 : 0); 1658 } 1659 1660 /* 1661 * ------------------------------------------------------------- 1662 */ 1663 int 1664 idn_cpu_per_board(pda_handle_t ph, cpuset_t cset, struct hwconfig *hwp) 1665 { 1666 int b, err = 0; 1667 boardset_t bset, cpu_bset; 1668 board_desc_t *lbp; 1669 1670 if (!idn_check_cpu_per_board) 1671 return (1); 1672 1673 bset = hwp->dh_boardset; 1674 CPUSET_TO_BOARDSET(cset, cpu_bset); 1675 1676 /* 1677 * Every board has at least one cpu, we're happy. 1678 */ 1679 if (cpu_bset == bset) 1680 return (1); 1681 1682 /* 1683 * Well, not all boards had cpus. That's okay so 1684 * long as they don't have memory also. 1685 * Get rid of the boards that have a cpu. 1686 */ 1687 bset &= ~cpu_bset; 1688 /* 1689 * None of the remaining boards in the set shold have mem. 1690 */ 1691 err = 0; 1692 1693 /* 1694 * A NULL post2obp pointer indicates we're checking 1695 * the config of a remote domain. Since we can't 1696 * look at the post2obp of the remote domain, we'll 1697 * have to trust what he passed us in his config. 1698 */ 1699 if (ph && !pda_is_valid(ph)) { 1700 cmn_err(CE_WARN, "IDN: 508: post2obp checksum invalid"); 1701 return (0); 1702 } 1703 1704 for (b = 0; b < MAX_BOARDS; b++) { 1705 if (!BOARD_IN_SET(bset, b)) 1706 continue; 1707 1708 lbp = ph ? pda_get_board_info(ph, b) : NULL; 1709 1710 if ((lbp && 1711 (BDA_NBL(lbp->bda_board, BDA_MC_NBL) == BDAN_GOOD)) || 1712 (!lbp && hwp->dh_mcadr[b])) { 1713 err++; 1714 cmn_err(CE_WARN, 1715 "IDN: 516: (%s) board %d has memory, " 1716 "but no CPUs - CPU per memory board REQUIRED", 1717 ph ? "local" : "remote", b); 1718 } 1719 } 1720 1721 return (err ? 0 : 1); 1722 } 1723