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 2007 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/errno.h> 29 #include <sys/types.h> 30 #include <sys/param.h> 31 #include <sys/cpu.h> 32 #include <sys/cpuvar.h> 33 #include <sys/clock.h> 34 35 #include <sys/promif.h> 36 #include <sys/promimpl.h> 37 #include <sys/systm.h> 38 #include <sys/machsystm.h> 39 #include <sys/debug.h> 40 #include <sys/sunddi.h> 41 #include <sys/modctl.h> 42 #include <sys/spitregs.h> 43 #include <sys/cheetahregs.h> 44 #include <sys/cpu_module.h> 45 #include <sys/kobj.h> 46 #include <sys/cmp.h> 47 #include <sys/async.h> 48 #include <vm/page.h> 49 50 /* 51 * The OpenBoot Standalone Interface supplies the kernel with 52 * implementation dependent parameters through the devinfo/property mechanism 53 */ 54 typedef enum { XDRBOOL, XDRINT, XDRSTRING } xdrs; 55 56 /* 57 * structure describing properties that we are interested in querying the 58 * OBP for. 59 */ 60 struct getprop_info { 61 char *name; 62 xdrs type; 63 uint_t *var; 64 }; 65 66 /* 67 * structure used to convert between a string returned by the OBP & a type 68 * used within the kernel. We prefer to paramaterize rather than type. 69 */ 70 struct convert_info { 71 char *name; 72 uint_t var; 73 char *realname; 74 }; 75 76 /* 77 * structure describing nodes that we are interested in querying the OBP for 78 * properties. 79 */ 80 struct node_info { 81 char *name; 82 int size; 83 struct getprop_info *prop; 84 struct getprop_info *prop_end; 85 unsigned int *value; 86 }; 87 88 /* 89 * macro definitions for routines that form the OBP interface 90 */ 91 #define NEXT prom_nextnode 92 #define CHILD prom_childnode 93 #define GETPROP prom_getprop 94 #define GETPROPLEN prom_getproplen 95 96 97 /* 0=quiet; 1=verbose; 2=debug */ 98 int debug_fillsysinfo = 0; 99 #define VPRINTF if (debug_fillsysinfo) prom_printf 100 101 int ncpunode; 102 struct cpu_node cpunodes[NCPU]; 103 104 static void check_cpus_ver(void); 105 static void check_cpus_set(void); 106 void fill_cpu(pnode_t); 107 void fill_cpu_ddi(dev_info_t *); 108 void empty_cpu(int); 109 void plat_fill_mc(pnode_t); 110 #pragma weak plat_fill_mc 111 112 uint64_t system_clock_freq; 113 114 /* 115 * list of well known devices that must be mapped, and the variables that 116 * contain their addresses. 117 */ 118 caddr_t v_auxio_addr = NULL; 119 caddr_t v_eeprom_addr = NULL; 120 caddr_t v_timecheck_addr = NULL; 121 caddr_t v_rtc_addr_reg = NULL; 122 volatile unsigned char *v_rtc_data_reg = NULL; 123 volatile uint8_t *v_pmc_addr_reg = NULL; 124 volatile uint8_t *v_pmc_data_reg = NULL; 125 126 int niobus = 0; 127 uint_t niommu_tsbs = 0; 128 129 /* 130 * Hardware watchdog support. 131 */ 132 #define CHOSEN_EEPROM "eeprom" 133 #define WATCHDOG_ENABLE "watchdog-enable" 134 static pnode_t chosen_eeprom; 135 136 /* 137 * Appropriate tod module will be dynamically selected while booting 138 * based on finding a device tree node with a "device_type" property value 139 * of "tod". If such a node describing tod is not found, for backward 140 * compatibility, a node with a "name" property value of "eeprom" and 141 * "model" property value of "mk48t59" will be used. Failing to find a 142 * node matching either of the above criteria will result in no tod module 143 * being selected; this will cause the boot process to halt. 144 */ 145 char *tod_module_name; 146 147 /* 148 * If this variable is non-zero, cpr should return "not supported" when 149 * it is queried even though it would normally be supported on this platform. 150 */ 151 int cpr_supported_override; 152 153 /* 154 * Some platforms may need to support CPR even in the absence of the 155 * energystar-v* property (Enchilada server, for example). If this 156 * variable is non-zero, cpr should proceed even in the absence 157 * of the energystar-v* property. 158 */ 159 int cpr_platform_enable = 0; 160 161 /* 162 * Some nodes have functions that need to be called when they're seen. 163 */ 164 static void have_sbus(pnode_t); 165 static void have_pci(pnode_t); 166 static void have_eeprom(pnode_t); 167 static void have_auxio(pnode_t); 168 static void have_rtc(pnode_t); 169 static void have_tod(pnode_t); 170 static void have_pmc(pnode_t); 171 172 static struct wkdevice { 173 char *wk_namep; 174 void (*wk_func)(pnode_t); 175 caddr_t *wk_vaddrp; 176 ushort_t wk_flags; 177 #define V_OPTIONAL 0x0000 178 #define V_MUSTHAVE 0x0001 179 #define V_MAPPED 0x0002 180 #define V_MULTI 0x0003 /* optional, may be more than one */ 181 } wkdevice[] = { 182 { "sbus", have_sbus, NULL, V_MULTI }, 183 { "pci", have_pci, NULL, V_MULTI }, 184 { "eeprom", have_eeprom, NULL, V_MULTI }, 185 { "auxio", have_auxio, NULL, V_OPTIONAL }, 186 { "rtc", have_rtc, NULL, V_OPTIONAL }, 187 { "pmc", have_pmc, NULL, V_OPTIONAL }, 188 { 0, }, 189 }; 190 191 static void map_wellknown(pnode_t); 192 193 void 194 map_wellknown_devices() 195 { 196 struct wkdevice *wkp; 197 phandle_t ieeprom; 198 pnode_t root; 199 uint_t stick_freq; 200 201 /* 202 * if there is a chosen eeprom, note it (for have_eeprom()) 203 */ 204 if (GETPROPLEN(prom_chosennode(), CHOSEN_EEPROM) == 205 sizeof (phandle_t) && 206 GETPROP(prom_chosennode(), CHOSEN_EEPROM, (caddr_t)&ieeprom) != -1) 207 chosen_eeprom = (pnode_t)prom_decode_int(ieeprom); 208 209 root = prom_nextnode((pnode_t)0); 210 /* 211 * Get System clock frequency from root node if it exists. 212 */ 213 if (GETPROP(root, "stick-frequency", (caddr_t)&stick_freq) != -1) 214 system_clock_freq = stick_freq; 215 216 map_wellknown(NEXT((pnode_t)0)); 217 218 /* 219 * See if it worked 220 */ 221 for (wkp = wkdevice; wkp->wk_namep; ++wkp) { 222 if (wkp->wk_flags == V_MUSTHAVE) { 223 cmn_err(CE_PANIC, "map_wellknown_devices: required " 224 "device %s not mapped", wkp->wk_namep); 225 } 226 } 227 228 /* 229 * all sun4u systems must have an IO bus, i.e. sbus or pcibus 230 */ 231 if (niobus == 0) 232 cmn_err(CE_PANIC, "map_wellknown_devices: no i/o bus node"); 233 234 check_cpus_ver(); 235 check_cpus_set(); 236 } 237 238 /* 239 * map_wellknown - map known devices & registers 240 */ 241 static void 242 map_wellknown(pnode_t curnode) 243 { 244 extern int status_okay(int, char *, int); 245 char tmp_name[MAXSYSNAME]; 246 static void fill_address(pnode_t, char *); 247 int sok; 248 249 #ifdef VPRINTF 250 VPRINTF("map_wellknown(%x)\n", curnode); 251 #endif /* VPRINTF */ 252 253 for (curnode = CHILD(curnode); curnode; curnode = NEXT(curnode)) { 254 /* 255 * prune subtree if status property indicating not okay 256 */ 257 sok = status_okay((int)curnode, (char *)NULL, 0); 258 if (!sok) { 259 char devtype_buf[OBP_MAXPROPNAME]; 260 int size; 261 262 #ifdef VPRINTF 263 VPRINTF("map_wellknown: !okay status property\n"); 264 #endif /* VPRINTF */ 265 /* 266 * a status property indicating bad memory will be 267 * associated with a node which has a "device_type" 268 * property with a value of "memory-controller" 269 */ 270 if ((size = GETPROPLEN(curnode, 271 OBP_DEVICETYPE)) == -1) 272 continue; 273 if (size > OBP_MAXPROPNAME) { 274 cmn_err(CE_CONT, "node %x '%s' prop too " 275 "big\n", curnode, OBP_DEVICETYPE); 276 continue; 277 } 278 if (GETPROP(curnode, OBP_DEVICETYPE, 279 devtype_buf) == -1) { 280 cmn_err(CE_CONT, "node %x '%s' get failed\n", 281 curnode, OBP_DEVICETYPE); 282 continue; 283 } 284 if (strcmp(devtype_buf, "memory-controller") != 0) 285 continue; 286 /* 287 * ...else fall thru and process the node... 288 */ 289 } 290 bzero(tmp_name, MAXSYSNAME); 291 if (GETPROP(curnode, OBP_NAME, (caddr_t)tmp_name) != -1) 292 fill_address(curnode, tmp_name); 293 if (GETPROP(curnode, OBP_DEVICETYPE, tmp_name) != -1 && 294 strcmp(tmp_name, "cpu") == 0) { 295 fill_cpu(curnode); 296 } 297 if (strcmp(tmp_name, "tod") == 0) 298 have_tod(curnode); 299 if (sok && (strcmp(tmp_name, "memory-controller") == 0) && 300 (&plat_fill_mc != NULL)) 301 plat_fill_mc(curnode); 302 map_wellknown(curnode); 303 } 304 } 305 306 static void 307 fill_address(pnode_t curnode, char *namep) 308 { 309 struct wkdevice *wkp; 310 int size; 311 uint32_t vaddr; 312 313 for (wkp = wkdevice; wkp->wk_namep; ++wkp) { 314 if (strcmp(wkp->wk_namep, namep) != 0) 315 continue; 316 if (wkp->wk_flags == V_MAPPED) 317 return; 318 if (wkp->wk_vaddrp != NULL) { 319 if ((size = GETPROPLEN(curnode, OBP_ADDRESS)) == -1) { 320 cmn_err(CE_CONT, "device %s size %d\n", 321 namep, size); 322 continue; 323 } 324 if (size != sizeof (vaddr)) { 325 cmn_err(CE_CONT, "device %s address prop too " 326 "big\n", namep); 327 continue; 328 } 329 if (GETPROP(curnode, OBP_ADDRESS, 330 (caddr_t)&vaddr) == -1) { 331 cmn_err(CE_CONT, "device %s not mapped\n", 332 namep); 333 continue; 334 } 335 336 /* make into a native pointer */ 337 *wkp->wk_vaddrp = (caddr_t)(uintptr_t)vaddr; 338 #ifdef VPRINTF 339 VPRINTF("fill_address: %s mapped to %p\n", namep, 340 *wkp->wk_vaddrp); 341 #endif /* VPRINTF */ 342 } 343 if (wkp->wk_func != NULL) 344 (*wkp->wk_func)(curnode); 345 /* 346 * If this one is optional and there may be more than 347 * one, don't set V_MAPPED, which would cause us to skip it 348 * next time around 349 */ 350 if (wkp->wk_flags != V_MULTI) 351 wkp->wk_flags = V_MAPPED; 352 } 353 } 354 355 int 356 get_portid(pnode_t node, pnode_t *cmpp) 357 { 358 int portid; 359 int i; 360 char dev_type[OBP_MAXPROPNAME]; 361 pnode_t cpu_parent; 362 363 if (cmpp != NULL) 364 *cmpp = OBP_NONODE; 365 366 if (GETPROP(node, "portid", (caddr_t)&portid) != -1) 367 return (portid); 368 if (GETPROP(node, "upa-portid", (caddr_t)&portid) != -1) 369 return (portid); 370 if (GETPROP(node, "device_type", (caddr_t)&dev_type) == -1) 371 return (-1); 372 373 /* 374 * For a virtual cpu node that is a CMP core, the "portid" 375 * is in the parent node. 376 * For a virtual cpu node that is a CMT strand, the "portid" is 377 * in its grandparent node. 378 * So we iterate up as far as 2 levels to get the "portid". 379 */ 380 if (strcmp(dev_type, "cpu") == 0) { 381 cpu_parent = node = prom_parentnode(node); 382 for (i = 0; i < 2; i++) { 383 if (node == OBP_NONODE || node == OBP_BADNODE) 384 break; 385 if (GETPROP(node, "portid", (caddr_t)&portid) != -1) { 386 if (cmpp != NULL) 387 *cmpp = cpu_parent; 388 return (portid); 389 } 390 node = prom_parentnode(node); 391 } 392 } 393 394 return (-1); 395 } 396 397 /* 398 * Adjust page coloring variables based on the physical ecache setsize of 399 * the configured cpus: 400 * 401 * Set ecache_setsize to max ecache set size to be used by 402 * page_coloring_init() to determine the page colors to configure. 403 * The adjustment is unlikely to be necessary... For cheetah+ systems, 404 * ecache_setsize should already be set in cpu_fiximp() to the maximum 405 * possible ecache setsize of any supported cheetah+ cpus. The adjustment 406 * is for the off chance that a non-cheetah+ system may have heterogenous 407 * cpus. 408 * 409 * Set cpu_setsize to the actual cpu setsize if the setsize is homogenous 410 * across all cpus otherwise set it to -1 if heterogenous. 411 * 412 * Set cpu_page_colors to -1 to signify heterogeneity of ecache setsizes 413 * to the page_get routines. 414 */ 415 static void 416 adj_ecache_setsize(int ecsetsize) 417 { 418 if (ecsetsize > ecache_setsize) 419 ecache_setsize = ecsetsize; 420 421 switch (cpu_setsize) { 422 case -1: 423 break; 424 case 0: 425 cpu_setsize = ecsetsize; 426 break; 427 default: 428 /* set to -1 if hetergenous cpus */ 429 if (cpu_setsize != ecsetsize) { 430 if (do_pg_coloring) 431 cpu_page_colors = -1; 432 /* 433 * if page coloring disabled, cpu_page_colors should 434 * remain 0 to prevent page coloring processing. 435 */ 436 cpu_setsize = -1; 437 } 438 break; 439 } 440 } 441 442 void 443 fill_cpu(pnode_t node) 444 { 445 extern int cpu_get_cpu_unum(int, char *, int, int *); 446 struct cpu_node *cpunode; 447 processorid_t cpuid; 448 int portid; 449 int tlbsize; 450 int size; 451 uint_t clk_freq; 452 pnode_t cmpnode; 453 char namebuf[OBP_MAXPROPNAME], unum[UNUM_NAMLEN]; 454 char *namebufp; 455 456 if ((portid = get_portid(node, &cmpnode)) == -1) { 457 cmn_err(CE_PANIC, "portid not found"); 458 } 459 460 if (GETPROP(node, "cpuid", (caddr_t)&cpuid) == -1) { 461 cpuid = portid; 462 } 463 464 if (cpuid < 0 || cpuid >= NCPU) { 465 cmn_err(CE_PANIC, "cpu node %x: cpuid %d out of range", node, 466 cpuid); 467 return; 468 } 469 470 cpunode = &cpunodes[cpuid]; 471 cpunode->portid = portid; 472 cpunode->nodeid = node; 473 474 if (cpu_get_cpu_unum(cpuid, unum, UNUM_NAMLEN, &size) != 0) { 475 cpunode->fru_fmri[0] = '\0'; 476 } else { 477 (void) snprintf(cpunode->fru_fmri, sizeof (cpunode->fru_fmri), 478 "%s%s", CPU_FRU_FMRI, unum); 479 } 480 481 if (cmpnode) { 482 /* 483 * For the CMT case, the parent "core" node contains 484 * properties needed below, use it instead of the 485 * cpu node. 486 */ 487 if ((GETPROP(cmpnode, "device_type", namebuf) > 0) && 488 (strcmp(namebuf, "core") == 0)) { 489 node = cmpnode; 490 } 491 } 492 493 (void) GETPROP(node, (cmpnode ? "compatible" : "name"), namebuf); 494 namebufp = namebuf; 495 if (strncmp(namebufp, "SUNW,", 5) == 0) 496 namebufp += 5; 497 else if (strncmp(namebufp, "FJSV,", 5) == 0) 498 namebufp += 5; 499 (void) strcpy(cpunode->name, namebufp); 500 501 (void) GETPROP(node, "implementation#", 502 (caddr_t)&cpunode->implementation); 503 (void) GETPROP(node, "mask#", (caddr_t)&cpunode->version); 504 505 if (IS_CHEETAH(cpunode->implementation)) { 506 /* remap mask reg */ 507 cpunode->version = REMAP_CHEETAH_MASK(cpunode->version); 508 } 509 if (GETPROP(node, "clock-frequency", (caddr_t)&clk_freq) == -1) { 510 /* 511 * If we didn't find it in the CPU node, look in the root node. 512 */ 513 pnode_t root = prom_nextnode((pnode_t)0); 514 if (GETPROP(root, "clock-frequency", (caddr_t)&clk_freq) == -1) 515 clk_freq = 0; 516 } 517 cpunode->clock_freq = clk_freq; 518 519 ASSERT(cpunode->clock_freq != 0); 520 /* 521 * Compute scaling factor based on rate of %tick. This is used 522 * to convert from ticks derived from %tick to nanoseconds. See 523 * comment in sun4u/sys/clock.h for details. 524 */ 525 cpunode->tick_nsec_scale = (uint_t)(((uint64_t)NANOSEC << 526 (32 - TICK_NSEC_SHIFT)) / cpunode->clock_freq); 527 528 (void) GETPROP(node, "#itlb-entries", (caddr_t)&tlbsize); 529 ASSERT(tlbsize < USHRT_MAX); /* since we cast it */ 530 cpunode->itlb_size = (ushort_t)tlbsize; 531 532 (void) GETPROP(node, "#dtlb-entries", (caddr_t)&tlbsize); 533 ASSERT(tlbsize < USHRT_MAX); /* since we cast it */ 534 cpunode->dtlb_size = (ushort_t)tlbsize; 535 536 if (cmpnode != OBP_NONODE) { 537 /* 538 * If the CPU has a level 3 cache, then it will be the 539 * external cache. Otherwise the level 2 cache is the 540 * external cache. 541 */ 542 size = 0; 543 (void) GETPROP(node, "l3-cache-size", (caddr_t)&size); 544 if (size <= 0) 545 (void) GETPROP(node, "l2-cache-size", (caddr_t)&size); 546 ASSERT(size != 0); 547 cpunode->ecache_size = size; 548 549 size = 0; 550 (void) GETPROP(node, "l3-cache-line-size", (caddr_t)&size); 551 if (size <= 0) 552 (void) GETPROP(node, "l2-cache-line-size", 553 (caddr_t)&size); 554 ASSERT(size != 0); 555 cpunode->ecache_linesize = size; 556 557 size = 0; 558 (void) GETPROP(node, "l2-cache-associativity", (caddr_t)&size); 559 ASSERT(size != 0); 560 cpunode->ecache_associativity = size; 561 562 cmp_add_cpu(portid, cpuid); 563 } else { 564 size = 0; 565 (void) GETPROP(node, "ecache-size", (caddr_t)&size); 566 ASSERT(size != 0); 567 cpunode->ecache_size = size; 568 569 size = 0; 570 (void) GETPROP(node, "ecache-line-size", (caddr_t)&size); 571 ASSERT(size != 0); 572 cpunode->ecache_linesize = size; 573 574 size = 0; 575 (void) GETPROP(node, "ecache-associativity", (caddr_t)&size); 576 ASSERT(size != 0); 577 cpunode->ecache_associativity = size; 578 } 579 580 /* by default set msram to non-mirrored one */ 581 cpunode->msram = ECACHE_CPU_NON_MIRROR; 582 583 if (GETPROPLEN(node, "msram") != -1) { 584 cpunode->msram = ECACHE_CPU_MIRROR; 585 } 586 587 if (GETPROPLEN(node, "msram-observed") != -1) { 588 cpunode->msram = ECACHE_CPU_MIRROR; 589 } 590 591 if (ncpunode == 0) { 592 cpu_fiximp(node); 593 } 594 595 cpunode->ecache_setsize = 596 cpunode->ecache_size / cpunode->ecache_associativity; 597 598 adj_ecache_setsize(cpunode->ecache_setsize); 599 600 ncpunode++; 601 } 602 603 int 604 get_portid_ddi(dev_info_t *dip, dev_info_t **cmpp) 605 { 606 int portid; 607 int i; 608 char dev_type[OBP_MAXPROPNAME]; 609 int len = OBP_MAXPROPNAME; 610 dev_info_t *cpu_parent; 611 612 if (cmpp != NULL) 613 *cmpp = NULL; 614 615 if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 616 DDI_PROP_DONTPASS, "portid", -1)) != -1) 617 return (portid); 618 if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 619 DDI_PROP_DONTPASS, "upa-portid", -1)) != -1) 620 return (portid); 621 if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF, 622 DDI_PROP_DONTPASS, "device_type", (caddr_t)dev_type, 623 &len) != 0) 624 return (-1); 625 626 /* 627 * For a virtual cpu node that is a CMP core, the "portid" 628 * is in the parent node. 629 * For a virtual cpu node that is a CMT strand, the "portid" is 630 * in its grandparent node. 631 * So we iterate up as far as 2 levels to get the "portid". 632 */ 633 if (strcmp(dev_type, "cpu") == 0) { 634 cpu_parent = dip = ddi_get_parent(dip); 635 for (i = 0; dip != NULL && i < 2; i++) { 636 if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 637 DDI_PROP_DONTPASS, "portid", -1)) != -1) { 638 if (cmpp != NULL) 639 *cmpp = cpu_parent; 640 return (portid); 641 } 642 dip = ddi_get_parent(dip); 643 } 644 } 645 646 return (-1); 647 } 648 649 /* 650 * A hotplug version of fill_cpu(). (Doesn't assume that there's a node 651 * in the PROM device tree for this CPU.) We still need the PROM version 652 * since it is called very early in the boot cycle before (before 653 * setup_ddi()). Sigh...someday this will all be cleaned up. 654 */ 655 void 656 fill_cpu_ddi(dev_info_t *dip) 657 { 658 extern int cpu_get_cpu_unum(int, char *, int, int *); 659 struct cpu_node *cpunode; 660 processorid_t cpuid; 661 int portid; 662 int len = OBP_MAXPROPNAME; 663 int tlbsize; 664 dev_info_t *cmpnode; 665 char namebuf[OBP_MAXPROPNAME], unum[UNUM_NAMLEN]; 666 char *namebufp; 667 char dev_type[OBP_MAXPROPNAME]; 668 669 if ((portid = get_portid_ddi(dip, &cmpnode)) == -1) { 670 cmn_err(CE_PANIC, "portid not found"); 671 } 672 673 if ((cpuid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 674 DDI_PROP_DONTPASS, "cpuid", -1)) == -1) { 675 cpuid = portid; 676 } 677 678 if (cpuid < 0 || cpuid >= NCPU) { 679 cmn_err(CE_PANIC, "cpu dip %p: cpuid %d out of range", 680 (void *)dip, cpuid); 681 return; 682 } 683 684 cpunode = &cpunodes[cpuid]; 685 cpunode->portid = portid; 686 cpunode->nodeid = ddi_get_nodeid(dip); 687 688 if (cmpnode != NULL) { 689 /* 690 * For the CMT case, the parent "core" node contains 691 * properties needed below, use it instead of the 692 * cpu node. 693 */ 694 if ((ddi_prop_op(DDI_DEV_T_ANY, cmpnode, PROP_LEN_AND_VAL_BUF, 695 DDI_PROP_DONTPASS, "device_type", 696 (caddr_t)dev_type, &len) == DDI_PROP_SUCCESS) && 697 (strcmp(dev_type, "core") == 0)) 698 dip = cmpnode; 699 } 700 701 if (cpu_get_cpu_unum(cpuid, unum, UNUM_NAMLEN, &len) != 0) { 702 cpunode->fru_fmri[0] = '\0'; 703 } else { 704 (void) snprintf(cpunode->fru_fmri, sizeof (cpunode->fru_fmri), 705 "%s%s", CPU_FRU_FMRI, unum); 706 } 707 708 len = sizeof (namebuf); 709 (void) ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF, 710 DDI_PROP_DONTPASS, (cmpnode ? "compatible" : "name"), 711 (caddr_t)namebuf, &len); 712 713 namebufp = namebuf; 714 if (strncmp(namebufp, "SUNW,", 5) == 0) 715 namebufp += 5; 716 else if (strncmp(namebufp, "FJSV,", 5) == 0) 717 namebufp += 5; 718 (void) strcpy(cpunode->name, namebufp); 719 720 cpunode->implementation = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 721 DDI_PROP_DONTPASS, "implementation#", 0); 722 723 cpunode->version = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 724 DDI_PROP_DONTPASS, "mask#", 0); 725 726 if (IS_CHEETAH(cpunode->implementation)) { 727 /* remap mask reg */ 728 cpunode->version = REMAP_CHEETAH_MASK(cpunode->version); 729 } 730 731 cpunode->clock_freq = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip, 732 DDI_PROP_DONTPASS, "clock-frequency", 0); 733 734 ASSERT(cpunode->clock_freq != 0); 735 /* 736 * Compute scaling factor based on rate of %tick. This is used 737 * to convert from ticks derived from %tick to nanoseconds. See 738 * comment in sun4u/sys/clock.h for details. 739 */ 740 cpunode->tick_nsec_scale = (uint_t)(((uint64_t)NANOSEC << 741 (32 - TICK_NSEC_SHIFT)) / cpunode->clock_freq); 742 743 tlbsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 744 DDI_PROP_DONTPASS, "#itlb-entries", 0); 745 ASSERT(tlbsize < USHRT_MAX); /* since we cast it */ 746 cpunode->itlb_size = (ushort_t)tlbsize; 747 748 tlbsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 749 DDI_PROP_DONTPASS, "#dtlb-entries", 0); 750 ASSERT(tlbsize < USHRT_MAX); /* since we cast it */ 751 cpunode->dtlb_size = (ushort_t)tlbsize; 752 753 if (cmpnode != NULL) { 754 /* 755 * If the CPU has a level 3 cache, then that is it's 756 * external cache. Otherwise the external cache must 757 * be the level 2 cache. 758 */ 759 cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY, 760 dip, DDI_PROP_DONTPASS, "l3-cache-size", 0); 761 if (cpunode->ecache_size == 0) 762 cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY, 763 dip, DDI_PROP_DONTPASS, "l2-cache-size", 0); 764 ASSERT(cpunode->ecache_size != 0); 765 766 cpunode->ecache_linesize = ddi_prop_get_int(DDI_DEV_T_ANY, 767 dip, DDI_PROP_DONTPASS, "l3-cache-line-size", 0); 768 if (cpunode->ecache_linesize == 0) 769 cpunode->ecache_linesize = 770 ddi_prop_get_int(DDI_DEV_T_ANY, dip, 771 DDI_PROP_DONTPASS, "l2-cache-line-size", 0); 772 ASSERT(cpunode->ecache_linesize != 0); 773 774 cpunode->ecache_associativity = ddi_prop_get_int(DDI_DEV_T_ANY, 775 dip, DDI_PROP_DONTPASS, "l2-cache-associativity", 0); 776 ASSERT(cpunode->ecache_associativity != 0); 777 778 cmp_add_cpu(portid, cpuid); 779 } else { 780 cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY, 781 dip, DDI_PROP_DONTPASS, "ecache-size", 0); 782 ASSERT(cpunode->ecache_size != 0); 783 784 cpunode->ecache_linesize = ddi_prop_get_int(DDI_DEV_T_ANY, 785 dip, DDI_PROP_DONTPASS, "ecache-line-size", 0); 786 ASSERT(cpunode->ecache_linesize != 0); 787 788 cpunode->ecache_associativity = ddi_prop_get_int(DDI_DEV_T_ANY, 789 dip, DDI_PROP_DONTPASS, "ecache-associativity", 0); 790 ASSERT(cpunode->ecache_associativity != 0); 791 } 792 793 /* by default set msram to non-mirrored one */ 794 cpunode->msram = ECACHE_CPU_NON_MIRROR; 795 796 if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "msram")) { 797 cpunode->msram = ECACHE_CPU_MIRROR; 798 } else if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 799 "msram-observed")) { 800 cpunode->msram = ECACHE_CPU_MIRROR; 801 } 802 803 ASSERT(ncpunode > 0); /* fiximp not req'd */ 804 805 cpunode->ecache_setsize = 806 cpunode->ecache_size / cpunode->ecache_associativity; 807 808 adj_ecache_setsize(cpunode->ecache_setsize); 809 810 ncpunode++; 811 } 812 813 void 814 empty_cpu(int cpuid) 815 { 816 bzero(&cpunodes[cpuid], sizeof (struct cpu_node)); 817 ncpunode--; 818 } 819 820 #ifdef SF_ERRATA_30 /* call causes fp-disabled */ 821 int spitfire_call_bug = 0; 822 #endif 823 #ifdef SF_V9_TABLE_28 /* fp over/underflow traps may cause wrong fsr.cexc */ 824 int spitfire_bb_fsr_bug = 0; 825 #endif 826 827 #ifdef JALAPENO_ERRATA_85 828 /* 829 * Set the values here assuming we're running 2.4 or later Jalapenos. If 830 * not, they'll be reset below. Either way, the default can be overridden 831 * when we read /etc/system later in boot. 832 */ 833 int jp_errata_85_allow_slow_scrub = 1; 834 int jp_errata_85_enable = 0; 835 #endif /* JALAPENO_ERRATA_85 */ 836 837 static void 838 check_cpus_ver(void) 839 { 840 int i; 841 int impl, cpuid = getprocessorid(); 842 int min_supported_rev; 843 844 ASSERT(cpunodes[cpuid].nodeid != 0); 845 846 impl = cpunodes[cpuid].implementation; 847 switch (impl) { 848 default: 849 min_supported_rev = 0; 850 break; 851 case SPITFIRE_IMPL: 852 min_supported_rev = SPITFIRE_MINREV_SUPPORTED; 853 break; 854 case CHEETAH_IMPL: 855 min_supported_rev = CHEETAH_MINREV_SUPPORTED; 856 break; 857 } 858 859 for (i = 0; i < NCPU; i++) { 860 if (cpunodes[i].nodeid == 0) 861 continue; 862 863 if (IS_SPITFIRE(impl)) { 864 if (cpunodes[i].version < min_supported_rev) { 865 cmn_err(CE_PANIC, "UltraSPARC versions older " 866 "than %d.%d are no longer supported " 867 "(cpu #%d)", 868 SPITFIRE_MAJOR_VERSION(min_supported_rev), 869 SPITFIRE_MINOR_VERSION(min_supported_rev), 870 i); 871 } 872 873 /* 874 * Min supported rev is 2.1 but we've seen problems 875 * with that so we still want to warn if we see one. 876 */ 877 if (cpunodes[i].version < 0x22) { 878 cmn_err(CE_WARN, 879 "UltraSPARC versions older than " 880 "2.2 are not supported (cpu #%d)", i); 881 #ifdef SF_ERRATA_30 /* call causes fp-disabled */ 882 spitfire_call_bug = 1; 883 #endif /* SF_ERRATA_30 */ 884 } 885 } 886 887 888 #ifdef SF_V9_TABLE_28 /* fp over/underflow traps may cause wrong fsr.cexc */ 889 if (IS_SPITFIRE(impl) || IS_BLACKBIRD(impl)) 890 spitfire_bb_fsr_bug = 1; 891 #endif /* SF_V9_TABLE_28 */ 892 893 if (IS_CHEETAH(impl)) { 894 if (cpunodes[i].version < min_supported_rev) { 895 cmn_err(CE_PANIC, "UltraSPARC-III versions " 896 "older than %d.%d are no longer supported " 897 "(cpu #%d)", 898 CHEETAH_MAJOR_VERSION(min_supported_rev), 899 CHEETAH_MINOR_VERSION(min_supported_rev), 900 i); 901 } 902 903 } 904 905 #ifdef JALAPENO_ERRATA_85 906 if (IS_JALAPENO(impl) && (cpunodes[i].version < 0x24)) { 907 jp_errata_85_allow_slow_scrub = 0; 908 jp_errata_85_enable = 1; 909 } 910 #endif /* JALAPENO_ERRATA_85 */ 911 } 912 } 913 914 /* 915 * Check for a legal set of CPUs. 916 */ 917 static void 918 check_cpus_set(void) 919 { 920 int i; 921 int impl; 922 int npanther = 0; 923 int njupiter = 0; 924 925 impl = cpunodes[getprocessorid()].implementation; 926 927 switch (impl) { 928 case CHEETAH_PLUS_IMPL: 929 case JAGUAR_IMPL: 930 case PANTHER_IMPL: 931 /* 932 * Check for a legal heterogeneous set of CPUs. 933 */ 934 for (i = 0; i < NCPU; i++) { 935 if (cpunodes[i].nodeid == 0) 936 continue; 937 938 if (IS_PANTHER(cpunodes[i].implementation)) { 939 npanther += 1; 940 } 941 942 if (!(IS_CHEETAH_PLUS(cpunodes[i].implementation) || 943 IS_JAGUAR(cpunodes[i].implementation) || 944 IS_PANTHER(cpunodes[i].implementation))) { 945 use_mp = 0; 946 break; 947 } 948 } 949 break; 950 case OLYMPUS_C_IMPL: 951 case JUPITER_IMPL: 952 /* 953 * Check for a legal heterogeneous set of CPUs on the 954 * OPL platform. 955 */ 956 for (i = 0; i < NCPU; i++) { 957 if (cpunodes[i].nodeid == 0) 958 continue; 959 960 if (IS_JUPITER(cpunodes[i].implementation)) { 961 njupiter += 1; 962 } 963 if (!(IS_OLYMPUS_C(cpunodes[i].implementation) || 964 IS_JUPITER(cpunodes[i].implementation))) { 965 use_mp = 0; 966 break; 967 } 968 } 969 break; 970 default: 971 /* 972 * Check for a homogeneous set of CPUs. 973 */ 974 for (i = 0; i < NCPU; i++) { 975 if (cpunodes[i].nodeid == 0) 976 continue; 977 978 if (cpunodes[i].implementation != impl) { 979 use_mp = 0; 980 break; 981 } 982 } 983 break; 984 } 985 986 /* 987 * Change from mmu_page_sizes from 4 to 6 for totally-Panther domains, 988 * where npanther == ncpunode. Also, set ecache_alignsize (and a few 989 * other globals) to the correct value for totally-Panther domains. 990 */ 991 if (&mmu_init_mmu_page_sizes) { 992 (void) mmu_init_mmu_page_sizes(npanther); 993 } 994 if ((npanther == ncpunode) && (&cpu_fix_allpanther)) { 995 cpu_fix_allpanther(); 996 } 997 998 /* 999 * For all-Jupiter domains the cpu module will update the hwcap features 1000 * for integer multiply-add instruction support. 1001 */ 1002 if ((njupiter == ncpunode) && (&cpu_fix_alljupiter)) { 1003 cpu_fix_alljupiter(); 1004 } 1005 1006 /* 1007 * Set max cpus we can have based on ncpunode and use_mp 1008 */ 1009 if (use_mp) { 1010 int (*set_max_ncpus)(void); 1011 1012 set_max_ncpus = (int (*)(void)) 1013 kobj_getsymvalue("set_platform_max_ncpus", 0); 1014 1015 if (set_max_ncpus) { 1016 max_ncpus = set_max_ncpus(); 1017 if (max_ncpus < ncpunode) 1018 max_ncpus = ncpunode; 1019 boot_max_ncpus = ncpunode; 1020 } else { 1021 max_ncpus = ncpunode; 1022 } 1023 } else { 1024 cmn_err(CE_NOTE, "MP not supported on mismatched modules," 1025 " booting UP only"); 1026 1027 for (i = 0; i < NCPU; i++) { 1028 if (cpunodes[i].nodeid == 0) 1029 continue; 1030 1031 cmn_err(CE_NOTE, "cpu%d: %s version 0x%x", i, 1032 cpunodes[i].name, cpunodes[i].version); 1033 } 1034 1035 max_ncpus = 1; 1036 } 1037 } 1038 1039 /* 1040 * The first sysio must always programmed up for the system clock and error 1041 * handling purposes, referenced by v_sysio_addr in machdep.c. 1042 */ 1043 static void 1044 have_sbus(pnode_t node) 1045 { 1046 int size; 1047 uint_t portid; 1048 1049 size = GETPROPLEN(node, "upa-portid"); 1050 if (size == -1 || size > sizeof (portid)) 1051 cmn_err(CE_PANIC, "upa-portid size"); 1052 if (GETPROP(node, "upa-portid", (caddr_t)&portid) == -1) 1053 cmn_err(CE_PANIC, "upa-portid"); 1054 1055 niobus++; 1056 1057 /* 1058 * need one physical TSB 1059 */ 1060 niommu_tsbs++; 1061 } 1062 1063 1064 #define IOMMU_PER_SCHIZO 2 1065 1066 /* 1067 * The first psycho must always programmed up for the system clock and error 1068 * handling purposes. 1069 */ 1070 static void 1071 have_pci(pnode_t node) 1072 { 1073 int size; 1074 uint_t portid; 1075 char compatible[OBP_MAXDRVNAME]; 1076 1077 size = GETPROPLEN(node, "portid"); 1078 if (size == -1) size = GETPROPLEN(node, "upa-portid"); 1079 if (size == -1) 1080 return; 1081 if (size > sizeof (portid)) 1082 cmn_err(CE_PANIC, "portid size wrong"); 1083 1084 if (GETPROP(node, "portid", (caddr_t)&portid) == -1) 1085 if (GETPROP(node, "upa-portid", (caddr_t)&portid) == -1) 1086 cmn_err(CE_PANIC, "portid not found"); 1087 1088 niobus++; 1089 1090 1091 /* 1092 * Need two physical TSBs for Schizo compatible nodes, 1093 * one otherwise. 1094 */ 1095 compatible[0] = '\0'; 1096 (void) prom_getprop(node, OBP_COMPATIBLE, compatible); 1097 if (strcmp(compatible, "pci108e,8001") == 0) 1098 niommu_tsbs += IOMMU_PER_SCHIZO; 1099 else 1100 niommu_tsbs++; 1101 } 1102 1103 /* 1104 * The first eeprom is used as the TOD clock, referenced 1105 * by v_eeprom_addr in locore.s. 1106 */ 1107 static void 1108 have_eeprom(pnode_t node) 1109 { 1110 int size; 1111 uint32_t eaddr; 1112 1113 /* 1114 * "todmostek" module will be selected based on finding a "model" 1115 * property value of "mk48t59" in the "eeprom" node. 1116 */ 1117 if (tod_module_name == NULL) { 1118 char buf[MAXSYSNAME]; 1119 1120 if ((GETPROP(node, "model", buf) != -1) && 1121 (strcmp(buf, "mk48t59") == 0)) 1122 tod_module_name = "todmostek"; 1123 } 1124 1125 /* 1126 * If we have found two distinct eeprom's, then we're done. 1127 */ 1128 if (v_eeprom_addr && v_timecheck_addr != v_eeprom_addr) 1129 return; 1130 1131 /* 1132 * multiple eeproms may exist but at least 1133 * one must have an "address" property 1134 */ 1135 if ((size = GETPROPLEN(node, OBP_ADDRESS)) == -1) 1136 return; 1137 if (size != sizeof (eaddr)) 1138 cmn_err(CE_PANIC, "eeprom addr size"); 1139 if (GETPROP(node, OBP_ADDRESS, (caddr_t)&eaddr) == -1) 1140 cmn_err(CE_PANIC, "eeprom addr"); 1141 1142 /* 1143 * If we have a chosen eeprom and it is not this node, keep looking. 1144 */ 1145 if (chosen_eeprom != NULL && chosen_eeprom != node) { 1146 v_timecheck_addr = (caddr_t)(uintptr_t)eaddr; 1147 return; 1148 } 1149 1150 v_eeprom_addr = (caddr_t)(uintptr_t)eaddr; 1151 1152 /* 1153 * If we don't find an I/O board to use to check the clock, 1154 * we'll fall back on whichever TOD is available. 1155 */ 1156 if (v_timecheck_addr == NULL) 1157 v_timecheck_addr = v_eeprom_addr; 1158 1159 /* 1160 * Does this eeprom have watchdog support? 1161 */ 1162 if (GETPROPLEN(node, WATCHDOG_ENABLE) != -1) 1163 watchdog_available = 1; 1164 } 1165 1166 static void 1167 have_rtc(pnode_t node) 1168 { 1169 int size; 1170 uint32_t eaddr; 1171 1172 /* 1173 * "ds1287" module will be selected based on finding a "model" 1174 * property value of "ds1287" in the "rtc" node. 1175 */ 1176 if (tod_module_name == NULL) { 1177 char buf[MAXSYSNAME]; 1178 1179 if (GETPROP(node, "model", buf) != -1) { 1180 if ((strcmp(buf, "m5819p") == 0) || 1181 (strcmp(buf, "m5823") == 0)) 1182 tod_module_name = "todm5823"; 1183 else if (strcmp(buf, "ds1287") == 0) 1184 tod_module_name = "todds1287"; 1185 } 1186 } 1187 1188 /* 1189 * XXX - drives on if address prop doesn't exist, later falls 1190 * over in tod module 1191 */ 1192 if ((size = GETPROPLEN(node, OBP_ADDRESS)) == -1) 1193 return; 1194 if (size != sizeof (eaddr)) 1195 cmn_err(CE_PANIC, "rtc addr size"); 1196 if (GETPROP(node, OBP_ADDRESS, (caddr_t)&eaddr) == -1) 1197 cmn_err(CE_PANIC, "rtc addr"); 1198 1199 v_rtc_addr_reg = (caddr_t)(uintptr_t)eaddr; 1200 v_rtc_data_reg = (volatile unsigned char *)(uintptr_t)eaddr + 1; 1201 1202 /* 1203 * Does this rtc have watchdog support? 1204 */ 1205 if (GETPROPLEN(node, WATCHDOG_ENABLE) != -1) 1206 watchdog_available = 1; 1207 } 1208 1209 static void 1210 have_pmc(pnode_t node) 1211 { 1212 uint32_t vaddr; 1213 pnode_t root; 1214 1215 /* 1216 * Watchdog property is in the root node. 1217 */ 1218 root = prom_nextnode((pnode_t)0); 1219 if (GETPROPLEN(root, WATCHDOG_ENABLE) != -1) { 1220 /* 1221 * The hardware watchdog timer resides within logical 1222 * unit 8 of SuperI/O. The address property of the node 1223 * contains the virtual address that we use to program 1224 * the timer. 1225 */ 1226 if (GETPROP(node, OBP_ADDRESS, (caddr_t)&vaddr) == -1) { 1227 watchdog_available = 0; 1228 return; 1229 } 1230 v_pmc_addr_reg = (volatile uint8_t *)(uintptr_t)vaddr; 1231 v_pmc_data_reg = (volatile uint8_t *)(uintptr_t)vaddr + 1; 1232 watchdog_available = 1; 1233 } 1234 } 1235 1236 static void 1237 have_auxio(pnode_t node) 1238 { 1239 size_t size, n; 1240 uint32_t addr[5]; 1241 1242 /* 1243 * Get the size of the auzio's address property. 1244 * On some platforms, the address property contains one 1245 * entry and on others it contains five entries. 1246 * In all cases, the first entries are compatible. 1247 * 1248 * This routine gets the address property for the auxio 1249 * node and stores the first entry in v_auxio_addr which 1250 * is used by the routine set_auxioreg in sun4u/ml/locore.s. 1251 */ 1252 if ((size = GETPROPLEN(node, OBP_ADDRESS)) == -1) 1253 cmn_err(CE_PANIC, "no auxio address property"); 1254 1255 switch (n = (size / sizeof (addr[0]))) { 1256 case 1: 1257 break; 1258 case 5: 1259 break; 1260 default: 1261 cmn_err(CE_PANIC, "auxio addr has %lu entries?", n); 1262 } 1263 1264 if (GETPROP(node, OBP_ADDRESS, (caddr_t)addr) == -1) 1265 cmn_err(CE_PANIC, "auxio addr"); 1266 1267 v_auxio_addr = (caddr_t)(uintptr_t)(addr[0]); /* make into pointer */ 1268 } 1269 1270 static void 1271 have_tod(pnode_t node) 1272 { 1273 static char tod_name[MAXSYSNAME]; 1274 1275 if (GETPROP(node, OBP_NAME, (caddr_t)tod_name) == -1) 1276 cmn_err(CE_PANIC, "tod name"); 1277 /* 1278 * This is a node with "device_type" property value of "tod". 1279 * Name of the tod module is the name from the node. 1280 */ 1281 tod_module_name = tod_name; 1282 } 1283