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