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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/cpuvar.h> 29 #include <sys/systm.h> 30 #include <sys/sysmacros.h> 31 #include <sys/promif.h> 32 #include <sys/platform_module.h> 33 #include <sys/cmn_err.h> 34 #include <sys/errno.h> 35 #include <sys/machsystm.h> 36 #include <sys/bootconf.h> 37 #include <sys/nvpair.h> 38 #include <sys/kobj.h> 39 #include <sys/mem_cage.h> 40 #include <sys/opl.h> 41 #include <sys/scfd/scfostoescf.h> 42 #include <sys/cpu_sgnblk_defs.h> 43 #include <sys/utsname.h> 44 #include <sys/ddi.h> 45 #include <sys/sunndi.h> 46 #include <sys/lgrp.h> 47 #include <sys/memnode.h> 48 #include <sys/sysmacros.h> 49 #include <sys/time.h> 50 #include <sys/cpu.h> 51 #include <vm/vm_dep.h> 52 53 int (*opl_get_mem_unum)(int, uint64_t, char *, int, int *); 54 int (*opl_get_mem_sid)(char *unum, char *buf, int buflen, int *lenp); 55 int (*opl_get_mem_offset)(uint64_t paddr, uint64_t *offp); 56 int (*opl_get_mem_addr)(char *unum, char *sid, 57 uint64_t offset, uint64_t *paddr); 58 59 /* Memory for fcode claims. 16k times # maximum possible IO units */ 60 #define EFCODE_SIZE (OPL_MAX_BOARDS * OPL_MAX_IO_UNITS_PER_BOARD * 0x4000) 61 int efcode_size = EFCODE_SIZE; 62 63 #define OPL_MC_MEMBOARD_SHIFT 38 /* Boards on 256BG boundary */ 64 65 /* Set the maximum number of boards for DR */ 66 int opl_boards = OPL_MAX_BOARDS; 67 68 void sgn_update_all_cpus(ushort_t, uchar_t, uchar_t); 69 70 extern int tsb_lgrp_affinity; 71 72 int opl_tsb_spares = (OPL_MAX_BOARDS) * (OPL_MAX_PCICH_UNITS_PER_BOARD) * 73 (OPL_MAX_TSBS_PER_PCICH); 74 75 pgcnt_t opl_startup_cage_size = 0; 76 77 /* 78 * The length of the delay in seconds in communication with XSCF after 79 * which the warning message will be logged. 80 */ 81 uint_t xscf_connect_delay = 60 * 15; 82 83 static opl_model_info_t opl_models[] = { 84 { "FF1", OPL_MAX_BOARDS_FF1, FF1, STD_DISPATCH_TABLE }, 85 { "FF2", OPL_MAX_BOARDS_FF2, FF2, STD_DISPATCH_TABLE }, 86 { "DC1", OPL_MAX_BOARDS_DC1, DC1, STD_DISPATCH_TABLE }, 87 { "DC2", OPL_MAX_BOARDS_DC2, DC2, EXT_DISPATCH_TABLE }, 88 { "DC3", OPL_MAX_BOARDS_DC3, DC3, EXT_DISPATCH_TABLE }, 89 }; 90 static int opl_num_models = sizeof (opl_models)/sizeof (opl_model_info_t); 91 92 /* 93 * opl_cur_model 94 */ 95 static opl_model_info_t *opl_cur_model = NULL; 96 97 static struct memlist *opl_memlist_per_board(struct memlist *ml); 98 static void post_xscf_msg(char *, int); 99 static void pass2xscf_thread(); 100 101 /* 102 * Note FF/DC out-of-order instruction engine takes only a 103 * single cycle to execute each spin loop 104 * for comparison, Panther takes 6 cycles for same loop 105 * OPL_BOFF_SPIN = base spin loop, roughly one memory reference time 106 * OPL_BOFF_TM = approx nsec for OPL sleep instruction (1600 for OPL-C) 107 * OPL_BOFF_SLEEP = approx number of SPIN iterations to equal one sleep 108 * OPL_BOFF_MAX_SCALE - scaling factor for max backoff based on active cpus 109 * Listed values tuned for 2.15GHz to 2.64GHz systems 110 * Value may change for future systems 111 */ 112 #define OPL_BOFF_SPIN 7 113 #define OPL_BOFF_SLEEP 4 114 #define OPL_BOFF_TM 1600 115 #define OPL_BOFF_MAX_SCALE 8 116 117 #define OPL_CLOCK_TICK_THRESHOLD 128 118 #define OPL_CLOCK_TICK_NCPUS 64 119 120 extern int clock_tick_threshold; 121 extern int clock_tick_ncpus; 122 123 int 124 set_platform_max_ncpus(void) 125 { 126 return (OPL_MAX_CPU_PER_BOARD * OPL_MAX_BOARDS); 127 } 128 129 int 130 set_platform_tsb_spares(void) 131 { 132 return (MIN(opl_tsb_spares, MAX_UPA)); 133 } 134 135 static void 136 set_model_info() 137 { 138 extern int ts_dispatch_extended; 139 char name[MAXSYSNAME]; 140 int i; 141 142 /* 143 * Get model name from the root node. 144 * 145 * We are using the prom device tree since, at this point, 146 * the Solaris device tree is not yet setup. 147 */ 148 (void) prom_getprop(prom_rootnode(), "model", (caddr_t)name); 149 150 for (i = 0; i < opl_num_models; i++) { 151 if (strncmp(name, opl_models[i].model_name, MAXSYSNAME) == 0) { 152 opl_cur_model = &opl_models[i]; 153 break; 154 } 155 } 156 157 /* 158 * If model not matched, it's an unknown model. 159 * just return. 160 */ 161 if (i == opl_num_models) 162 return; 163 164 if ((opl_cur_model->model_cmds & EXT_DISPATCH_TABLE) && 165 (ts_dispatch_extended == -1)) { 166 /* 167 * Based on a platform model, select a dispatch table. 168 * Only DC2 and DC3 systems uses the alternate/extended 169 * TS dispatch table. 170 * FF1, FF2 and DC1 systems used standard dispatch tables. 171 */ 172 ts_dispatch_extended = 1; 173 } 174 175 } 176 177 static void 178 set_max_mmu_ctxdoms() 179 { 180 extern uint_t max_mmu_ctxdoms; 181 int max_boards; 182 183 /* 184 * From the model, get the maximum number of boards 185 * supported and set the value accordingly. If the model 186 * could not be determined or recognized, we assume the max value. 187 */ 188 if (opl_cur_model == NULL) 189 max_boards = OPL_MAX_BOARDS; 190 else 191 max_boards = opl_cur_model->model_max_boards; 192 193 /* 194 * On OPL, cores and MMUs are one-to-one. 195 */ 196 max_mmu_ctxdoms = OPL_MAX_CORE_UNITS_PER_BOARD * max_boards; 197 } 198 199 #pragma weak mmu_init_large_pages 200 201 void 202 set_platform_defaults(void) 203 { 204 extern char *tod_module_name; 205 extern void cpu_sgn_update(ushort_t, uchar_t, uchar_t, int); 206 extern void mmu_init_large_pages(size_t); 207 208 /* Set the CPU signature function pointer */ 209 cpu_sgn_func = cpu_sgn_update; 210 211 /* Set appropriate tod module for OPL platform */ 212 ASSERT(tod_module_name == NULL); 213 tod_module_name = "todopl"; 214 215 if ((mmu_page_sizes == max_mmu_page_sizes) && 216 (mmu_ism_pagesize != DEFAULT_ISM_PAGESIZE)) { 217 if (&mmu_init_large_pages) 218 mmu_init_large_pages(mmu_ism_pagesize); 219 } 220 221 tsb_lgrp_affinity = 1; 222 223 set_max_mmu_ctxdoms(); 224 } 225 226 /* 227 * Convert logical a board number to a physical one. 228 */ 229 230 #define LSBPROP "board#" 231 #define PSBPROP "physical-board#" 232 233 int 234 opl_get_physical_board(int id) 235 { 236 dev_info_t *root_dip, *dip = NULL; 237 char *dname = NULL; 238 int circ; 239 240 pnode_t pnode; 241 char pname[MAXSYSNAME] = {0}; 242 243 int lsb_id; /* Logical System Board ID */ 244 int psb_id; /* Physical System Board ID */ 245 246 247 /* 248 * This function is called on early stage of bootup when the 249 * kernel device tree is not initialized yet, and also 250 * later on when the device tree is up. We want to try 251 * the fast track first. 252 */ 253 root_dip = ddi_root_node(); 254 if (root_dip) { 255 /* Get from devinfo node */ 256 ndi_devi_enter(root_dip, &circ); 257 for (dip = ddi_get_child(root_dip); dip; 258 dip = ddi_get_next_sibling(dip)) { 259 260 dname = ddi_node_name(dip); 261 if (strncmp(dname, "pseudo-mc", 9) != 0) 262 continue; 263 264 if ((lsb_id = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 265 DDI_PROP_DONTPASS, LSBPROP, -1)) == -1) 266 continue; 267 268 if (id == lsb_id) { 269 if ((psb_id = (int)ddi_getprop(DDI_DEV_T_ANY, 270 dip, DDI_PROP_DONTPASS, PSBPROP, -1)) 271 == -1) { 272 ndi_devi_exit(root_dip, circ); 273 return (-1); 274 } else { 275 ndi_devi_exit(root_dip, circ); 276 return (psb_id); 277 } 278 } 279 } 280 ndi_devi_exit(root_dip, circ); 281 } 282 283 /* 284 * We do not have the kernel device tree, or we did not 285 * find the node for some reason (let's say the kernel 286 * device tree was modified), let's try the OBP tree. 287 */ 288 pnode = prom_rootnode(); 289 for (pnode = prom_childnode(pnode); pnode; 290 pnode = prom_nextnode(pnode)) { 291 292 if ((prom_getprop(pnode, "name", (caddr_t)pname) == -1) || 293 (strncmp(pname, "pseudo-mc", 9) != 0)) 294 continue; 295 296 if (prom_getprop(pnode, LSBPROP, (caddr_t)&lsb_id) == -1) 297 continue; 298 299 if (id == lsb_id) { 300 if (prom_getprop(pnode, PSBPROP, 301 (caddr_t)&psb_id) == -1) { 302 return (-1); 303 } else { 304 return (psb_id); 305 } 306 } 307 } 308 309 return (-1); 310 } 311 312 /* 313 * For OPL it's possible that memory from two or more successive boards 314 * will be contiguous across the boards, and therefore represented as a 315 * single chunk. 316 * This function splits such chunks down the board boundaries. 317 */ 318 static struct memlist * 319 opl_memlist_per_board(struct memlist *ml) 320 { 321 uint64_t ssize, low, high, boundary; 322 struct memlist *head, *tail, *new; 323 324 ssize = (1ull << OPL_MC_MEMBOARD_SHIFT); 325 326 head = tail = NULL; 327 328 for (; ml; ml = ml->next) { 329 low = (uint64_t)ml->address; 330 high = low+(uint64_t)(ml->size); 331 while (low < high) { 332 boundary = roundup(low+1, ssize); 333 boundary = MIN(high, boundary); 334 new = kmem_zalloc(sizeof (struct memlist), KM_SLEEP); 335 new->address = low; 336 new->size = boundary - low; 337 if (head == NULL) 338 head = new; 339 if (tail) { 340 tail->next = new; 341 new->prev = tail; 342 } 343 tail = new; 344 low = boundary; 345 } 346 } 347 return (head); 348 } 349 350 void 351 set_platform_cage_params(void) 352 { 353 extern pgcnt_t total_pages; 354 extern struct memlist *phys_avail; 355 struct memlist *ml, *tml; 356 357 if (kernel_cage_enable) { 358 pgcnt_t preferred_cage_size; 359 360 preferred_cage_size = MAX(opl_startup_cage_size, 361 total_pages / 256); 362 363 ml = opl_memlist_per_board(phys_avail); 364 365 /* 366 * Note: we are assuming that post has load the 367 * whole show in to the high end of memory. Having 368 * taken this leap, we copy the whole of phys_avail 369 * the glist and arrange for the cage to grow 370 * downward (descending pfns). 371 */ 372 kcage_range_init(ml, KCAGE_DOWN, preferred_cage_size); 373 374 /* free the memlist */ 375 do { 376 tml = ml->next; 377 kmem_free(ml, sizeof (struct memlist)); 378 ml = tml; 379 } while (ml != NULL); 380 } 381 382 if (kcage_on) 383 cmn_err(CE_NOTE, "!DR Kernel Cage is ENABLED"); 384 else 385 cmn_err(CE_NOTE, "!DR Kernel Cage is DISABLED"); 386 } 387 388 /*ARGSUSED*/ 389 int 390 plat_cpu_poweron(struct cpu *cp) 391 { 392 int (*opl_cpu_poweron)(struct cpu *) = NULL; 393 394 opl_cpu_poweron = 395 (int (*)(struct cpu *))kobj_getsymvalue("drmach_cpu_poweron", 0); 396 397 if (opl_cpu_poweron == NULL) 398 return (ENOTSUP); 399 else 400 return ((opl_cpu_poweron)(cp)); 401 402 } 403 404 /*ARGSUSED*/ 405 int 406 plat_cpu_poweroff(struct cpu *cp) 407 { 408 int (*opl_cpu_poweroff)(struct cpu *) = NULL; 409 410 opl_cpu_poweroff = 411 (int (*)(struct cpu *))kobj_getsymvalue("drmach_cpu_poweroff", 0); 412 413 if (opl_cpu_poweroff == NULL) 414 return (ENOTSUP); 415 else 416 return ((opl_cpu_poweroff)(cp)); 417 418 } 419 420 int 421 plat_max_boards(void) 422 { 423 return (OPL_MAX_BOARDS); 424 } 425 426 int 427 plat_max_cpu_units_per_board(void) 428 { 429 return (OPL_MAX_CPU_PER_BOARD); 430 } 431 432 int 433 plat_max_mem_units_per_board(void) 434 { 435 return (OPL_MAX_MEM_UNITS_PER_BOARD); 436 } 437 438 int 439 plat_max_io_units_per_board(void) 440 { 441 return (OPL_MAX_IO_UNITS_PER_BOARD); 442 } 443 444 int 445 plat_max_cmp_units_per_board(void) 446 { 447 return (OPL_MAX_CMP_UNITS_PER_BOARD); 448 } 449 450 int 451 plat_max_core_units_per_board(void) 452 { 453 return (OPL_MAX_CORE_UNITS_PER_BOARD); 454 } 455 456 int 457 plat_pfn_to_mem_node(pfn_t pfn) 458 { 459 return (pfn >> mem_node_pfn_shift); 460 } 461 462 /* ARGSUSED */ 463 void 464 plat_build_mem_nodes(prom_memlist_t *list, size_t nelems) 465 { 466 size_t elem; 467 pfn_t basepfn; 468 pgcnt_t npgs; 469 uint64_t boundary, ssize; 470 uint64_t low, high; 471 472 /* 473 * OPL mem slices are always aligned on a 256GB boundary. 474 */ 475 mem_node_pfn_shift = OPL_MC_MEMBOARD_SHIFT - MMU_PAGESHIFT; 476 mem_node_physalign = 0; 477 478 /* 479 * Boot install lists are arranged <addr, len>, <addr, len>, ... 480 */ 481 ssize = (1ull << OPL_MC_MEMBOARD_SHIFT); 482 for (elem = 0; elem < nelems; list++, elem++) { 483 low = list->addr; 484 high = low + list->size; 485 while (low < high) { 486 boundary = roundup(low+1, ssize); 487 boundary = MIN(high, boundary); 488 basepfn = btop(low); 489 npgs = btop(boundary - low); 490 mem_node_add_slice(basepfn, basepfn + npgs - 1); 491 low = boundary; 492 } 493 } 494 } 495 496 /* 497 * Find the CPU associated with a slice at boot-time. 498 */ 499 void 500 plat_fill_mc(pnode_t nodeid) 501 { 502 int board; 503 int memnode; 504 struct { 505 uint64_t addr; 506 uint64_t size; 507 } mem_range; 508 509 if (prom_getprop(nodeid, "board#", (caddr_t)&board) < 0) { 510 panic("Can not find board# property in mc node %x", nodeid); 511 } 512 if (prom_getprop(nodeid, "sb-mem-ranges", (caddr_t)&mem_range) < 0) { 513 panic("Can not find sb-mem-ranges property in mc node %x", 514 nodeid); 515 } 516 memnode = mem_range.addr >> OPL_MC_MEMBOARD_SHIFT; 517 plat_assign_lgrphand_to_mem_node(board, memnode); 518 } 519 520 /* 521 * Return the platform handle for the lgroup containing the given CPU 522 * 523 * For OPL, lgroup platform handle == board #. 524 */ 525 526 extern int mpo_disabled; 527 extern lgrp_handle_t lgrp_default_handle; 528 529 lgrp_handle_t 530 plat_lgrp_cpu_to_hand(processorid_t id) 531 { 532 lgrp_handle_t plathand; 533 534 /* 535 * Return the real platform handle for the CPU until 536 * such time as we know that MPO should be disabled. 537 * At that point, we set the "mpo_disabled" flag to true, 538 * and from that point on, return the default handle. 539 * 540 * By the time we know that MPO should be disabled, the 541 * first CPU will have already been added to a leaf 542 * lgroup, but that's ok. The common lgroup code will 543 * double check that the boot CPU is in the correct place, 544 * and in the case where mpo should be disabled, will move 545 * it to the root if necessary. 546 */ 547 if (mpo_disabled) { 548 /* If MPO is disabled, return the default (UMA) handle */ 549 plathand = lgrp_default_handle; 550 } else 551 plathand = (lgrp_handle_t)LSB_ID(id); 552 return (plathand); 553 } 554 555 /* 556 * Platform specific lgroup initialization 557 */ 558 void 559 plat_lgrp_init(void) 560 { 561 extern uint32_t lgrp_expand_proc_thresh; 562 extern uint32_t lgrp_expand_proc_diff; 563 564 /* 565 * Set tuneables for the OPL architecture 566 * 567 * lgrp_expand_proc_thresh is the minimum load on the lgroups 568 * this process is currently running on before considering 569 * expanding threads to another lgroup. 570 * 571 * lgrp_expand_proc_diff determines how much less the remote lgroup 572 * must be loaded before expanding to it. 573 * 574 * Since remote latencies can be costly, attempt to keep 3 threads 575 * within the same lgroup before expanding to the next lgroup. 576 */ 577 lgrp_expand_proc_thresh = LGRP_LOADAVG_THREAD_MAX * 3; 578 lgrp_expand_proc_diff = LGRP_LOADAVG_THREAD_MAX; 579 } 580 581 /* 582 * Platform notification of lgroup (re)configuration changes 583 */ 584 /*ARGSUSED*/ 585 void 586 plat_lgrp_config(lgrp_config_flag_t evt, uintptr_t arg) 587 { 588 update_membounds_t *umb; 589 lgrp_config_mem_rename_t lmr; 590 int sbd, tbd; 591 lgrp_handle_t hand, shand, thand; 592 int mnode, snode, tnode; 593 pfn_t start, end; 594 595 if (mpo_disabled) 596 return; 597 598 switch (evt) { 599 600 case LGRP_CONFIG_MEM_ADD: 601 /* 602 * Establish the lgroup handle to memnode translation. 603 */ 604 umb = (update_membounds_t *)arg; 605 606 hand = umb->u_board; 607 mnode = plat_pfn_to_mem_node(umb->u_base >> MMU_PAGESHIFT); 608 plat_assign_lgrphand_to_mem_node(hand, mnode); 609 610 break; 611 612 case LGRP_CONFIG_MEM_DEL: 613 /* 614 * Special handling for possible memory holes. 615 */ 616 umb = (update_membounds_t *)arg; 617 hand = umb->u_board; 618 if ((mnode = plat_lgrphand_to_mem_node(hand)) != -1) { 619 if (mem_node_config[mnode].exists) { 620 start = mem_node_config[mnode].physbase; 621 end = mem_node_config[mnode].physmax; 622 mem_node_pre_del_slice(start, end); 623 mem_node_post_del_slice(start, end, 0); 624 } 625 } 626 627 break; 628 629 case LGRP_CONFIG_MEM_RENAME: 630 /* 631 * During a DR copy-rename operation, all of the memory 632 * on one board is moved to another board -- but the 633 * addresses/pfns and memnodes don't change. This means 634 * the memory has changed locations without changing identity. 635 * 636 * Source is where we are copying from and target is where we 637 * are copying to. After source memnode is copied to target 638 * memnode, the physical addresses of the target memnode are 639 * renamed to match what the source memnode had. Then target 640 * memnode can be removed and source memnode can take its 641 * place. 642 * 643 * To do this, swap the lgroup handle to memnode mappings for 644 * the boards, so target lgroup will have source memnode and 645 * source lgroup will have empty target memnode which is where 646 * its memory will go (if any is added to it later). 647 * 648 * Then source memnode needs to be removed from its lgroup 649 * and added to the target lgroup where the memory was living 650 * but under a different name/memnode. The memory was in the 651 * target memnode and now lives in the source memnode with 652 * different physical addresses even though it is the same 653 * memory. 654 */ 655 sbd = arg & 0xffff; 656 tbd = (arg & 0xffff0000) >> 16; 657 shand = sbd; 658 thand = tbd; 659 snode = plat_lgrphand_to_mem_node(shand); 660 tnode = plat_lgrphand_to_mem_node(thand); 661 662 /* 663 * Special handling for possible memory holes. 664 */ 665 if (tnode != -1 && mem_node_config[tnode].exists) { 666 start = mem_node_config[tnode].physbase; 667 end = mem_node_config[tnode].physmax; 668 mem_node_pre_del_slice(start, end); 669 mem_node_post_del_slice(start, end, 0); 670 } 671 672 plat_assign_lgrphand_to_mem_node(thand, snode); 673 plat_assign_lgrphand_to_mem_node(shand, tnode); 674 675 lmr.lmem_rename_from = shand; 676 lmr.lmem_rename_to = thand; 677 678 /* 679 * Remove source memnode of copy rename from its lgroup 680 * and add it to its new target lgroup 681 */ 682 lgrp_config(LGRP_CONFIG_MEM_RENAME, (uintptr_t)snode, 683 (uintptr_t)&lmr); 684 685 break; 686 687 default: 688 break; 689 } 690 } 691 692 /* 693 * Return latency between "from" and "to" lgroups 694 * 695 * This latency number can only be used for relative comparison 696 * between lgroups on the running system, cannot be used across platforms, 697 * and may not reflect the actual latency. It is platform and implementation 698 * specific, so platform gets to decide its value. It would be nice if the 699 * number was at least proportional to make comparisons more meaningful though. 700 * NOTE: The numbers below are supposed to be load latencies for uncached 701 * memory divided by 10. 702 * 703 */ 704 int 705 plat_lgrp_latency(lgrp_handle_t from, lgrp_handle_t to) 706 { 707 /* 708 * Return min remote latency when there are more than two lgroups 709 * (root and child) and getting latency between two different lgroups 710 * or root is involved 711 */ 712 if (lgrp_optimizations() && (from != to || 713 from == LGRP_DEFAULT_HANDLE || to == LGRP_DEFAULT_HANDLE)) 714 return (42); 715 else 716 return (35); 717 } 718 719 /* 720 * Return platform handle for root lgroup 721 */ 722 lgrp_handle_t 723 plat_lgrp_root_hand(void) 724 { 725 if (mpo_disabled) 726 return (lgrp_default_handle); 727 728 return (LGRP_DEFAULT_HANDLE); 729 } 730 731 /*ARGSUSED*/ 732 void 733 plat_freelist_process(int mnode) 734 { 735 } 736 737 void 738 load_platform_drivers(void) 739 { 740 (void) i_ddi_attach_pseudo_node("dr"); 741 } 742 743 /* 744 * No platform drivers on this platform 745 */ 746 char *platform_module_list[] = { 747 (char *)0 748 }; 749 750 /*ARGSUSED*/ 751 void 752 plat_tod_fault(enum tod_fault_type tod_bad) 753 { 754 } 755 756 /*ARGSUSED*/ 757 void 758 cpu_sgn_update(ushort_t sgn, uchar_t state, uchar_t sub_state, int cpuid) 759 { 760 static void (*scf_panic_callback)(int); 761 static void (*scf_shutdown_callback)(int); 762 763 /* 764 * This is for notifing system panic/shutdown to SCF. 765 * In case of shutdown and panic, SCF call back 766 * function should be called. 767 * <SCF call back functions> 768 * scf_panic_callb() : panicsys()->panic_quiesce_hw() 769 * scf_shutdown_callb(): halt() or power_down() or reboot_machine() 770 * cpuid should be -1 and state should be SIGST_EXIT. 771 */ 772 if (state == SIGST_EXIT && cpuid == -1) { 773 774 /* 775 * find the symbol for the SCF panic callback routine in driver 776 */ 777 if (scf_panic_callback == NULL) 778 scf_panic_callback = (void (*)(int)) 779 modgetsymvalue("scf_panic_callb", 0); 780 if (scf_shutdown_callback == NULL) 781 scf_shutdown_callback = (void (*)(int)) 782 modgetsymvalue("scf_shutdown_callb", 0); 783 784 switch (sub_state) { 785 case SIGSUBST_PANIC: 786 if (scf_panic_callback == NULL) { 787 cmn_err(CE_NOTE, "!cpu_sgn_update: " 788 "scf_panic_callb not found\n"); 789 return; 790 } 791 scf_panic_callback(SIGSUBST_PANIC); 792 break; 793 794 case SIGSUBST_HALT: 795 if (scf_shutdown_callback == NULL) { 796 cmn_err(CE_NOTE, "!cpu_sgn_update: " 797 "scf_shutdown_callb not found\n"); 798 return; 799 } 800 scf_shutdown_callback(SIGSUBST_HALT); 801 break; 802 803 case SIGSUBST_ENVIRON: 804 if (scf_shutdown_callback == NULL) { 805 cmn_err(CE_NOTE, "!cpu_sgn_update: " 806 "scf_shutdown_callb not found\n"); 807 return; 808 } 809 scf_shutdown_callback(SIGSUBST_ENVIRON); 810 break; 811 812 case SIGSUBST_REBOOT: 813 if (scf_shutdown_callback == NULL) { 814 cmn_err(CE_NOTE, "!cpu_sgn_update: " 815 "scf_shutdown_callb not found\n"); 816 return; 817 } 818 scf_shutdown_callback(SIGSUBST_REBOOT); 819 break; 820 } 821 } 822 } 823 824 /*ARGSUSED*/ 825 int 826 plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id, 827 int flt_in_memory, ushort_t flt_status, 828 char *buf, int buflen, int *lenp) 829 { 830 /* 831 * check if it's a Memory error. 832 */ 833 if (flt_in_memory) { 834 if (opl_get_mem_unum != NULL) { 835 return (opl_get_mem_unum(synd_code, flt_addr, buf, 836 buflen, lenp)); 837 } else { 838 return (ENOTSUP); 839 } 840 } else { 841 return (ENOTSUP); 842 } 843 } 844 845 /*ARGSUSED*/ 846 int 847 plat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp) 848 { 849 int ret = 0; 850 int sb; 851 int plen; 852 853 sb = opl_get_physical_board(LSB_ID(cpuid)); 854 if (sb == -1) { 855 return (ENXIO); 856 } 857 858 /* 859 * opl_cur_model is assigned here 860 */ 861 if (opl_cur_model == NULL) { 862 set_model_info(); 863 864 /* 865 * if not matched, return 866 */ 867 if (opl_cur_model == NULL) 868 return (ENODEV); 869 } 870 871 ASSERT((opl_cur_model - opl_models) == (opl_cur_model->model_type)); 872 873 switch (opl_cur_model->model_type) { 874 case FF1: 875 plen = snprintf(buf, buflen, "/%s/CPUM%d", "MBU_A", 876 CHIP_ID(cpuid) / 2); 877 break; 878 879 case FF2: 880 plen = snprintf(buf, buflen, "/%s/CPUM%d", "MBU_B", 881 (CHIP_ID(cpuid) / 2) + (sb * 2)); 882 break; 883 884 case DC1: 885 case DC2: 886 case DC3: 887 plen = snprintf(buf, buflen, "/%s%02d/CPUM%d", "CMU", sb, 888 CHIP_ID(cpuid)); 889 break; 890 891 default: 892 /* This should never happen */ 893 return (ENODEV); 894 } 895 896 if (plen >= buflen) { 897 ret = ENOSPC; 898 } else { 899 if (lenp) 900 *lenp = strlen(buf); 901 } 902 return (ret); 903 } 904 905 void 906 plat_nodename_set(void) 907 { 908 post_xscf_msg((char *)&utsname, sizeof (struct utsname)); 909 } 910 911 caddr_t efcode_vaddr = NULL; 912 913 /* 914 * Preallocate enough memory for fcode claims. 915 */ 916 917 caddr_t 918 efcode_alloc(caddr_t alloc_base) 919 { 920 caddr_t efcode_alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, 921 MMU_PAGESIZE); 922 caddr_t vaddr; 923 924 /* 925 * allocate the physical memory for the Oberon fcode. 926 */ 927 if ((vaddr = (caddr_t)BOP_ALLOC(bootops, efcode_alloc_base, 928 efcode_size, MMU_PAGESIZE)) == NULL) 929 cmn_err(CE_PANIC, "Cannot allocate Efcode Memory"); 930 931 efcode_vaddr = vaddr; 932 933 return (efcode_alloc_base + efcode_size); 934 } 935 936 caddr_t 937 plat_startup_memlist(caddr_t alloc_base) 938 { 939 caddr_t tmp_alloc_base; 940 941 tmp_alloc_base = efcode_alloc(alloc_base); 942 tmp_alloc_base = 943 (caddr_t)roundup((uintptr_t)tmp_alloc_base, ecache_alignsize); 944 return (tmp_alloc_base); 945 } 946 947 /* need to forward declare these */ 948 static void plat_lock_delay(uint_t); 949 950 void 951 startup_platform(void) 952 { 953 if (clock_tick_threshold == 0) 954 clock_tick_threshold = OPL_CLOCK_TICK_THRESHOLD; 955 if (clock_tick_ncpus == 0) 956 clock_tick_ncpus = OPL_CLOCK_TICK_NCPUS; 957 mutex_lock_delay = plat_lock_delay; 958 mutex_cap_factor = OPL_BOFF_MAX_SCALE; 959 } 960 961 static uint_t 962 get_mmu_id(processorid_t cpuid) 963 { 964 int pb = opl_get_physical_board(LSB_ID(cpuid)); 965 966 if (pb == -1) { 967 cmn_err(CE_PANIC, 968 "opl_get_physical_board failed (cpu %d LSB %u)", 969 cpuid, LSB_ID(cpuid)); 970 } 971 return (pb * OPL_MAX_COREID_PER_BOARD) + (CHIP_ID(cpuid) * 972 OPL_MAX_COREID_PER_CMP) + CORE_ID(cpuid); 973 } 974 975 void 976 plat_cpuid_to_mmu_ctx_info(processorid_t cpuid, mmu_ctx_info_t *info) 977 { 978 int impl; 979 980 impl = cpunodes[cpuid].implementation; 981 if (IS_OLYMPUS_C(impl) || IS_JUPITER(impl)) { 982 info->mmu_idx = get_mmu_id(cpuid); 983 info->mmu_nctxs = 8192; 984 } else { 985 cmn_err(CE_PANIC, "Unknown processor %d", impl); 986 } 987 } 988 989 int 990 plat_get_mem_sid(char *unum, char *buf, int buflen, int *lenp) 991 { 992 if (opl_get_mem_sid == NULL) { 993 return (ENOTSUP); 994 } 995 return (opl_get_mem_sid(unum, buf, buflen, lenp)); 996 } 997 998 int 999 plat_get_mem_offset(uint64_t paddr, uint64_t *offp) 1000 { 1001 if (opl_get_mem_offset == NULL) { 1002 return (ENOTSUP); 1003 } 1004 return (opl_get_mem_offset(paddr, offp)); 1005 } 1006 1007 int 1008 plat_get_mem_addr(char *unum, char *sid, uint64_t offset, uint64_t *addrp) 1009 { 1010 if (opl_get_mem_addr == NULL) { 1011 return (ENOTSUP); 1012 } 1013 return (opl_get_mem_addr(unum, sid, offset, addrp)); 1014 } 1015 1016 void 1017 plat_lock_delay(uint_t backoff) 1018 { 1019 int i; 1020 uint_t cnt, remcnt; 1021 int ctr; 1022 hrtime_t delay_start, rem_delay; 1023 /* 1024 * Platform specific lock delay code for OPL 1025 * 1026 * Using staged linear increases in the delay. 1027 * The sleep instruction is the preferred method of delay, 1028 * but is too large of granularity for the initial backoff. 1029 */ 1030 1031 if (backoff < 100) { 1032 /* 1033 * If desired backoff is long enough, 1034 * use sleep for most of it 1035 */ 1036 for (cnt = backoff; 1037 cnt >= OPL_BOFF_SLEEP; 1038 cnt -= OPL_BOFF_SLEEP) { 1039 cpu_smt_pause(); 1040 } 1041 /* 1042 * spin for small remainder of backoff 1043 */ 1044 for (ctr = cnt * OPL_BOFF_SPIN; ctr; ctr--) { 1045 mutex_delay_default(); 1046 } 1047 } else { 1048 /* backoff is large. Fill it by sleeping */ 1049 delay_start = gethrtime(); 1050 cnt = backoff / OPL_BOFF_SLEEP; 1051 /* 1052 * use sleep instructions for delay 1053 */ 1054 for (i = 0; i < cnt; i++) { 1055 cpu_smt_pause(); 1056 } 1057 1058 /* 1059 * Note: if the other strand executes a sleep instruction, 1060 * then the sleep ends immediately with a minimum time of 1061 * 42 clocks. We check gethrtime to insure we have 1062 * waited long enough. And we include both a short 1063 * spin loop and a sleep for repeated delay times. 1064 */ 1065 1066 rem_delay = gethrtime() - delay_start; 1067 while (rem_delay < cnt * OPL_BOFF_TM) { 1068 remcnt = cnt - (rem_delay / OPL_BOFF_TM); 1069 for (i = 0; i < remcnt; i++) { 1070 cpu_smt_pause(); 1071 for (ctr = OPL_BOFF_SPIN; ctr; ctr--) { 1072 mutex_delay_default(); 1073 } 1074 } 1075 rem_delay = gethrtime() - delay_start; 1076 } 1077 } 1078 } 1079 1080 /* 1081 * The following code implements asynchronous call to XSCF to setup the 1082 * domain node name. 1083 */ 1084 1085 #define FREE_MSG(m) kmem_free((m), NM_LEN((m)->len)) 1086 1087 /* 1088 * The following three macros define the all operations on the request 1089 * list we are using here, and hide the details of the list 1090 * implementation from the code. 1091 */ 1092 #define PUSH(m) \ 1093 { \ 1094 (m)->next = ctl_msg.head; \ 1095 (m)->prev = NULL; \ 1096 if ((m)->next != NULL) \ 1097 (m)->next->prev = (m); \ 1098 ctl_msg.head = (m); \ 1099 } 1100 1101 #define REMOVE(m) \ 1102 { \ 1103 if ((m)->prev != NULL) \ 1104 (m)->prev->next = (m)->next; \ 1105 else \ 1106 ctl_msg.head = (m)->next; \ 1107 if ((m)->next != NULL) \ 1108 (m)->next->prev = (m)->prev; \ 1109 } 1110 1111 #define FREE_THE_TAIL(head) \ 1112 { \ 1113 nm_msg_t *n_msg, *m; \ 1114 m = (head)->next; \ 1115 (head)->next = NULL; \ 1116 while (m != NULL) { \ 1117 n_msg = m->next; \ 1118 FREE_MSG(m); \ 1119 m = n_msg; \ 1120 } \ 1121 } 1122 1123 #define SCF_PUTINFO(f, s, p) \ 1124 f(KEY_ESCF, 0x01, 0, s, p) 1125 1126 #define PASS2XSCF(m, r) ((r = SCF_PUTINFO(ctl_msg.scf_service_function, \ 1127 (m)->len, (m)->data)) == 0) 1128 1129 /* 1130 * The value of the following macro loosely depends on the 1131 * value of the "device busy" timeout used in the SCF driver. 1132 * (See pass2xscf_thread()). 1133 */ 1134 #define SCF_DEVBUSY_DELAY 10 1135 1136 /* 1137 * The default number of attempts to contact the scf driver 1138 * if we cannot fetch any information about the timeout value 1139 * it uses. 1140 */ 1141 1142 #define REPEATS 4 1143 1144 typedef struct nm_msg { 1145 struct nm_msg *next; 1146 struct nm_msg *prev; 1147 int len; 1148 char data[1]; 1149 } nm_msg_t; 1150 1151 #define NM_LEN(len) (sizeof (nm_msg_t) + (len) - 1) 1152 1153 static struct ctlmsg { 1154 nm_msg_t *head; 1155 nm_msg_t *now_serving; 1156 kmutex_t nm_lock; 1157 kthread_t *nmt; 1158 int cnt; 1159 int (*scf_service_function)(uint32_t, uint8_t, 1160 uint32_t, uint32_t, void *); 1161 } ctl_msg; 1162 1163 static void 1164 post_xscf_msg(char *dp, int len) 1165 { 1166 nm_msg_t *msg; 1167 1168 msg = (nm_msg_t *)kmem_zalloc(NM_LEN(len), KM_SLEEP); 1169 1170 bcopy(dp, msg->data, len); 1171 msg->len = len; 1172 1173 mutex_enter(&ctl_msg.nm_lock); 1174 if (ctl_msg.nmt == NULL) { 1175 ctl_msg.nmt = thread_create(NULL, 0, pass2xscf_thread, 1176 NULL, 0, &p0, TS_RUN, minclsyspri); 1177 } 1178 1179 PUSH(msg); 1180 ctl_msg.cnt++; 1181 mutex_exit(&ctl_msg.nm_lock); 1182 } 1183 1184 static void 1185 pass2xscf_thread() 1186 { 1187 nm_msg_t *msg; 1188 int ret; 1189 uint_t i, msg_sent, xscf_driver_delay; 1190 static uint_t repeat_cnt; 1191 uint_t *scf_wait_cnt; 1192 1193 mutex_enter(&ctl_msg.nm_lock); 1194 1195 /* 1196 * Find the address of the SCF put routine if it's not done yet. 1197 */ 1198 if (ctl_msg.scf_service_function == NULL) { 1199 if ((ctl_msg.scf_service_function = 1200 (int (*)(uint32_t, uint8_t, uint32_t, uint32_t, void *)) 1201 modgetsymvalue("scf_service_putinfo", 0)) == NULL) { 1202 cmn_err(CE_NOTE, "pass2xscf_thread: " 1203 "scf_service_putinfo not found\n"); 1204 ctl_msg.nmt = NULL; 1205 mutex_exit(&ctl_msg.nm_lock); 1206 return; 1207 } 1208 } 1209 1210 /* 1211 * Calculate the number of attempts to connect XSCF based on the 1212 * scf driver delay (which is 1213 * SCF_DEVBUSY_DELAY*scf_online_wait_rcnt seconds) and the value 1214 * of xscf_connect_delay (the total number of seconds to wait 1215 * till xscf get ready.) 1216 */ 1217 if (repeat_cnt == 0) { 1218 if ((scf_wait_cnt = 1219 (uint_t *) 1220 modgetsymvalue("scf_online_wait_rcnt", 0)) == NULL) { 1221 repeat_cnt = REPEATS; 1222 } else { 1223 1224 xscf_driver_delay = *scf_wait_cnt * 1225 SCF_DEVBUSY_DELAY; 1226 repeat_cnt = (xscf_connect_delay/xscf_driver_delay) + 1; 1227 } 1228 } 1229 1230 while (ctl_msg.cnt != 0) { 1231 1232 /* 1233 * Take the very last request from the queue, 1234 */ 1235 ctl_msg.now_serving = ctl_msg.head; 1236 ASSERT(ctl_msg.now_serving != NULL); 1237 1238 /* 1239 * and discard all the others if any. 1240 */ 1241 FREE_THE_TAIL(ctl_msg.now_serving); 1242 ctl_msg.cnt = 1; 1243 mutex_exit(&ctl_msg.nm_lock); 1244 1245 /* 1246 * Pass the name to XSCF. Note please, we do not hold the 1247 * mutex while we are doing this. 1248 */ 1249 msg_sent = 0; 1250 for (i = 0; i < repeat_cnt; i++) { 1251 if (PASS2XSCF(ctl_msg.now_serving, ret)) { 1252 msg_sent = 1; 1253 break; 1254 } else { 1255 if (ret != EBUSY) { 1256 cmn_err(CE_NOTE, "pass2xscf_thread:" 1257 " unexpected return code" 1258 " from scf_service_putinfo():" 1259 " %d\n", ret); 1260 } 1261 } 1262 } 1263 1264 if (msg_sent) { 1265 1266 /* 1267 * Remove the request from the list 1268 */ 1269 mutex_enter(&ctl_msg.nm_lock); 1270 msg = ctl_msg.now_serving; 1271 ctl_msg.now_serving = NULL; 1272 REMOVE(msg); 1273 ctl_msg.cnt--; 1274 mutex_exit(&ctl_msg.nm_lock); 1275 FREE_MSG(msg); 1276 } else { 1277 1278 /* 1279 * If while we have tried to communicate with 1280 * XSCF there were any other requests we are 1281 * going to drop this one and take the latest 1282 * one. Otherwise we will try to pass this one 1283 * again. 1284 */ 1285 cmn_err(CE_NOTE, 1286 "pass2xscf_thread: " 1287 "scf_service_putinfo " 1288 "not responding\n"); 1289 } 1290 mutex_enter(&ctl_msg.nm_lock); 1291 } 1292 1293 /* 1294 * The request queue is empty, exit. 1295 */ 1296 ctl_msg.nmt = NULL; 1297 mutex_exit(&ctl_msg.nm_lock); 1298 } 1299