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 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright (c) 2010, Intel Corporation.
  27  * All rights reserved.
  28  */
  29 /*
  30  * Copyright 2015 Joyent, Inc.
  31  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/thread.h>
  36 #include <sys/cpuvar.h>
  37 #include <sys/cpu.h>
  38 #include <sys/t_lock.h>
  39 #include <sys/param.h>
  40 #include <sys/proc.h>
  41 #include <sys/disp.h>
  42 #include <sys/class.h>
  43 #include <sys/cmn_err.h>
  44 #include <sys/debug.h>
  45 #include <sys/note.h>
  46 #include <sys/asm_linkage.h>
  47 #include <sys/x_call.h>
  48 #include <sys/systm.h>
  49 #include <sys/var.h>
  50 #include <sys/vtrace.h>
 
 
 230                 ASSERT32(UCS_SEL == ((KCS_SEL + 16) | 3));
 231                 ASSERT32(UDS_SEL == UCS_SEL + 8);
 232 
 233                 ASSERT64(U32CS_SEL == ((KCS_SEL + 16) | 3));
 234                 ASSERT64(UDS_SEL == U32CS_SEL + 8);
 235 #endif
 236 
 237                 cpu_sep_enable();
 238 
 239                 /*
 240                  * resume() sets this value to the base of the threads stack
 241                  * via a context handler.
 242                  */
 243                 wrmsr(MSR_INTC_SEP_ESP, 0);
 244                 wrmsr(MSR_INTC_SEP_EIP, (uint64_t)(uintptr_t)sys_sysenter);
 245         }
 246 
 247         kpreempt_enable();
 248 }
 249 
 250 /*
 251  * Multiprocessor initialization.
 252  *
 253  * Allocate and initialize the cpu structure, TRAPTRACE buffer, and the
 254  * startup and idle threads for the specified CPU.
 255  * Parameter boot is true for boot time operations and is false for CPU
 256  * DR operations.
 257  */
 258 static struct cpu *
 259 mp_cpu_configure_common(int cpun, boolean_t boot)
 260 {
 261         struct cpu *cp;
 262         kthread_id_t tp;
 263         caddr_t sp;
 264         proc_t *procp;
 265 #if !defined(__xpv)
 266         extern int idle_cpu_prefer_mwait;
 267         extern void cpu_idle_mwait();
 268 #endif
 269         extern void idle();
 270         extern void cpu_idle();
 
 413                 bcopy(CPU->cpu_idt, cp->cpu_idt, PAGESIZE);
 414         } else {
 415                 cp->cpu_idt = CPU->cpu_idt;
 416         }
 417 
 418         /*
 419          * alloc space for cpuid info
 420          */
 421         cpuid_alloc_space(cp);
 422 #if !defined(__xpv)
 423         if (is_x86_feature(x86_featureset, X86FSET_MWAIT) &&
 424             idle_cpu_prefer_mwait) {
 425                 cp->cpu_m.mcpu_mwait = cpuid_mwait_alloc(cp);
 426                 cp->cpu_m.mcpu_idle_cpu = cpu_idle_mwait;
 427         } else
 428 #endif
 429                 cp->cpu_m.mcpu_idle_cpu = cpu_idle;
 430 
 431         init_cpu_info(cp);
 432 
 433         /*
 434          * alloc space for ucode_info
 435          */
 436         ucode_alloc_space(cp);
 437         xc_init_cpu(cp);
 438         hat_cpu_online(cp);
 439 
 440 #ifdef TRAPTRACE
 441         /*
 442          * If this is a TRAPTRACE kernel, allocate TRAPTRACE buffers
 443          */
 444         ttc->ttc_first = (uintptr_t)kmem_zalloc(trap_trace_bufsize, KM_SLEEP);
 445         ttc->ttc_next = ttc->ttc_first;
 446         ttc->ttc_limit = ttc->ttc_first + trap_trace_bufsize;
 447 #endif
 448 
 449         /*
 450          * Record that we have another CPU.
 451          */
 452         /*
 
1469                 tempset = *((volatile cpuset_t *)&cpu_ready_set);
1470         }
1471         mutex_enter(&cpu_lock);
1472 
1473         return (0);
1474 }
1475 
1476 void
1477 start_other_cpus(int cprboot)
1478 {
1479         _NOTE(ARGUNUSED(cprboot));
1480 
1481         uint_t who;
1482         uint_t bootcpuid = 0;
1483 
1484         /*
1485          * Initialize our own cpu_info.
1486          */
1487         init_cpu_info(CPU);
1488 
1489         cmn_err(CE_CONT, "?cpu%d: %s\n", CPU->cpu_id, CPU->cpu_idstr);
1490         cmn_err(CE_CONT, "?cpu%d: %s\n", CPU->cpu_id, CPU->cpu_brandstr);
1491 
1492         /*
1493          * Initialize our syscall handlers
1494          */
1495         init_cpu_syscall(CPU);
1496 
1497         /*
1498          * Take the boot cpu out of the mp_cpus set because we know
1499          * it's already running.  Add it to the cpu_ready_set for
1500          * precisely the same reason.
1501          */
1502         CPUSET_DEL(mp_cpus, bootcpuid);
1503         CPUSET_ADD(cpu_ready_set, bootcpuid);
1504 
1505         /*
1506          * skip the rest of this if
1507          * . only 1 cpu dectected and system isn't hotplug-capable
1508          * . not using MP
 
 | 
 
 
  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 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright (c) 2010, Intel Corporation.
  27  * All rights reserved.
  28  */
  29 /*
  30  * Copyright 2016 Joyent, Inc.
  31  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/thread.h>
  36 #include <sys/cpuvar.h>
  37 #include <sys/cpu.h>
  38 #include <sys/t_lock.h>
  39 #include <sys/param.h>
  40 #include <sys/proc.h>
  41 #include <sys/disp.h>
  42 #include <sys/class.h>
  43 #include <sys/cmn_err.h>
  44 #include <sys/debug.h>
  45 #include <sys/note.h>
  46 #include <sys/asm_linkage.h>
  47 #include <sys/x_call.h>
  48 #include <sys/systm.h>
  49 #include <sys/var.h>
  50 #include <sys/vtrace.h>
 
 
 230                 ASSERT32(UCS_SEL == ((KCS_SEL + 16) | 3));
 231                 ASSERT32(UDS_SEL == UCS_SEL + 8);
 232 
 233                 ASSERT64(U32CS_SEL == ((KCS_SEL + 16) | 3));
 234                 ASSERT64(UDS_SEL == U32CS_SEL + 8);
 235 #endif
 236 
 237                 cpu_sep_enable();
 238 
 239                 /*
 240                  * resume() sets this value to the base of the threads stack
 241                  * via a context handler.
 242                  */
 243                 wrmsr(MSR_INTC_SEP_ESP, 0);
 244                 wrmsr(MSR_INTC_SEP_EIP, (uint64_t)(uintptr_t)sys_sysenter);
 245         }
 246 
 247         kpreempt_enable();
 248 }
 249 
 250 #if !defined(__xpv)
 251 /*
 252  * Configure per-cpu ID GDT
 253  */
 254 static void
 255 init_cpu_id_gdt(struct cpu *cp)
 256 {
 257         /* Write cpu_id into limit field of GDT for usermode retrieval */
 258 #if defined(__amd64)
 259         set_usegd(&cp->cpu_gdt[GDT_CPUID], SDP_SHORT, NULL, cp->cpu_id,
 260             SDT_MEMRODA, SEL_UPL, SDP_BYTES, SDP_OP32);
 261 #elif defined(__i386)
 262         set_usegd(&cp->cpu_gdt[GDT_CPUID], NULL, cp->cpu_id, SDT_MEMRODA,
 263             SEL_UPL, SDP_BYTES, SDP_OP32);
 264 #endif
 265 }
 266 #endif /* !defined(__xpv) */
 267 
 268 /*
 269  * Multiprocessor initialization.
 270  *
 271  * Allocate and initialize the cpu structure, TRAPTRACE buffer, and the
 272  * startup and idle threads for the specified CPU.
 273  * Parameter boot is true for boot time operations and is false for CPU
 274  * DR operations.
 275  */
 276 static struct cpu *
 277 mp_cpu_configure_common(int cpun, boolean_t boot)
 278 {
 279         struct cpu *cp;
 280         kthread_id_t tp;
 281         caddr_t sp;
 282         proc_t *procp;
 283 #if !defined(__xpv)
 284         extern int idle_cpu_prefer_mwait;
 285         extern void cpu_idle_mwait();
 286 #endif
 287         extern void idle();
 288         extern void cpu_idle();
 
 431                 bcopy(CPU->cpu_idt, cp->cpu_idt, PAGESIZE);
 432         } else {
 433                 cp->cpu_idt = CPU->cpu_idt;
 434         }
 435 
 436         /*
 437          * alloc space for cpuid info
 438          */
 439         cpuid_alloc_space(cp);
 440 #if !defined(__xpv)
 441         if (is_x86_feature(x86_featureset, X86FSET_MWAIT) &&
 442             idle_cpu_prefer_mwait) {
 443                 cp->cpu_m.mcpu_mwait = cpuid_mwait_alloc(cp);
 444                 cp->cpu_m.mcpu_idle_cpu = cpu_idle_mwait;
 445         } else
 446 #endif
 447                 cp->cpu_m.mcpu_idle_cpu = cpu_idle;
 448 
 449         init_cpu_info(cp);
 450 
 451 #if !defined(__xpv)
 452         init_cpu_id_gdt(cp);
 453 #endif
 454 
 455         /*
 456          * alloc space for ucode_info
 457          */
 458         ucode_alloc_space(cp);
 459         xc_init_cpu(cp);
 460         hat_cpu_online(cp);
 461 
 462 #ifdef TRAPTRACE
 463         /*
 464          * If this is a TRAPTRACE kernel, allocate TRAPTRACE buffers
 465          */
 466         ttc->ttc_first = (uintptr_t)kmem_zalloc(trap_trace_bufsize, KM_SLEEP);
 467         ttc->ttc_next = ttc->ttc_first;
 468         ttc->ttc_limit = ttc->ttc_first + trap_trace_bufsize;
 469 #endif
 470 
 471         /*
 472          * Record that we have another CPU.
 473          */
 474         /*
 
1491                 tempset = *((volatile cpuset_t *)&cpu_ready_set);
1492         }
1493         mutex_enter(&cpu_lock);
1494 
1495         return (0);
1496 }
1497 
1498 void
1499 start_other_cpus(int cprboot)
1500 {
1501         _NOTE(ARGUNUSED(cprboot));
1502 
1503         uint_t who;
1504         uint_t bootcpuid = 0;
1505 
1506         /*
1507          * Initialize our own cpu_info.
1508          */
1509         init_cpu_info(CPU);
1510 
1511 #if !defined(__xpv)
1512         init_cpu_id_gdt(CPU);
1513 #endif
1514 
1515         cmn_err(CE_CONT, "?cpu%d: %s\n", CPU->cpu_id, CPU->cpu_idstr);
1516         cmn_err(CE_CONT, "?cpu%d: %s\n", CPU->cpu_id, CPU->cpu_brandstr);
1517 
1518         /*
1519          * Initialize our syscall handlers
1520          */
1521         init_cpu_syscall(CPU);
1522 
1523         /*
1524          * Take the boot cpu out of the mp_cpus set because we know
1525          * it's already running.  Add it to the cpu_ready_set for
1526          * precisely the same reason.
1527          */
1528         CPUSET_DEL(mp_cpus, bootcpuid);
1529         CPUSET_ADD(cpu_ready_set, bootcpuid);
1530 
1531         /*
1532          * skip the rest of this if
1533          * . only 1 cpu dectected and system isn't hotplug-capable
1534          * . not using MP
 
 |