1 /* $NetBSD: cpu.c,v 1.113 2014/06/10 18:27:41 palle Exp $ */ 2 3 /* 4 * Copyright (c) 1996 5 * The President and Fellows of Harvard College. All rights reserved. 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This software was developed by the Computer Systems Engineering group 10 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 11 * contributed to Berkeley. 12 * 13 * All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Harvard University. 16 * This product includes software developed by the University of 17 * California, Lawrence Berkeley Laboratory. 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 3. All advertising materials mentioning features or use of this software 29 * must display the following acknowledgement: 30 * This product includes software developed by Aaron Brown and 31 * Harvard University. 32 * This product includes software developed by the University of 33 * California, Berkeley and its contributors. 34 * 4. Neither the name of the University nor the names of its contributors 35 * may be used to endorse or promote products derived from this software 36 * without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 41 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * 50 * @(#)cpu.c 8.5 (Berkeley) 11/23/93 51 * 52 */ 53 54 #include <sys/cdefs.h> 55 __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.113 2014/06/10 18:27:41 palle Exp $"); 56 57 #include "opt_multiprocessor.h" 58 59 #include <sys/param.h> 60 #include <sys/systm.h> 61 #include <sys/device.h> 62 #include <sys/kernel.h> 63 #include <sys/reboot.h> 64 #include <sys/cpu.h> 65 66 #include <uvm/uvm.h> 67 68 #include <machine/autoconf.h> 69 #include <machine/cpu.h> 70 #include <machine/reg.h> 71 #include <machine/trap.h> 72 #include <machine/pmap.h> 73 #include <machine/sparc64.h> 74 #include <machine/openfirm.h> 75 76 #include <sparc64/sparc64/cache.h> 77 #ifdef SUN4V 78 #include <sparc64/hypervisor.h> 79 #endif 80 81 #ifdef SUN4V 82 #define SUN4V_MONDO_QUEUE_SIZE 32 83 #define SUN4V_QUEUE_ENTRY_SIZE 64 84 #endif 85 86 int ecache_min_line_size; 87 88 /* Linked list of all CPUs in system. */ 89 #if defined(MULTIPROCESSOR) 90 int sparc_ncpus = 0; 91 #endif 92 struct cpu_info *cpus = NULL; 93 94 volatile sparc64_cpuset_t cpus_active;/* set of active cpus */ 95 struct cpu_bootargs *cpu_args; /* allocated very early in pmap_bootstrap. */ 96 struct pool_cache *fpstate_cache; 97 98 static struct cpu_info *alloc_cpuinfo(u_int); 99 100 /* The following are used externally (sysctl_hw). */ 101 char machine[] = MACHINE; /* from <machine/param.h> */ 102 char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */ 103 104 /* These are used in locore.s, and are maximums */ 105 int dcache_line_size; 106 int dcache_size; 107 int icache_line_size; 108 int icache_size; 109 110 #ifdef MULTIPROCESSOR 111 static const char *ipi_evcnt_names[IPI_EVCNT_NUM] = IPI_EVCNT_NAMES; 112 #endif 113 114 static void cpu_reset_fpustate(void); 115 116 volatile int sync_tick = 0; 117 118 /* The CPU configuration driver. */ 119 void cpu_attach(device_t, device_t, void *); 120 int cpu_match(device_t, cfdata_t, void *); 121 122 CFATTACH_DECL_NEW(cpu, 0, cpu_match, cpu_attach, NULL, NULL); 123 124 static int 125 cpuid_from_node(u_int cpu_node) 126 { 127 /* 128 * Determine the cpuid by examining the nodes properties 129 * in the following order: 130 * upa-portid 131 * portid 132 * cpuid 133 * reg (sun4v only) 134 */ 135 136 int id; 137 138 id = prom_getpropint(cpu_node, "upa-portid", -1); 139 if (id == -1) 140 id = prom_getpropint(cpu_node, "portid", -1); 141 if (id == -1) 142 id = prom_getpropint(cpu_node, "cpuid", -1); 143 #ifdef SUN4V 144 if (CPU_ISSUN4V) { 145 int reg[4]; 146 int* regp=reg; 147 int len = 4; 148 int rc = prom_getprop(cpu_node, "reg", sizeof(int), 149 &len, ®p); 150 if ( rc != 0) 151 panic("No reg property found\n"); 152 /* cpuid in the lower 24 bits - sun4v hypervisor arch */ 153 id = reg[0] & 0x0fffffff; 154 } 155 #endif 156 if (id == -1) 157 panic("failed to determine cpuid"); 158 159 return id; 160 } 161 162 struct cpu_info * 163 alloc_cpuinfo(u_int cpu_node) 164 { 165 paddr_t pa0, pa; 166 vaddr_t va, va0; 167 vsize_t sz = 8 * PAGE_SIZE; 168 int cpuid; 169 struct cpu_info *cpi, *ci; 170 extern paddr_t cpu0paddr; 171 172 /* 173 * Check for matching cpuid in the cpus list. 174 */ 175 cpuid = cpuid_from_node(cpu_node); 176 177 for (cpi = cpus; cpi != NULL; cpi = cpi->ci_next) 178 if (cpi->ci_cpuid == cpuid) 179 return cpi; 180 181 /* Allocate the aligned VA and determine the size. */ 182 va = uvm_km_alloc(kernel_map, sz, 8 * PAGE_SIZE, UVM_KMF_VAONLY); 183 if (!va) 184 panic("alloc_cpuinfo: no virtual space"); 185 va0 = va; 186 187 pa0 = cpu0paddr; 188 cpu0paddr += sz; 189 190 for (pa = pa0; pa < cpu0paddr; pa += PAGE_SIZE, va += PAGE_SIZE) 191 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0); 192 193 pmap_update(pmap_kernel()); 194 195 cpi = (struct cpu_info *)(va0 + CPUINFO_VA - INTSTACK); 196 197 memset((void *)va0, 0, sz); 198 199 /* 200 * Initialize cpuinfo structure. 201 * 202 * Arrange pcb, idle stack and interrupt stack in the same 203 * way as is done for the boot CPU in pmap.c. 204 */ 205 cpi->ci_next = NULL; 206 cpi->ci_curlwp = NULL; 207 cpi->ci_cpuid = cpuid; 208 cpi->ci_fplwp = NULL; 209 cpi->ci_eintstack = NULL; 210 cpi->ci_spinup = NULL; 211 cpi->ci_paddr = pa0; 212 cpi->ci_self = cpi; 213 #ifdef SUN4V 214 if (CPU_ISSUN4V) 215 cpi->ci_mmfsa = pa0; 216 #endif 217 cpi->ci_node = cpu_node; 218 cpi->ci_idepth = -1; 219 memset(cpi->ci_intrpending, -1, sizeof(cpi->ci_intrpending)); 220 221 /* 222 * Finally, add itself to the list of active cpus. 223 */ 224 for (ci = cpus; ci->ci_next != NULL; ci = ci->ci_next) 225 ; 226 #ifdef MULTIPROCESSOR 227 ci->ci_next = cpi; 228 #endif 229 return (cpi); 230 } 231 232 int 233 cpu_match(device_t parent, cfdata_t cf, void *aux) 234 { 235 struct mainbus_attach_args *ma = aux; 236 237 if (strcmp(cf->cf_name, ma->ma_name) != 0) 238 return 0; 239 240 /* 241 * If we are going to only attach a single cpu, make sure 242 * to pick the one we are running on right now. 243 */ 244 if (cpuid_from_node(ma->ma_node) != cpu_myid()) { 245 #ifdef MULTIPROCESSOR 246 if (boothowto & RB_MD1) 247 #endif 248 return 0; 249 } 250 251 return 1; 252 } 253 254 static void 255 cpu_reset_fpustate(void) 256 { 257 struct fpstate64 *fpstate; 258 struct fpstate64 fps[2]; 259 260 /* This needs to be 64-byte aligned */ 261 fpstate = ALIGNFPSTATE(&fps[1]); 262 263 /* 264 * Get the FSR and clear any exceptions. If we do not unload 265 * the queue here and it is left over from a previous crash, we 266 * will panic in the first loadfpstate(), due to a sequence error, 267 * so we need to dump the whole state anyway. 268 */ 269 fpstate->fs_fsr = 7 << FSR_VER_SHIFT; /* 7 is reserved for "none" */ 270 savefpstate(fpstate); 271 } 272 273 /* 274 * Attach the CPU. 275 * Discover interesting goop about the virtual address cache 276 * (slightly funny place to do it, but this is where it is to be found). 277 */ 278 void 279 cpu_attach(device_t parent, device_t dev, void *aux) 280 { 281 int node; 282 long clk, sclk = 0; 283 struct mainbus_attach_args *ma = aux; 284 struct cpu_info *ci; 285 const char *sep; 286 register int i, l; 287 int bigcache, cachesize; 288 char buf[100]; 289 int totalsize = 0; 290 int linesize, dcachesize, icachesize; 291 292 /* tell them what we have */ 293 node = ma->ma_node; 294 295 /* 296 * Allocate cpu_info structure if needed. 297 */ 298 ci = alloc_cpuinfo((u_int)node); 299 300 /* 301 * Only do this on the boot cpu. Other cpu's call 302 * cpu_reset_fpustate() from cpu_hatch() before they 303 * call into the idle loop. 304 * For other cpus, we need to call mi_cpu_attach() 305 * and complete setting up cpcb. 306 */ 307 if (ci->ci_flags & CPUF_PRIMARY) { 308 fpstate_cache = pool_cache_init(sizeof(struct fpstate64), 309 SPARC64_BLOCK_SIZE, 0, 0, "fpstate", 310 NULL, IPL_NONE, NULL, NULL, NULL); 311 cpu_reset_fpustate(); 312 } 313 #ifdef MULTIPROCESSOR 314 else { 315 mi_cpu_attach(ci); 316 ci->ci_cpcb = lwp_getpcb(ci->ci_data.cpu_idlelwp); 317 } 318 for (i = 0; i < IPI_EVCNT_NUM; ++i) 319 evcnt_attach_dynamic(&ci->ci_ipi_evcnt[i], EVCNT_TYPE_INTR, 320 NULL, device_xname(dev), ipi_evcnt_names[i]); 321 #endif 322 evcnt_attach_dynamic(&ci->ci_tick_evcnt, EVCNT_TYPE_INTR, NULL, 323 device_xname(dev), "timer"); 324 mutex_init(&ci->ci_ctx_lock, MUTEX_SPIN, IPL_VM); 325 326 clk = prom_getpropint(node, "clock-frequency", 0); 327 if (clk == 0) { 328 /* 329 * Try to find it in the OpenPROM root... 330 */ 331 clk = prom_getpropint(findroot(), "clock-frequency", 0); 332 } 333 if (clk) { 334 /* Tell OS what frequency we run on */ 335 ci->ci_cpu_clockrate[0] = clk; 336 ci->ci_cpu_clockrate[1] = clk / 1000000; 337 } 338 339 sclk = prom_getpropint(findroot(), "stick-frequency", 0); 340 341 ci->ci_system_clockrate[0] = sclk; 342 ci->ci_system_clockrate[1] = sclk / 1000000; 343 344 snprintf(buf, sizeof buf, "%s @ %s MHz", 345 prom_getpropstring(node, "name"), clockfreq(clk / 1000)); 346 cpu_setmodel("%s (%s)", machine_model, buf); 347 348 aprint_normal(": %s, CPU id %d\n", buf, ci->ci_cpuid); 349 aprint_naive("\n"); 350 351 if (ci->ci_system_clockrate[0] != 0) { 352 aprint_normal_dev(dev, "system tick frequency %d MHz\n", 353 (int)ci->ci_system_clockrate[1]); 354 } 355 aprint_normal_dev(dev, ""); 356 357 /* XXX sun4v mising cache info printout */ 358 bigcache = 0; 359 360 icachesize = prom_getpropint(node, "icache-size", 0); 361 if (icachesize > icache_size) 362 icache_size = icachesize; 363 linesize = l = prom_getpropint(node, "icache-line-size", 0); 364 if (linesize > icache_line_size) 365 icache_line_size = linesize; 366 367 for (i = 0; (1 << i) < l && l; i++) 368 /* void */; 369 if ((1 << i) != l && l) 370 panic("bad icache line size %d", l); 371 totalsize = icachesize; 372 if (totalsize == 0) 373 totalsize = l * 374 prom_getpropint(node, "icache-nlines", 64) * 375 prom_getpropint(node, "icache-associativity", 1); 376 377 cachesize = totalsize / 378 prom_getpropint(node, "icache-associativity", 1); 379 bigcache = cachesize; 380 381 sep = ""; 382 if (totalsize > 0) { 383 aprint_normal("%s%ldK instruction (%ld b/l)", sep, 384 (long)totalsize/1024, 385 (long)linesize); 386 sep = ", "; 387 } 388 389 dcachesize = prom_getpropint(node, "dcache-size", 0); 390 if (dcachesize > dcache_size) 391 dcache_size = dcachesize; 392 linesize = l = prom_getpropint(node, "dcache-line-size", 0); 393 if (linesize > dcache_line_size) 394 dcache_line_size = linesize; 395 396 for (i = 0; (1 << i) < l && l; i++) 397 /* void */; 398 if ((1 << i) != l && l) 399 panic("bad dcache line size %d", l); 400 totalsize = dcachesize; 401 if (totalsize == 0) 402 totalsize = l * 403 prom_getpropint(node, "dcache-nlines", 128) * 404 prom_getpropint(node, "dcache-associativity", 1); 405 406 cachesize = totalsize / 407 prom_getpropint(node, "dcache-associativity", 1); 408 if (cachesize > bigcache) 409 bigcache = cachesize; 410 411 if (totalsize > 0) { 412 aprint_normal("%s%ldK data (%ld b/l)", sep, 413 (long)totalsize/1024, 414 (long)linesize); 415 sep = ", "; 416 } 417 418 linesize = l = 419 prom_getpropint(node, "ecache-line-size", 0); 420 for (i = 0; (1 << i) < l && l; i++) 421 /* void */; 422 if ((1 << i) != l && l) 423 panic("bad ecache line size %d", l); 424 totalsize = prom_getpropint(node, "ecache-size", 0); 425 if (totalsize == 0) 426 totalsize = l * 427 prom_getpropint(node, "ecache-nlines", 32768) * 428 prom_getpropint(node, "ecache-associativity", 1); 429 430 cachesize = totalsize / 431 prom_getpropint(node, "ecache-associativity", 1); 432 if (cachesize > bigcache) 433 bigcache = cachesize; 434 435 if (totalsize > 0) { 436 aprint_normal("%s%ldK external (%ld b/l)", sep, 437 (long)totalsize/1024, 438 (long)linesize); 439 } 440 aprint_normal("\n"); 441 442 if (ecache_min_line_size == 0 || 443 linesize < ecache_min_line_size) 444 ecache_min_line_size = linesize; 445 446 /* 447 * Now that we know the size of the largest cache on this CPU, 448 * re-color our pages. 449 */ 450 uvm_page_recolor(atop(bigcache)); /* XXX */ 451 452 /* 453 * CPU specific ipi setup 454 * Currently only necessary for SUN4V 455 */ 456 #ifdef SUN4V 457 if (CPU_ISSUN4V) { 458 paddr_t pa = ci->ci_paddr; 459 int err; 460 461 pa += CPUINFO_VA - INTSTACK; 462 pa += PAGE_SIZE; 463 464 ci->ci_cpumq = pa; 465 err = hv_cpu_qconf(CPU_MONDO_QUEUE, ci->ci_cpumq, SUN4V_MONDO_QUEUE_SIZE); 466 if (err != H_EOK) 467 panic("Unable to set cpu mondo queue: %d", err); 468 pa += SUN4V_MONDO_QUEUE_SIZE * SUN4V_QUEUE_ENTRY_SIZE; 469 470 ci->ci_devmq = pa; 471 err = hv_cpu_qconf(DEVICE_MONDO_QUEUE, ci->ci_devmq, SUN4V_MONDO_QUEUE_SIZE); 472 if (err != H_EOK) 473 panic("Unable to set device mondo queue: %d", err); 474 pa += SUN4V_MONDO_QUEUE_SIZE * SUN4V_QUEUE_ENTRY_SIZE; 475 476 ci->ci_mondo = pa; 477 pa += 64; /* mondo message is 64 bytes */ 478 479 ci->ci_cpuset = pa; 480 pa += 64; 481 } 482 #endif 483 484 } 485 486 int 487 cpu_myid(void) 488 { 489 char buf[32]; 490 int impl; 491 492 #ifdef SUN4V 493 if (CPU_ISSUN4V) { 494 uint64_t myid; 495 hv_cpu_myid(&myid); 496 return myid; 497 } 498 #endif 499 if (OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && 500 strcmp(buf, "SUNW,Ultra-Enterprise-10000") == 0) 501 return lduwa(0x1fff40000d0UL, ASI_PHYS_NON_CACHED); 502 impl = (getver() & VER_IMPL) >> VER_IMPL_SHIFT; 503 switch (impl) { 504 case IMPL_OLYMPUS_C: 505 case IMPL_JUPITER: 506 return CPU_JUPITERID; 507 case IMPL_CHEETAH: 508 case IMPL_CHEETAH_PLUS: 509 case IMPL_JAGUAR: 510 case IMPL_PANTHER: 511 return CPU_FIREPLANEID; 512 default: 513 return CPU_UPAID; 514 } 515 } 516 517 #if defined(MULTIPROCESSOR) 518 vaddr_t cpu_spinup_trampoline; 519 520 /* 521 * Start secondary processors in motion. 522 */ 523 void 524 cpu_boot_secondary_processors(void) 525 { 526 int i, pstate; 527 struct cpu_info *ci; 528 529 sync_tick = 0; 530 531 sparc64_ipi_init(); 532 533 if (boothowto & RB_MD1) { 534 cpus[0].ci_next = NULL; 535 sparc_ncpus = ncpu = ncpuonline = 1; 536 return; 537 } 538 539 for (ci = cpus; ci != NULL; ci = ci->ci_next) { 540 if (ci->ci_cpuid == CPU_UPAID) 541 continue; 542 543 cpu_pmap_prepare(ci, false); 544 cpu_args->cb_node = ci->ci_node; 545 cpu_args->cb_cpuinfo = ci->ci_paddr; 546 membar_Sync(); 547 548 /* Disable interrupts and start another CPU. */ 549 pstate = getpstate(); 550 setpstate(PSTATE_KERN); 551 552 prom_startcpu(ci->ci_node, (void *)cpu_spinup_trampoline, 0); 553 554 for (i = 0; i < 2000; i++) { 555 membar_Sync(); 556 if (CPUSET_HAS(cpus_active, ci->ci_index)) 557 break; 558 delay(10000); 559 } 560 561 /* synchronize %tick ( to some degree at least ) */ 562 delay(1000); 563 sync_tick = 1; 564 membar_Sync(); 565 if (CPU_ISSUN4U || CPU_ISSUN4US) 566 settick(0); 567 if (ci->ci_system_clockrate[0] != 0) 568 if (CPU_ISSUN4U || CPU_ISSUN4US) 569 setstick(0); 570 571 setpstate(pstate); 572 573 if (!CPUSET_HAS(cpus_active, ci->ci_index)) 574 printf("cpu%d: startup failed\n", ci->ci_cpuid); 575 } 576 } 577 578 void 579 cpu_hatch(void) 580 { 581 char *v = (char*)CPUINFO_VA; 582 int i; 583 584 for (i = 0; i < 4*PAGE_SIZE; i += sizeof(long)) 585 flush(v + i); 586 587 cpu_pmap_init(curcpu()); 588 CPUSET_ADD(cpus_active, cpu_number()); 589 cpu_reset_fpustate(); 590 curlwp = curcpu()->ci_data.cpu_idlelwp; 591 membar_Sync(); 592 593 /* wait for the boot CPU to flip the switch */ 594 while (sync_tick == 0) { 595 /* we do nothing here */ 596 } 597 if (CPU_ISSUN4U || CPU_ISSUN4US) 598 settick(0); 599 if (curcpu()->ci_system_clockrate[0] != 0) { 600 if (CPU_ISSUN4U || CPU_ISSUN4US) 601 setstick(0); 602 stickintr_establish(PIL_CLOCK, stickintr); 603 } else { 604 tickintr_establish(PIL_CLOCK, tickintr); 605 } 606 spl0(); 607 } 608 #endif /* MULTIPROCESSOR */ 609