]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/i386/i386/mp_machdep.c
MFC r297884
[FreeBSD/stable/8.git] / sys / i386 / i386 / mp_machdep.c
1 /*-
2  * Copyright (c) 1996, by Steve Passe
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. The name of the developer may NOT be used to endorse or promote products
11  *    derived from this software without specific prior written permission.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include "opt_apic.h"
30 #include "opt_cpu.h"
31 #include "opt_kstack_pages.h"
32 #include "opt_mp_watchdog.h"
33 #include "opt_pmap.h"
34 #include "opt_sched.h"
35 #include "opt_smp.h"
36
37 #if !defined(lint)
38 #if !defined(SMP)
39 #error How did you get here?
40 #endif
41
42 #ifndef DEV_APIC
43 #error The apic device is required for SMP, add "device apic" to your config file.
44 #endif
45 #if defined(CPU_DISABLE_CMPXCHG) && !defined(COMPILING_LINT)
46 #error SMP not supported with CPU_DISABLE_CMPXCHG
47 #endif
48 #endif /* not lint */
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/bus.h>
53 #include <sys/cons.h>   /* cngetc() */
54 #ifdef GPROF 
55 #include <sys/gmon.h>
56 #endif
57 #include <sys/kernel.h>
58 #include <sys/ktr.h>
59 #include <sys/lock.h>
60 #include <sys/malloc.h>
61 #include <sys/memrange.h>
62 #include <sys/mutex.h>
63 #include <sys/pcpu.h>
64 #include <sys/proc.h>
65 #include <sys/sched.h>
66 #include <sys/smp.h>
67 #include <sys/sysctl.h>
68
69 #include <vm/vm.h>
70 #include <vm/vm_param.h>
71 #include <vm/pmap.h>
72 #include <vm/vm_kern.h>
73 #include <vm/vm_extern.h>
74
75 #include <machine/apicreg.h>
76 #include <machine/clock.h>
77 #include <machine/cputypes.h>
78 #include <machine/mca.h>
79 #include <machine/md_var.h>
80 #include <machine/mp_watchdog.h>
81 #include <machine/pcb.h>
82 #include <machine/psl.h>
83 #include <machine/smp.h>
84 #include <machine/specialreg.h>
85
86 #define WARMBOOT_TARGET         0
87 #define WARMBOOT_OFF            (KERNBASE + 0x0467)
88 #define WARMBOOT_SEG            (KERNBASE + 0x0469)
89
90 #define CMOS_REG                (0x70)
91 #define CMOS_DATA               (0x71)
92 #define BIOS_RESET              (0x0f)
93 #define BIOS_WARM               (0x0a)
94
95 /*
96  * this code MUST be enabled here and in mpboot.s.
97  * it follows the very early stages of AP boot by placing values in CMOS ram.
98  * it NORMALLY will never be needed and thus the primitive method for enabling.
99  *
100 #define CHECK_POINTS
101  */
102
103 #if defined(CHECK_POINTS) && !defined(PC98)
104 #define CHECK_READ(A)    (outb(CMOS_REG, (A)), inb(CMOS_DATA))
105 #define CHECK_WRITE(A,D) (outb(CMOS_REG, (A)), outb(CMOS_DATA, (D)))
106
107 #define CHECK_INIT(D);                          \
108         CHECK_WRITE(0x34, (D));                 \
109         CHECK_WRITE(0x35, (D));                 \
110         CHECK_WRITE(0x36, (D));                 \
111         CHECK_WRITE(0x37, (D));                 \
112         CHECK_WRITE(0x38, (D));                 \
113         CHECK_WRITE(0x39, (D));
114
115 #define CHECK_PRINT(S);                         \
116         printf("%s: %d, %d, %d, %d, %d, %d\n",  \
117            (S),                                 \
118            CHECK_READ(0x34),                    \
119            CHECK_READ(0x35),                    \
120            CHECK_READ(0x36),                    \
121            CHECK_READ(0x37),                    \
122            CHECK_READ(0x38),                    \
123            CHECK_READ(0x39));
124
125 #else                           /* CHECK_POINTS */
126
127 #define CHECK_INIT(D)
128 #define CHECK_PRINT(S)
129 #define CHECK_WRITE(A, D)
130
131 #endif                          /* CHECK_POINTS */
132
133 /* lock region used by kernel profiling */
134 int     mcount_lock;
135
136 int     mp_naps;                /* # of Applications processors */
137 int     boot_cpu_id = -1;       /* designated BSP */
138
139 extern  struct pcpu __pcpu[];
140
141 /* AP uses this during bootstrap.  Do not staticize.  */
142 char *bootSTK;
143 static int bootAP;
144
145 /* Free these after use */
146 void *bootstacks[MAXCPU];
147 static void *dpcpu;
148
149 /* Hotwire a 0->4MB V==P mapping */
150 extern pt_entry_t *KPTphys;
151
152 struct pcb stoppcbs[MAXCPU];
153
154 /* Variables needed for SMP tlb shootdown. */
155 vm_offset_t smp_tlb_addr1;
156 vm_offset_t smp_tlb_addr2;
157 volatile int smp_tlb_wait;
158
159 #ifdef COUNT_IPIS
160 /* Interrupt counts. */
161 static u_long *ipi_preempt_counts[MAXCPU];
162 static u_long *ipi_ast_counts[MAXCPU];
163 u_long *ipi_invltlb_counts[MAXCPU];
164 u_long *ipi_invlrng_counts[MAXCPU];
165 u_long *ipi_invlpg_counts[MAXCPU];
166 u_long *ipi_invlcache_counts[MAXCPU];
167 u_long *ipi_rendezvous_counts[MAXCPU];
168 u_long *ipi_lazypmap_counts[MAXCPU];
169 #endif
170
171 /*
172  * Local data and functions.
173  */
174
175 static volatile cpumask_t ipi_nmi_pending;
176
177 /* used to hold the AP's until we are ready to release them */
178 static struct mtx ap_boot_mtx;
179
180 /* Set to 1 once we're ready to let the APs out of the pen. */
181 static volatile int aps_ready = 0;
182
183 /*
184  * Store data from cpu_add() until later in the boot when we actually setup
185  * the APs.
186  */
187 struct cpu_info {
188         int     cpu_present:1;
189         int     cpu_bsp:1;
190         int     cpu_disabled:1;
191         int     cpu_hyperthread:1;
192 } static cpu_info[MAX_APIC_ID + 1];
193 int cpu_apic_ids[MAXCPU];
194 int apic_cpuids[MAX_APIC_ID + 1];
195
196 /* Holds pending bitmap based IPIs per CPU */
197 static volatile u_int cpu_ipi_pending[MAXCPU];
198
199 static u_int boot_address;
200 static int cpu_logical;                 /* logical cpus per core */
201 static int cpu_cores;                   /* cores per package */
202
203 static void     assign_cpu_ids(void);
204 static void     install_ap_tramp(void);
205 static void     set_interrupt_apic_ids(void);
206 static int      start_all_aps(void);
207 static int      start_ap(int apic_id);
208 static void     release_aps(void *dummy);
209
210 static int      hlt_logical_cpus;
211 static u_int    hyperthreading_cpus;    /* logical cpus sharing L1 cache */
212 static cpumask_t        hyperthreading_cpus_mask;
213 static int      hyperthreading_allowed = 1;
214 static struct   sysctl_ctx_list logical_cpu_clist;
215
216 static void
217 mem_range_AP_init(void)
218 {
219         if (mem_range_softc.mr_op && mem_range_softc.mr_op->initAP)
220                 mem_range_softc.mr_op->initAP(&mem_range_softc);
221 }
222
223 static void
224 topo_probe_amd(void)
225 {
226         int core_id_bits;
227         int id;
228
229         /* AMD processors do not support HTT. */
230         cpu_logical = 1;
231
232         if ((amd_feature2 & AMDID2_CMP) == 0) {
233                 cpu_cores = 1;
234                 return;
235         }
236
237         core_id_bits = (cpu_procinfo2 & AMDID_COREID_SIZE) >>
238             AMDID_COREID_SIZE_SHIFT;
239         if (core_id_bits == 0) {
240                 cpu_cores = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
241                 return;
242         }
243
244         /* Fam 10h and newer should get here. */
245         for (id = 0; id <= MAX_APIC_ID; id++) {
246                 /* Check logical CPU availability. */
247                 if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
248                         continue;
249                 /* Check if logical CPU has the same package ID. */
250                 if ((id >> core_id_bits) != (boot_cpu_id >> core_id_bits))
251                         continue;
252                 cpu_cores++;
253         }
254 }
255
256 /*
257  * Round up to the next power of two, if necessary, and then
258  * take log2.
259  * Returns -1 if argument is zero.
260  */
261 static __inline int
262 mask_width(u_int x)
263 {
264
265         return (fls(x << (1 - powerof2(x))) - 1);
266 }
267
268 static void
269 topo_probe_0x4(void)
270 {
271         u_int p[4];
272         int pkg_id_bits;
273         int core_id_bits;
274         int max_cores;
275         int max_logical;
276         int id;
277
278         /* Both zero and one here mean one logical processor per package. */
279         max_logical = (cpu_feature & CPUID_HTT) != 0 ?
280             (cpu_procinfo & CPUID_HTT_CORES) >> 16 : 1;
281         if (max_logical <= 1)
282                 return;
283
284         /*
285          * Because of uniformity assumption we examine only
286          * those logical processors that belong to the same
287          * package as BSP.  Further, we count number of
288          * logical processors that belong to the same core
289          * as BSP thus deducing number of threads per core.
290          */
291         if (cpu_high >= 0x4) {
292                 cpuid_count(0x04, 0, p);
293                 max_cores = ((p[0] >> 26) & 0x3f) + 1;
294         } else
295                 max_cores = 1;
296         core_id_bits = mask_width(max_logical/max_cores);
297         if (core_id_bits < 0)
298                 return;
299         pkg_id_bits = core_id_bits + mask_width(max_cores);
300
301         for (id = 0; id <= MAX_APIC_ID; id++) {
302                 /* Check logical CPU availability. */
303                 if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
304                         continue;
305                 /* Check if logical CPU has the same package ID. */
306                 if ((id >> pkg_id_bits) != (boot_cpu_id >> pkg_id_bits))
307                         continue;
308                 cpu_cores++;
309                 /* Check if logical CPU has the same package and core IDs. */
310                 if ((id >> core_id_bits) == (boot_cpu_id >> core_id_bits))
311                         cpu_logical++;
312         }
313
314         KASSERT(cpu_cores >= 1 && cpu_logical >= 1,
315             ("topo_probe_0x4 couldn't find BSP"));
316
317         cpu_cores /= cpu_logical;
318         hyperthreading_cpus = cpu_logical;
319 }
320
321 static void
322 topo_probe_0xb(void)
323 {
324         u_int p[4];
325         int bits;
326         int cnt;
327         int i;
328         int logical;
329         int type;
330         int x;
331
332         /* We only support three levels for now. */
333         for (i = 0; i < 3; i++) {
334                 cpuid_count(0x0b, i, p);
335
336                 /* Fall back if CPU leaf 11 doesn't really exist. */
337                 if (i == 0 && p[1] == 0) {
338                         topo_probe_0x4();
339                         return;
340                 }
341
342                 bits = p[0] & 0x1f;
343                 logical = p[1] &= 0xffff;
344                 type = (p[2] >> 8) & 0xff;
345                 if (type == 0 || logical == 0)
346                         break;
347                 /*
348                  * Because of uniformity assumption we examine only
349                  * those logical processors that belong to the same
350                  * package as BSP.
351                  */
352                 for (cnt = 0, x = 0; x <= MAX_APIC_ID; x++) {
353                         if (!cpu_info[x].cpu_present ||
354                             cpu_info[x].cpu_disabled)
355                                 continue;
356                         if (x >> bits == boot_cpu_id >> bits)
357                                 cnt++;
358                 }
359                 if (type == CPUID_TYPE_SMT)
360                         cpu_logical = cnt;
361                 else if (type == CPUID_TYPE_CORE)
362                         cpu_cores = cnt;
363         }
364         if (cpu_logical == 0)
365                 cpu_logical = 1;
366         cpu_cores /= cpu_logical;
367 }
368
369 /*
370  * Both topology discovery code and code that consumes topology
371  * information assume top-down uniformity of the topology.
372  * That is, all physical packages must be identical and each
373  * core in a package must have the same number of threads.
374  * Topology information is queried only on BSP, on which this
375  * code runs and for which it can query CPUID information.
376  * Then topology is extrapolated on all packages using the
377  * uniformity assumption.
378  */
379 static void
380 topo_probe(void)
381 {
382         static int cpu_topo_probed = 0;
383
384         if (cpu_topo_probed)
385                 return;
386
387         logical_cpus_mask = 0;
388         if (mp_ncpus <= 1)
389                 cpu_cores = cpu_logical = 1;
390         else if (cpu_vendor_id == CPU_VENDOR_AMD)
391                 topo_probe_amd();
392         else if (cpu_vendor_id == CPU_VENDOR_INTEL) {
393                 /*
394                  * See Intel(R) 64 Architecture Processor
395                  * Topology Enumeration article for details.
396                  *
397                  * Note that 0x1 <= cpu_high < 4 case should be
398                  * compatible with topo_probe_0x4() logic when
399                  * CPUID.1:EBX[23:16] > 0 (cpu_cores will be 1)
400                  * or it should trigger the fallback otherwise.
401                  */
402                 if (cpu_high >= 0xb)
403                         topo_probe_0xb();
404                 else if (cpu_high >= 0x1)
405                         topo_probe_0x4();
406         }
407
408         /*
409          * Fallback: assume each logical CPU is in separate
410          * physical package.  That is, no multi-core, no SMT.
411          */
412         if (cpu_cores == 0 || cpu_logical == 0)
413                 cpu_cores = cpu_logical = 1;
414         cpu_topo_probed = 1;
415 }
416
417 struct cpu_group *
418 cpu_topo(void)
419 {
420         int cg_flags;
421
422         /*
423          * Determine whether any threading flags are
424          * necessry.
425          */
426         topo_probe();
427         if (cpu_logical > 1 && hyperthreading_cpus)
428                 cg_flags = CG_FLAG_HTT;
429         else if (cpu_logical > 1)
430                 cg_flags = CG_FLAG_SMT;
431         else
432                 cg_flags = 0;
433         if (mp_ncpus % (cpu_cores * cpu_logical) != 0) {
434                 printf("WARNING: Non-uniform processors.\n");
435                 printf("WARNING: Using suboptimal topology.\n");
436                 return (smp_topo_none());
437         }
438         /*
439          * No multi-core or hyper-threaded.
440          */
441         if (cpu_logical * cpu_cores == 1)
442                 return (smp_topo_none());
443         /*
444          * Only HTT no multi-core.
445          */
446         if (cpu_logical > 1 && cpu_cores == 1)
447                 return (smp_topo_1level(CG_SHARE_L1, cpu_logical, cg_flags));
448         /*
449          * Only multi-core no HTT.
450          */
451         if (cpu_cores > 1 && cpu_logical == 1)
452                 return (smp_topo_1level(CG_SHARE_L2, cpu_cores, cg_flags));
453         /*
454          * Both HTT and multi-core.
455          */
456         return (smp_topo_2level(CG_SHARE_L2, cpu_cores,
457             CG_SHARE_L1, cpu_logical, cg_flags));
458 }
459
460
461 /*
462  * Calculate usable address in base memory for AP trampoline code.
463  */
464 u_int
465 mp_bootaddress(u_int basemem)
466 {
467
468         boot_address = trunc_page(basemem);     /* round down to 4k boundary */
469         if ((basemem - boot_address) < bootMP_size)
470                 boot_address -= PAGE_SIZE;      /* not enough, lower by 4k */
471
472         return boot_address;
473 }
474
475 void
476 cpu_add(u_int apic_id, char boot_cpu)
477 {
478
479         if (apic_id > MAX_APIC_ID) {
480                 panic("SMP: APIC ID %d too high", apic_id);
481                 return;
482         }
483         KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
484             apic_id));
485         cpu_info[apic_id].cpu_present = 1;
486         if (boot_cpu) {
487                 KASSERT(boot_cpu_id == -1,
488                     ("CPU %d claims to be BSP, but CPU %d already is", apic_id,
489                     boot_cpu_id));
490                 boot_cpu_id = apic_id;
491                 cpu_info[apic_id].cpu_bsp = 1;
492         }
493         if (mp_ncpus < MAXCPU)
494                 mp_ncpus++;
495         if (bootverbose)
496                 printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
497                     "AP");
498 }
499
500 void
501 cpu_mp_setmaxid(void)
502 {
503
504         mp_maxid = MAXCPU - 1;
505 }
506
507 int
508 cpu_mp_probe(void)
509 {
510
511         /*
512          * Always record BSP in CPU map so that the mbuf init code works
513          * correctly.
514          */
515         all_cpus = 1;
516         if (mp_ncpus == 0) {
517                 /*
518                  * No CPUs were found, so this must be a UP system.  Setup
519                  * the variables to represent a system with a single CPU
520                  * with an id of 0.
521                  */
522                 mp_ncpus = 1;
523                 return (0);
524         }
525
526         /* At least one CPU was found. */
527         if (mp_ncpus == 1) {
528                 /*
529                  * One CPU was found, so this must be a UP system with
530                  * an I/O APIC.
531                  */
532                 return (0);
533         }
534
535         /* At least two CPUs were found. */
536         return (1);
537 }
538
539 /*
540  * Initialize the IPI handlers and start up the AP's.
541  */
542 void
543 cpu_mp_start(void)
544 {
545         int i;
546
547         /* Initialize the logical ID to APIC ID table. */
548         for (i = 0; i < MAXCPU; i++) {
549                 cpu_apic_ids[i] = -1;
550                 cpu_ipi_pending[i] = 0;
551         }
552
553         /* Install an inter-CPU IPI for TLB invalidation */
554         setidt(IPI_INVLTLB, IDTVEC(invltlb),
555                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
556         setidt(IPI_INVLPG, IDTVEC(invlpg),
557                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
558         setidt(IPI_INVLRNG, IDTVEC(invlrng),
559                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
560
561         /* Install an inter-CPU IPI for cache invalidation. */
562         setidt(IPI_INVLCACHE, IDTVEC(invlcache),
563                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
564
565         /* Install an inter-CPU IPI for lazy pmap release */
566         setidt(IPI_LAZYPMAP, IDTVEC(lazypmap),
567                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
568
569         /* Install an inter-CPU IPI for all-CPU rendezvous */
570         setidt(IPI_RENDEZVOUS, IDTVEC(rendezvous),
571                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
572
573         /* Install generic inter-CPU IPI handler */
574         setidt(IPI_BITMAP_VECTOR, IDTVEC(ipi_intr_bitmap_handler),
575                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
576
577         /* Install an inter-CPU IPI for CPU stop/restart */
578         setidt(IPI_STOP, IDTVEC(cpustop),
579                SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
580
581
582         /* Set boot_cpu_id if needed. */
583         if (boot_cpu_id == -1) {
584                 boot_cpu_id = PCPU_GET(apic_id);
585                 cpu_info[boot_cpu_id].cpu_bsp = 1;
586         } else
587                 KASSERT(boot_cpu_id == PCPU_GET(apic_id),
588                     ("BSP's APIC ID doesn't match boot_cpu_id"));
589
590         /* Probe logical/physical core configuration. */
591         topo_probe();
592
593         assign_cpu_ids();
594
595         /* Start each Application Processor */
596         start_all_aps();
597
598         set_interrupt_apic_ids();
599 }
600
601
602 /*
603  * Print various information about the SMP system hardware and setup.
604  */
605 void
606 cpu_mp_announce(void)
607 {
608         const char *hyperthread;
609         int i;
610
611         printf("FreeBSD/SMP: %d package(s) x %d core(s)",
612             mp_ncpus / (cpu_cores * cpu_logical), cpu_cores);
613         if (hyperthreading_cpus > 1)
614             printf(" x %d HTT threads", cpu_logical);
615         else if (cpu_logical > 1)
616             printf(" x %d SMT threads", cpu_logical);
617         printf("\n");
618
619         /* List active CPUs first. */
620         printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
621         for (i = 1; i < mp_ncpus; i++) {
622                 if (cpu_info[cpu_apic_ids[i]].cpu_hyperthread)
623                         hyperthread = "/HT";
624                 else
625                         hyperthread = "";
626                 printf(" cpu%d (AP%s): APIC ID: %2d\n", i, hyperthread,
627                     cpu_apic_ids[i]);
628         }
629
630         /* List disabled CPUs last. */
631         for (i = 0; i <= MAX_APIC_ID; i++) {
632                 if (!cpu_info[i].cpu_present || !cpu_info[i].cpu_disabled)
633                         continue;
634                 if (cpu_info[i].cpu_hyperthread)
635                         hyperthread = "/HT";
636                 else
637                         hyperthread = "";
638                 printf("  cpu (AP%s): APIC ID: %2d (disabled)\n", hyperthread,
639                     i);
640         }
641 }
642
643 /*
644  * AP CPU's call this to initialize themselves.
645  */
646 void
647 init_secondary(void)
648 {
649         struct pcpu *pc;
650         vm_offset_t addr;
651         int     gsel_tss;
652         int     x, myid;
653         u_int   cr0;
654
655         /* bootAP is set in start_ap() to our ID. */
656         myid = bootAP;
657
658         /* Get per-cpu data */
659         pc = &__pcpu[myid];
660
661         /* prime data page for it to use */
662         pcpu_init(pc, myid, sizeof(struct pcpu));
663         dpcpu_init(dpcpu, myid);
664         pc->pc_apic_id = cpu_apic_ids[myid];
665         pc->pc_prvspace = pc;
666         pc->pc_curthread = 0;
667
668         gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
669         gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
670
671         for (x = 0; x < NGDT; x++) {
672                 ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
673         }
674
675         r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
676         r_gdt.rd_base = (int) &gdt[myid * NGDT];
677         lgdt(&r_gdt);                   /* does magic intra-segment return */
678
679         lidt(&r_idt);
680
681         lldt(_default_ldt);
682         PCPU_SET(currentldt, _default_ldt);
683
684         gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
685         gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS;
686         PCPU_SET(common_tss.tss_esp0, 0); /* not used until after switch */
687         PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
688         PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16);
689         PCPU_SET(tss_gdt, &gdt[myid * NGDT + GPROC0_SEL].sd);
690         PCPU_SET(common_tssd, *PCPU_GET(tss_gdt));
691         ltr(gsel_tss);
692
693         PCPU_SET(fsgs_gdt, &gdt[myid * NGDT + GUFS_SEL].sd);
694
695         /*
696          * Set to a known state:
697          * Set by mpboot.s: CR0_PG, CR0_PE
698          * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
699          */
700         cr0 = rcr0();
701         cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
702         load_cr0(cr0);
703         CHECK_WRITE(0x38, 5);
704         
705         /* Disable local APIC just to be sure. */
706         lapic_disable();
707
708         /* signal our startup to the BSP. */
709         mp_naps++;
710         CHECK_WRITE(0x39, 6);
711
712         /* Spin until the BSP releases the AP's. */
713         while (!aps_ready)
714                 ia32_pause();
715
716         /* BSP may have changed PTD while we were waiting */
717         invltlb();
718         for (addr = 0; addr < NKPT * NBPDR - 1; addr += PAGE_SIZE)
719                 invlpg(addr);
720
721 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
722         lidt(&r_idt);
723 #endif
724
725         /* Initialize the PAT MSR if present. */
726         pmap_init_pat();
727
728         /* set up CPU registers and state */
729         cpu_setregs();
730
731         /* set up FPU state on the AP */
732         npxinit();
733
734         /* set up SSE registers */
735         enable_sse();
736
737 #ifdef PAE
738         /* Enable the PTE no-execute bit. */
739         if ((amd_feature & AMDID_NX) != 0) {
740                 uint64_t msr;
741
742                 msr = rdmsr(MSR_EFER) | EFER_NXE;
743                 wrmsr(MSR_EFER, msr);
744         }
745 #endif
746
747         /* A quick check from sanity claus */
748         if (PCPU_GET(apic_id) != lapic_id()) {
749                 printf("SMP: cpuid = %d\n", PCPU_GET(cpuid));
750                 printf("SMP: actual apic_id = %d\n", lapic_id());
751                 printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
752                 panic("cpuid mismatch! boom!!");
753         }
754
755         /* Initialize curthread. */
756         KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
757         PCPU_SET(curthread, PCPU_GET(idlethread));
758
759         mca_init();
760
761         mtx_lock_spin(&ap_boot_mtx);
762
763         /* Init local apic for irq's */
764         lapic_setup(1);
765
766         /* Set memory range attributes for this CPU to match the BSP */
767         mem_range_AP_init();
768
769         smp_cpus++;
770
771         CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", PCPU_GET(cpuid));
772         printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid));
773
774         /* Determine if we are a logical CPU. */
775         /* XXX Calculation depends on cpu_logical being a power of 2, e.g. 2 */
776         if (cpu_logical > 1 && PCPU_GET(apic_id) % cpu_logical != 0)
777                 logical_cpus_mask |= PCPU_GET(cpumask);
778         
779         /* Determine if we are a hyperthread. */
780         if (hyperthreading_cpus > 1 &&
781             PCPU_GET(apic_id) % hyperthreading_cpus != 0)
782                 hyperthreading_cpus_mask |= PCPU_GET(cpumask);
783
784         /* Build our map of 'other' CPUs. */
785         PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
786
787         if (bootverbose)
788                 lapic_dump("AP");
789
790         if (smp_cpus == mp_ncpus) {
791                 /* enable IPI's, tlb shootdown, freezes etc */
792                 atomic_store_rel_int(&smp_started, 1);
793                 smp_active = 1;  /* historic */
794         }
795
796         mtx_unlock_spin(&ap_boot_mtx);
797
798         /* wait until all the AP's are up */
799         while (smp_started == 0)
800                 ia32_pause();
801
802         /* enter the scheduler */
803         sched_throw(NULL);
804
805         panic("scheduler returned us to %s", __func__);
806         /* NOTREACHED */
807 }
808
809 /*******************************************************************
810  * local functions and data
811  */
812
813 /*
814  * We tell the I/O APIC code about all the CPUs we want to receive
815  * interrupts.  If we don't want certain CPUs to receive IRQs we
816  * can simply not tell the I/O APIC code about them in this function.
817  * We also do not tell it about the BSP since it tells itself about
818  * the BSP internally to work with UP kernels and on UP machines.
819  */
820 static void
821 set_interrupt_apic_ids(void)
822 {
823         u_int i, apic_id;
824
825         for (i = 0; i < MAXCPU; i++) {
826                 apic_id = cpu_apic_ids[i];
827                 if (apic_id == -1)
828                         continue;
829                 if (cpu_info[apic_id].cpu_bsp)
830                         continue;
831                 if (cpu_info[apic_id].cpu_disabled)
832                         continue;
833
834                 /* Don't let hyperthreads service interrupts. */
835                 if (hyperthreading_cpus > 1 &&
836                     apic_id % hyperthreading_cpus != 0)
837                         continue;
838
839                 intr_add_cpu(i);
840         }
841 }
842
843 /*
844  * Assign logical CPU IDs to local APICs.
845  */
846 static void
847 assign_cpu_ids(void)
848 {
849         u_int i;
850
851         TUNABLE_INT_FETCH("machdep.hyperthreading_allowed",
852             &hyperthreading_allowed);
853
854         /* Check for explicitly disabled CPUs. */
855         for (i = 0; i <= MAX_APIC_ID; i++) {
856                 if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
857                         continue;
858
859                 if (hyperthreading_cpus > 1 && i % hyperthreading_cpus != 0) {
860                         cpu_info[i].cpu_hyperthread = 1;
861 #if defined(SCHED_ULE)
862                         /*
863                          * Don't use HT CPU if it has been disabled by a
864                          * tunable.
865                          */
866                         if (hyperthreading_allowed == 0) {
867                                 cpu_info[i].cpu_disabled = 1;
868                                 continue;
869                         }
870 #endif
871                 }
872
873                 /* Don't use this CPU if it has been disabled by a tunable. */
874                 if (resource_disabled("lapic", i)) {
875                         cpu_info[i].cpu_disabled = 1;
876                         continue;
877                 }
878         }
879
880         /*
881          * Assign CPU IDs to local APIC IDs and disable any CPUs
882          * beyond MAXCPU.  CPU 0 is always assigned to the BSP.
883          *
884          * To minimize confusion for userland, we attempt to number
885          * CPUs such that all threads and cores in a package are
886          * grouped together.  For now we assume that the BSP is always
887          * the first thread in a package and just start adding APs
888          * starting with the BSP's APIC ID.
889          */
890         mp_ncpus = 1;
891         cpu_apic_ids[0] = boot_cpu_id;
892         apic_cpuids[boot_cpu_id] = 0;
893         for (i = boot_cpu_id + 1; i != boot_cpu_id;
894              i == MAX_APIC_ID ? i = 0 : i++) {
895                 if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
896                     cpu_info[i].cpu_disabled)
897                         continue;
898
899                 if (mp_ncpus < MAXCPU) {
900                         cpu_apic_ids[mp_ncpus] = i;
901                         apic_cpuids[i] = mp_ncpus;
902                         mp_ncpus++;
903                 } else
904                         cpu_info[i].cpu_disabled = 1;
905         }
906         KASSERT(mp_maxid >= mp_ncpus - 1,
907             ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
908             mp_ncpus));         
909 }
910
911 /*
912  * start each AP in our list
913  */
914 /* Lowest 1MB is already mapped: don't touch*/
915 #define TMPMAP_START 1
916 static int
917 start_all_aps(void)
918 {
919 #ifndef PC98
920         u_char mpbiosreason;
921 #endif
922         uintptr_t kptbase;
923         u_int32_t mpbioswarmvec;
924         int apic_id, cpu, i;
925
926         mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
927
928         /* install the AP 1st level boot code */
929         install_ap_tramp();
930
931         /* save the current value of the warm-start vector */
932         mpbioswarmvec = *((u_int32_t *) WARMBOOT_OFF);
933 #ifndef PC98
934         outb(CMOS_REG, BIOS_RESET);
935         mpbiosreason = inb(CMOS_DATA);
936 #endif
937
938         /* set up temporary P==V mapping for AP boot */
939         /* XXX this is a hack, we should boot the AP on its own stack/PTD */
940
941         kptbase = (uintptr_t)(void *)KPTphys;
942         for (i = TMPMAP_START; i < NKPT; i++)
943                 PTD[i] = (pd_entry_t)(PG_V | PG_RW |
944                     ((kptbase + i * PAGE_SIZE) & PG_FRAME));
945         invltlb();
946
947         /* start each AP */
948         for (cpu = 1; cpu < mp_ncpus; cpu++) {
949                 apic_id = cpu_apic_ids[cpu];
950
951                 /* allocate and set up a boot stack data page */
952                 bootstacks[cpu] =
953                     (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
954                 dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
955                 /* setup a vector to our boot code */
956                 *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
957                 *((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4);
958 #ifndef PC98
959                 outb(CMOS_REG, BIOS_RESET);
960                 outb(CMOS_DATA, BIOS_WARM);     /* 'warm-start' */
961 #endif
962
963                 bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 4;
964                 bootAP = cpu;
965
966                 /* attempt to start the Application Processor */
967                 CHECK_INIT(99); /* setup checkpoints */
968                 if (!start_ap(apic_id)) {
969                         printf("AP #%d (PHY# %d) failed!\n", cpu, apic_id);
970                         CHECK_PRINT("trace");   /* show checkpoints */
971                         /* better panic as the AP may be running loose */
972                         printf("panic y/n? [y] ");
973                         if (cngetc() != 'n')
974                                 panic("bye-bye");
975                 }
976                 CHECK_PRINT("trace");           /* show checkpoints */
977
978                 all_cpus |= (1 << cpu);         /* record AP in CPU map */
979         }
980
981         /* build our map of 'other' CPUs */
982         PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
983
984         /* restore the warmstart vector */
985         *(u_int32_t *) WARMBOOT_OFF = mpbioswarmvec;
986
987 #ifndef PC98
988         outb(CMOS_REG, BIOS_RESET);
989         outb(CMOS_DATA, mpbiosreason);
990 #endif
991
992         /* Undo V==P hack from above */
993         for (i = TMPMAP_START; i < NKPT; i++)
994                 PTD[i] = 0;
995         pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1);
996
997         /* number of APs actually started */
998         return mp_naps;
999 }
1000
1001 /*
1002  * load the 1st level AP boot code into base memory.
1003  */
1004
1005 /* targets for relocation */
1006 extern void bigJump(void);
1007 extern void bootCodeSeg(void);
1008 extern void bootDataSeg(void);
1009 extern void MPentry(void);
1010 extern u_int MP_GDT;
1011 extern u_int mp_gdtbase;
1012
1013 static void
1014 install_ap_tramp(void)
1015 {
1016         int     x;
1017         int     size = *(int *) ((u_long) & bootMP_size);
1018         vm_offset_t va = boot_address + KERNBASE;
1019         u_char *src = (u_char *) ((u_long) bootMP);
1020         u_char *dst = (u_char *) va;
1021         u_int   boot_base = (u_int) bootMP;
1022         u_int8_t *dst8;
1023         u_int16_t *dst16;
1024         u_int32_t *dst32;
1025
1026         KASSERT (size <= PAGE_SIZE,
1027             ("'size' do not fit into PAGE_SIZE, as expected."));
1028         pmap_kenter(va, boot_address);
1029         pmap_invalidate_page (kernel_pmap, va);
1030         for (x = 0; x < size; ++x)
1031                 *dst++ = *src++;
1032
1033         /*
1034          * modify addresses in code we just moved to basemem. unfortunately we
1035          * need fairly detailed info about mpboot.s for this to work.  changes
1036          * to mpboot.s might require changes here.
1037          */
1038
1039         /* boot code is located in KERNEL space */
1040         dst = (u_char *) va;
1041
1042         /* modify the lgdt arg */
1043         dst32 = (u_int32_t *) (dst + ((u_int) & mp_gdtbase - boot_base));
1044         *dst32 = boot_address + ((u_int) & MP_GDT - boot_base);
1045
1046         /* modify the ljmp target for MPentry() */
1047         dst32 = (u_int32_t *) (dst + ((u_int) bigJump - boot_base) + 1);
1048         *dst32 = ((u_int) MPentry - KERNBASE);
1049
1050         /* modify the target for boot code segment */
1051         dst16 = (u_int16_t *) (dst + ((u_int) bootCodeSeg - boot_base));
1052         dst8 = (u_int8_t *) (dst16 + 1);
1053         *dst16 = (u_int) boot_address & 0xffff;
1054         *dst8 = ((u_int) boot_address >> 16) & 0xff;
1055
1056         /* modify the target for boot data segment */
1057         dst16 = (u_int16_t *) (dst + ((u_int) bootDataSeg - boot_base));
1058         dst8 = (u_int8_t *) (dst16 + 1);
1059         *dst16 = (u_int) boot_address & 0xffff;
1060         *dst8 = ((u_int) boot_address >> 16) & 0xff;
1061 }
1062
1063 /*
1064  * This function starts the AP (application processor) identified
1065  * by the APIC ID 'physicalCpu'.  It does quite a "song and dance"
1066  * to accomplish this.  This is necessary because of the nuances
1067  * of the different hardware we might encounter.  It isn't pretty,
1068  * but it seems to work.
1069  */
1070 static int
1071 start_ap(int apic_id)
1072 {
1073         int vector, ms;
1074         int cpus;
1075
1076         /* calculate the vector */
1077         vector = (boot_address >> 12) & 0xff;
1078
1079         /* used as a watchpoint to signal AP startup */
1080         cpus = mp_naps;
1081
1082         /*
1083          * first we do an INIT/RESET IPI this INIT IPI might be run, reseting
1084          * and running the target CPU. OR this INIT IPI might be latched (P5
1085          * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be
1086          * ignored.
1087          */
1088
1089         /* do an INIT IPI: assert RESET */
1090         lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
1091             APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id);
1092
1093         /* wait for pending status end */
1094         lapic_ipi_wait(-1);
1095
1096         /* do an INIT IPI: deassert RESET */
1097         lapic_ipi_raw(APIC_DEST_ALLESELF | APIC_TRIGMOD_LEVEL |
1098             APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, 0);
1099
1100         /* wait for pending status end */
1101         DELAY(10000);           /* wait ~10mS */
1102         lapic_ipi_wait(-1);
1103
1104         /*
1105          * next we do a STARTUP IPI: the previous INIT IPI might still be
1106          * latched, (P5 bug) this 1st STARTUP would then terminate
1107          * immediately, and the previously started INIT IPI would continue. OR
1108          * the previous INIT IPI has already run. and this STARTUP IPI will
1109          * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
1110          * will run.
1111          */
1112
1113         /* do a STARTUP IPI */
1114         lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
1115             APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
1116             vector, apic_id);
1117         lapic_ipi_wait(-1);
1118         DELAY(200);             /* wait ~200uS */
1119
1120         /*
1121          * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
1122          * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
1123          * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
1124          * recognized after hardware RESET or INIT IPI.
1125          */
1126
1127         lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
1128             APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
1129             vector, apic_id);
1130         lapic_ipi_wait(-1);
1131         DELAY(200);             /* wait ~200uS */
1132
1133         /* Wait up to 5 seconds for it to start. */
1134         for (ms = 0; ms < 5000; ms++) {
1135                 if (mp_naps > cpus)
1136                         return 1;       /* return SUCCESS */
1137                 DELAY(1000);
1138         }
1139         return 0;               /* return FAILURE */
1140 }
1141
1142 #ifdef COUNT_XINVLTLB_HITS
1143 u_int xhits_gbl[MAXCPU];
1144 u_int xhits_pg[MAXCPU];
1145 u_int xhits_rng[MAXCPU];
1146 SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
1147 SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
1148     sizeof(xhits_gbl), "IU", "");
1149 SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
1150     sizeof(xhits_pg), "IU", "");
1151 SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
1152     sizeof(xhits_rng), "IU", "");
1153
1154 u_int ipi_global;
1155 u_int ipi_page;
1156 u_int ipi_range;
1157 u_int ipi_range_size;
1158 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
1159 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
1160 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
1161 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW, &ipi_range_size,
1162     0, "");
1163
1164 u_int ipi_masked_global;
1165 u_int ipi_masked_page;
1166 u_int ipi_masked_range;
1167 u_int ipi_masked_range_size;
1168 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
1169     &ipi_masked_global, 0, "");
1170 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
1171     &ipi_masked_page, 0, "");
1172 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
1173     &ipi_masked_range, 0, "");
1174 SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
1175     &ipi_masked_range_size, 0, "");
1176 #endif /* COUNT_XINVLTLB_HITS */
1177
1178 /*
1179  * Flush the TLB on all other CPU's
1180  */
1181 static void
1182 smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2)
1183 {
1184         u_int ncpu;
1185
1186         ncpu = mp_ncpus - 1;    /* does not shootdown self */
1187         if (ncpu < 1)
1188                 return;         /* no other cpus */
1189         if (!(read_eflags() & PSL_I))
1190                 panic("%s: interrupts disabled", __func__);
1191         mtx_lock_spin(&smp_ipi_mtx);
1192         smp_tlb_addr1 = addr1;
1193         smp_tlb_addr2 = addr2;
1194         atomic_store_rel_int(&smp_tlb_wait, 0);
1195         ipi_all_but_self(vector);
1196         while (smp_tlb_wait < ncpu)
1197                 ia32_pause();
1198         mtx_unlock_spin(&smp_ipi_mtx);
1199 }
1200
1201 static void
1202 smp_targeted_tlb_shootdown(cpumask_t mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2)
1203 {
1204         int ncpu, othercpus;
1205
1206         othercpus = mp_ncpus - 1;
1207         if (mask == (u_int)-1) {
1208                 ncpu = othercpus;
1209                 if (ncpu < 1)
1210                         return;
1211         } else {
1212                 mask &= ~PCPU_GET(cpumask);
1213                 if (mask == 0)
1214                         return;
1215                 ncpu = bitcount32(mask);
1216                 if (ncpu > othercpus) {
1217                         /* XXX this should be a panic offence */
1218                         printf("SMP: tlb shootdown to %d other cpus (only have %d)\n",
1219                             ncpu, othercpus);
1220                         ncpu = othercpus;
1221                 }
1222                 /* XXX should be a panic, implied by mask == 0 above */
1223                 if (ncpu < 1)
1224                         return;
1225         }
1226         if (!(read_eflags() & PSL_I))
1227                 panic("%s: interrupts disabled", __func__);
1228         mtx_lock_spin(&smp_ipi_mtx);
1229         smp_tlb_addr1 = addr1;
1230         smp_tlb_addr2 = addr2;
1231         atomic_store_rel_int(&smp_tlb_wait, 0);
1232         if (mask == (u_int)-1)
1233                 ipi_all_but_self(vector);
1234         else
1235                 ipi_selected(mask, vector);
1236         while (smp_tlb_wait < ncpu)
1237                 ia32_pause();
1238         mtx_unlock_spin(&smp_ipi_mtx);
1239 }
1240
1241 /*
1242  * Send an IPI to specified CPU handling the bitmap logic.
1243  */
1244 static void
1245 ipi_send_cpu(int cpu, u_int ipi)
1246 {
1247         u_int bitmap, old_pending, new_pending;
1248
1249         KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu));
1250
1251         if (IPI_IS_BITMAPED(ipi)) {
1252                 bitmap = 1 << ipi;
1253                 ipi = IPI_BITMAP_VECTOR;
1254                 do {
1255                         old_pending = cpu_ipi_pending[cpu];
1256                         new_pending = old_pending | bitmap;
1257                 } while  (!atomic_cmpset_int(&cpu_ipi_pending[cpu],
1258                     old_pending, new_pending)); 
1259                 if (old_pending)
1260                         return;
1261         }
1262         lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]);
1263 }
1264
1265 void
1266 smp_cache_flush(void)
1267 {
1268
1269         if (smp_started)
1270                 smp_tlb_shootdown(IPI_INVLCACHE, 0, 0);
1271 }
1272
1273 void
1274 smp_invltlb(void)
1275 {
1276
1277         if (smp_started) {
1278                 smp_tlb_shootdown(IPI_INVLTLB, 0, 0);
1279 #ifdef COUNT_XINVLTLB_HITS
1280                 ipi_global++;
1281 #endif
1282         }
1283 }
1284
1285 void
1286 smp_invlpg(vm_offset_t addr)
1287 {
1288
1289         if (smp_started) {
1290                 smp_tlb_shootdown(IPI_INVLPG, addr, 0);
1291 #ifdef COUNT_XINVLTLB_HITS
1292                 ipi_page++;
1293 #endif
1294         }
1295 }
1296
1297 void
1298 smp_invlpg_range(vm_offset_t addr1, vm_offset_t addr2)
1299 {
1300
1301         if (smp_started) {
1302                 smp_tlb_shootdown(IPI_INVLRNG, addr1, addr2);
1303 #ifdef COUNT_XINVLTLB_HITS
1304                 ipi_range++;
1305                 ipi_range_size += (addr2 - addr1) / PAGE_SIZE;
1306 #endif
1307         }
1308 }
1309
1310 void
1311 smp_masked_invltlb(cpumask_t mask)
1312 {
1313
1314         if (smp_started) {
1315                 smp_targeted_tlb_shootdown(mask, IPI_INVLTLB, 0, 0);
1316 #ifdef COUNT_XINVLTLB_HITS
1317                 ipi_masked_global++;
1318 #endif
1319         }
1320 }
1321
1322 void
1323 smp_masked_invlpg(cpumask_t mask, vm_offset_t addr)
1324 {
1325
1326         if (smp_started) {
1327                 smp_targeted_tlb_shootdown(mask, IPI_INVLPG, addr, 0);
1328 #ifdef COUNT_XINVLTLB_HITS
1329                 ipi_masked_page++;
1330 #endif
1331         }
1332 }
1333
1334 void
1335 smp_masked_invlpg_range(cpumask_t mask, vm_offset_t addr1, vm_offset_t addr2)
1336 {
1337
1338         if (smp_started) {
1339                 smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, addr1, addr2);
1340 #ifdef COUNT_XINVLTLB_HITS
1341                 ipi_masked_range++;
1342                 ipi_masked_range_size += (addr2 - addr1) / PAGE_SIZE;
1343 #endif
1344         }
1345 }
1346
1347 void
1348 ipi_bitmap_handler(struct trapframe frame)
1349 {
1350         int cpu = PCPU_GET(cpuid);
1351         u_int ipi_bitmap;
1352
1353         ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
1354
1355         if (ipi_bitmap & (1 << IPI_PREEMPT)) {
1356 #ifdef COUNT_IPIS
1357                 (*ipi_preempt_counts[cpu])++;
1358 #endif
1359                 sched_preempt(curthread);
1360         }
1361
1362         if (ipi_bitmap & (1 << IPI_AST)) {
1363 #ifdef COUNT_IPIS
1364                 (*ipi_ast_counts[cpu])++;
1365 #endif
1366                 /* Nothing to do for AST */
1367         }
1368
1369         if (ipi_bitmap & (1 << IPI_HARDCLOCK))
1370                 hardclockintr(&frame); 
1371
1372         if (ipi_bitmap & (1 << IPI_STATCLOCK))
1373                 statclockintr(&frame); 
1374
1375         if (ipi_bitmap & (1 << IPI_PROFCLOCK))
1376                 profclockintr(&frame);
1377 }
1378
1379 /*
1380  * send an IPI to a set of cpus.
1381  */
1382 void
1383 ipi_selected(cpumask_t cpus, u_int ipi)
1384 {
1385         int cpu;
1386
1387         /*
1388          * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
1389          * of help in order to understand what is the source.
1390          * Set the mask of receiving CPUs for this purpose.
1391          */
1392         if (ipi == IPI_STOP_HARD)
1393                 atomic_set_int(&ipi_nmi_pending, cpus);
1394
1395         CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi);
1396         while ((cpu = ffs(cpus)) != 0) {
1397                 cpu--;
1398                 cpus &= ~(1 << cpu);
1399                 ipi_send_cpu(cpu, ipi);
1400         }
1401 }
1402
1403 /*
1404  * send an IPI to a specific CPU.
1405  */
1406 void
1407 ipi_cpu(int cpu, u_int ipi)
1408 {
1409
1410         /*
1411          * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
1412          * of help in order to understand what is the source.
1413          * Set the mask of receiving CPUs for this purpose.
1414          */
1415         if (ipi == IPI_STOP_HARD)
1416                 atomic_set_int(&ipi_nmi_pending, 1 << cpu);
1417
1418         CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
1419         ipi_send_cpu(cpu, ipi);
1420 }
1421
1422 /*
1423  * send an IPI to all CPUs EXCEPT myself
1424  */
1425 void
1426 ipi_all_but_self(u_int ipi)
1427 {
1428
1429         if (IPI_IS_BITMAPED(ipi)) {
1430                 ipi_selected(PCPU_GET(other_cpus), ipi);
1431                 return;
1432         }
1433
1434         /*
1435          * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
1436          * of help in order to understand what is the source.
1437          * Set the mask of receiving CPUs for this purpose.
1438          */
1439         if (ipi == IPI_STOP_HARD)
1440                 atomic_set_int(&ipi_nmi_pending, PCPU_GET(other_cpus));
1441         CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
1442         lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
1443 }
1444
1445 int
1446 ipi_nmi_handler()
1447 {
1448         cpumask_t cpumask;
1449
1450         /*
1451          * As long as there is not a simple way to know about a NMI's
1452          * source, if the bitmask for the current CPU is present in
1453          * the global pending bitword an IPI_STOP_HARD has been issued
1454          * and should be handled.
1455          */
1456         cpumask = PCPU_GET(cpumask);
1457         if ((ipi_nmi_pending & cpumask) == 0)
1458                 return (1);
1459
1460         atomic_clear_int(&ipi_nmi_pending, cpumask);
1461         cpustop_handler();
1462         return (0);
1463 }
1464
1465 /*
1466  * Handle an IPI_STOP by saving our current context and spinning until we
1467  * are resumed.
1468  */
1469 void
1470 cpustop_handler(void)
1471 {
1472         cpumask_t cpumask;
1473         u_int cpu;
1474
1475         cpu = PCPU_GET(cpuid);
1476         cpumask = PCPU_GET(cpumask);
1477
1478         savectx(&stoppcbs[cpu]);
1479
1480         /* Indicate that we are stopped */
1481         atomic_set_int(&stopped_cpus, cpumask);
1482
1483         /* Wait for restart */
1484         while (!(started_cpus & cpumask))
1485             ia32_pause();
1486
1487         atomic_clear_int(&started_cpus, cpumask);
1488         atomic_clear_int(&stopped_cpus, cpumask);
1489
1490         if (cpu == 0 && cpustop_restartfunc != NULL) {
1491                 cpustop_restartfunc();
1492                 cpustop_restartfunc = NULL;
1493         }
1494 }
1495
1496 /*
1497  * This is called once the rest of the system is up and running and we're
1498  * ready to let the AP's out of the pen.
1499  */
1500 static void
1501 release_aps(void *dummy __unused)
1502 {
1503
1504         if (mp_ncpus == 1) 
1505                 return;
1506         atomic_store_rel_int(&aps_ready, 1);
1507         while (smp_started == 0)
1508                 ia32_pause();
1509 }
1510 SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
1511
1512 static int
1513 sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS)
1514 {
1515         cpumask_t mask;
1516         int error;
1517
1518         mask = hlt_cpus_mask;
1519         error = sysctl_handle_int(oidp, &mask, 0, req);
1520         if (error || !req->newptr)
1521                 return (error);
1522
1523         if (logical_cpus_mask != 0 &&
1524             (mask & logical_cpus_mask) == logical_cpus_mask)
1525                 hlt_logical_cpus = 1;
1526         else
1527                 hlt_logical_cpus = 0;
1528
1529         if (! hyperthreading_allowed)
1530                 mask |= hyperthreading_cpus_mask;
1531
1532         if ((mask & all_cpus) == all_cpus)
1533                 mask &= ~(1<<0);
1534         hlt_cpus_mask = mask;
1535         return (error);
1536 }
1537 SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW,
1538     0, 0, sysctl_hlt_cpus, "IU",
1539     "Bitmap of CPUs to halt.  101 (binary) will halt CPUs 0 and 2.");
1540
1541 static int
1542 sysctl_hlt_logical_cpus(SYSCTL_HANDLER_ARGS)
1543 {
1544         int disable, error;
1545
1546         disable = hlt_logical_cpus;
1547         error = sysctl_handle_int(oidp, &disable, 0, req);
1548         if (error || !req->newptr)
1549                 return (error);
1550
1551         if (disable)
1552                 hlt_cpus_mask |= logical_cpus_mask;
1553         else
1554                 hlt_cpus_mask &= ~logical_cpus_mask;
1555
1556         if (! hyperthreading_allowed)
1557                 hlt_cpus_mask |= hyperthreading_cpus_mask;
1558
1559         if ((hlt_cpus_mask & all_cpus) == all_cpus)
1560                 hlt_cpus_mask &= ~(1<<0);
1561
1562         hlt_logical_cpus = disable;
1563         return (error);
1564 }
1565
1566 static int
1567 sysctl_hyperthreading_allowed(SYSCTL_HANDLER_ARGS)
1568 {
1569         int allowed, error;
1570
1571         allowed = hyperthreading_allowed;
1572         error = sysctl_handle_int(oidp, &allowed, 0, req);
1573         if (error || !req->newptr)
1574                 return (error);
1575
1576 #ifdef SCHED_ULE
1577         /*
1578          * SCHED_ULE doesn't allow enabling/disabling HT cores at
1579          * run-time.
1580          */
1581         if (allowed != hyperthreading_allowed)
1582                 return (ENOTSUP);
1583         return (error);
1584 #endif
1585
1586         if (allowed)
1587                 hlt_cpus_mask &= ~hyperthreading_cpus_mask;
1588         else
1589                 hlt_cpus_mask |= hyperthreading_cpus_mask;
1590
1591         if (logical_cpus_mask != 0 &&
1592             (hlt_cpus_mask & logical_cpus_mask) == logical_cpus_mask)
1593                 hlt_logical_cpus = 1;
1594         else
1595                 hlt_logical_cpus = 0;
1596
1597         if ((hlt_cpus_mask & all_cpus) == all_cpus)
1598                 hlt_cpus_mask &= ~(1<<0);
1599
1600         hyperthreading_allowed = allowed;
1601         return (error);
1602 }
1603
1604 static void
1605 cpu_hlt_setup(void *dummy __unused)
1606 {
1607
1608         if (logical_cpus_mask != 0) {
1609                 TUNABLE_INT_FETCH("machdep.hlt_logical_cpus",
1610                     &hlt_logical_cpus);
1611                 sysctl_ctx_init(&logical_cpu_clist);
1612                 SYSCTL_ADD_PROC(&logical_cpu_clist,
1613                     SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO,
1614                     "hlt_logical_cpus", CTLTYPE_INT|CTLFLAG_RW, 0, 0,
1615                     sysctl_hlt_logical_cpus, "IU", "");
1616                 SYSCTL_ADD_UINT(&logical_cpu_clist,
1617                     SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO,
1618                     "logical_cpus_mask", CTLTYPE_INT|CTLFLAG_RD,
1619                     &logical_cpus_mask, 0, "");
1620
1621                 if (hlt_logical_cpus)
1622                         hlt_cpus_mask |= logical_cpus_mask;
1623
1624                 /*
1625                  * If necessary for security purposes, force
1626                  * hyperthreading off, regardless of the value
1627                  * of hlt_logical_cpus.
1628                  */
1629                 if (hyperthreading_cpus_mask) {
1630                         SYSCTL_ADD_PROC(&logical_cpu_clist,
1631                             SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO,
1632                             "hyperthreading_allowed", CTLTYPE_INT|CTLFLAG_RW,
1633                             0, 0, sysctl_hyperthreading_allowed, "IU", "");
1634                         if (! hyperthreading_allowed)
1635                                 hlt_cpus_mask |= hyperthreading_cpus_mask;
1636                 }
1637         }
1638 }
1639 SYSINIT(cpu_hlt, SI_SUB_SMP, SI_ORDER_ANY, cpu_hlt_setup, NULL);
1640
1641 int
1642 mp_grab_cpu_hlt(void)
1643 {
1644         cpumask_t mask;
1645 #ifdef MP_WATCHDOG
1646         u_int cpuid;
1647 #endif
1648         int retval;
1649
1650         mask = PCPU_GET(cpumask);
1651 #ifdef MP_WATCHDOG
1652         cpuid = PCPU_GET(cpuid);
1653         ap_watchdog(cpuid);
1654 #endif
1655
1656         retval = 0;
1657         while (mask & hlt_cpus_mask) {
1658                 retval = 1;
1659                 __asm __volatile("sti; hlt" : : : "memory");
1660         }
1661         return (retval);
1662 }
1663
1664 #ifdef COUNT_IPIS
1665 /*
1666  * Setup interrupt counters for IPI handlers.
1667  */
1668 static void
1669 mp_ipi_intrcnt(void *dummy)
1670 {
1671         char buf[64];
1672         int i;
1673
1674         CPU_FOREACH(i) {
1675                 snprintf(buf, sizeof(buf), "cpu%d: invltlb", i);
1676                 intrcnt_add(buf, &ipi_invltlb_counts[i]);
1677                 snprintf(buf, sizeof(buf), "cpu%d: invlrng", i);
1678                 intrcnt_add(buf, &ipi_invlrng_counts[i]);
1679                 snprintf(buf, sizeof(buf), "cpu%d: invlpg", i);
1680                 intrcnt_add(buf, &ipi_invlpg_counts[i]);
1681                 snprintf(buf, sizeof(buf), "cpu%d: invlcache", i);
1682                 intrcnt_add(buf, &ipi_invlcache_counts[i]);
1683                 snprintf(buf, sizeof(buf), "cpu%d: preempt", i);
1684                 intrcnt_add(buf, &ipi_preempt_counts[i]);
1685                 snprintf(buf, sizeof(buf), "cpu%d: ast", i);
1686                 intrcnt_add(buf, &ipi_ast_counts[i]);
1687                 snprintf(buf, sizeof(buf), "cpu%d: rendezvous", i);
1688                 intrcnt_add(buf, &ipi_rendezvous_counts[i]);
1689                 snprintf(buf, sizeof(buf), "cpu%d: lazypmap", i);
1690                 intrcnt_add(buf, &ipi_lazypmap_counts[i]);
1691         }               
1692 }
1693 SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL);
1694 #endif