]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/amd64/amd64/mp_machdep.c
This commit was generated by cvs2svn to compensate for changes in r135923,
[FreeBSD/FreeBSD.git] / sys / amd64 / amd64 / mp_machdep.c
1 /*-
2  * Copyright (c) 1996, by Steve Passe
3  * Copyright (c) 2003, by Peter Wemm
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. The name of the developer may NOT be used to endorse or promote products
12  *    derived from this software without specific prior written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "opt_cpu.h"
31 #include "opt_kstack_pages.h"
32 #include "opt_mp_watchdog.h"
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #ifdef GPROF 
38 #include <sys/gmon.h>
39 #endif
40 #include <sys/kernel.h>
41 #include <sys/ktr.h>
42 #include <sys/lock.h>
43 #include <sys/malloc.h>
44 #include <sys/memrange.h>
45 #include <sys/mutex.h>
46 #include <sys/pcpu.h>
47 #include <sys/proc.h>
48 #include <sys/smp.h>
49 #include <sys/sysctl.h>
50
51 #include <vm/vm.h>
52 #include <vm/vm_param.h>
53 #include <vm/pmap.h>
54 #include <vm/vm_kern.h>
55 #include <vm/vm_extern.h>
56
57 #include <machine/apicreg.h>
58 #include <machine/clock.h>
59 #include <machine/md_var.h>
60 #include <machine/mp_watchdog.h>
61 #include <machine/pcb.h>
62 #include <machine/psl.h>
63 #include <machine/smp.h>
64 #include <machine/specialreg.h>
65 #include <machine/tss.h>
66
67 #define WARMBOOT_TARGET         0
68 #define WARMBOOT_OFF            (KERNBASE + 0x0467)
69 #define WARMBOOT_SEG            (KERNBASE + 0x0469)
70
71 #define CMOS_REG                (0x70)
72 #define CMOS_DATA               (0x71)
73 #define BIOS_RESET              (0x0f)
74 #define BIOS_WARM               (0x0a)
75
76 /* lock region used by kernel profiling */
77 int     mcount_lock;
78
79 int     mp_naps;                /* # of Applications processors */
80 int     boot_cpu_id = -1;       /* designated BSP */
81 extern  int nkpt;
82
83 /*
84  * CPU topology map datastructures for HTT.
85  */
86 static struct cpu_group mp_groups[MAXCPU];
87 static struct cpu_top mp_top;
88
89 /* AP uses this during bootstrap.  Do not staticize.  */
90 char *bootSTK;
91 static int bootAP;
92
93 /* Free these after use */
94 void *bootstacks[MAXCPU];
95
96 /* Hotwire a 0->4MB V==P mapping */
97 extern pt_entry_t *KPTphys;
98
99 /* SMP page table page */
100 extern pt_entry_t *SMPpt;
101
102 struct pcb stoppcbs[MAXCPU];
103
104 /* Variables needed for SMP tlb shootdown. */
105 vm_offset_t smp_tlb_addr1;
106 vm_offset_t smp_tlb_addr2;
107 volatile int smp_tlb_wait;
108
109 extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
110
111 /*
112  * Local data and functions.
113  */
114
115 static u_int logical_cpus;
116
117 /* used to hold the AP's until we are ready to release them */
118 static struct mtx ap_boot_mtx;
119
120 /* Set to 1 once we're ready to let the APs out of the pen. */
121 static volatile int aps_ready = 0;
122
123 /*
124  * Store data from cpu_add() until later in the boot when we actually setup
125  * the APs.
126  */
127 struct cpu_info {
128         int     cpu_present:1;
129         int     cpu_bsp:1;
130 } static cpu_info[MAXCPU];
131 static int cpu_apic_ids[MAXCPU];
132
133 static u_int boot_address;
134
135 static void     set_logical_apic_ids(void);
136 static int      start_all_aps(void);
137 static int      start_ap(int apic_id);
138 static void     release_aps(void *dummy);
139
140 static int      hlt_logical_cpus;
141 static struct   sysctl_ctx_list logical_cpu_clist;
142 static u_int    bootMP_size;
143
144 static void
145 mem_range_AP_init(void)
146 {
147         if (mem_range_softc.mr_op && mem_range_softc.mr_op->initAP)
148                 mem_range_softc.mr_op->initAP(&mem_range_softc);
149 }
150
151 void
152 mp_topology(void)
153 {
154         struct cpu_group *group;
155         int logical_cpus;
156         int apic_id;
157         int groups;
158         int cpu;
159
160         /* Build the smp_topology map. */
161         /* Nothing to do if there is no HTT support. */
162         if ((cpu_feature & CPUID_HTT) == 0)
163                 return;
164         logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
165         if (logical_cpus <= 1)
166                 return;
167         group = &mp_groups[0];
168         groups = 1;
169         for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
170                 if (!cpu_info[apic_id].cpu_present)
171                         continue;
172                 /*
173                  * If the current group has members and we're not a logical
174                  * cpu, create a new group.
175                  */
176                 if (group->cg_count != 0 && (apic_id % logical_cpus) == 0) {
177                         group++;
178                         groups++;
179                 }
180                 group->cg_count++;
181                 group->cg_mask |= 1 << cpu;
182                 cpu++;
183         }
184
185         mp_top.ct_count = groups;
186         mp_top.ct_group = mp_groups;
187         smp_topology = &mp_top;
188 }
189
190
191 /*
192  * Calculate usable address in base memory for AP trampoline code.
193  */
194 u_int
195 mp_bootaddress(u_int basemem)
196 {
197
198         bootMP_size = mptramp_end - mptramp_start;
199         boot_address = trunc_page(basemem * 1024); /* round down to 4k boundary */
200         if (((basemem * 1024) - boot_address) < bootMP_size)
201                 boot_address -= PAGE_SIZE;      /* not enough, lower by 4k */
202         /* 3 levels of page table pages */
203         mptramp_pagetables = boot_address - (PAGE_SIZE * 3);
204
205         return mptramp_pagetables;
206 }
207
208 void
209 cpu_add(u_int apic_id, char boot_cpu)
210 {
211
212         if (apic_id >= MAXCPU) {
213                 printf("SMP: CPU %d exceeds maximum CPU %d, ignoring\n",
214                     apic_id, MAXCPU - 1);
215                 return;
216         }
217         KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
218             apic_id));
219         cpu_info[apic_id].cpu_present = 1;
220         if (boot_cpu) {
221                 KASSERT(boot_cpu_id == -1,
222                     ("CPU %d claims to be BSP, but CPU %d already is", apic_id,
223                     boot_cpu_id));
224                 boot_cpu_id = apic_id;
225                 cpu_info[apic_id].cpu_bsp = 1;
226         }
227         mp_ncpus++;
228         if (apic_id > mp_maxid)
229                 mp_maxid = apic_id;
230         if (bootverbose)
231                 printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
232                     "AP");
233         
234 }
235
236 void
237 cpu_mp_setmaxid(void)
238 {
239
240         /*
241          * mp_maxid should be already set by calls to cpu_add().
242          * Just sanity check its value here.
243          */
244         if (mp_ncpus == 0)
245                 KASSERT(mp_maxid == 0,
246                     ("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
247         else if (mp_ncpus == 1)
248                 mp_maxid = 0;
249         else
250                 KASSERT(mp_maxid >= mp_ncpus - 1,
251                     ("%s: counters out of sync: max %d, count %d", __func__,
252                         mp_maxid, mp_ncpus));
253                 
254 }
255
256 int
257 cpu_mp_probe(void)
258 {
259
260         /*
261          * Always record BSP in CPU map so that the mbuf init code works
262          * correctly.
263          */
264         all_cpus = 1;
265         if (mp_ncpus == 0) {
266                 /*
267                  * No CPUs were found, so this must be a UP system.  Setup
268                  * the variables to represent a system with a single CPU
269                  * with an id of 0.
270                  */
271                 mp_ncpus = 1;
272                 return (0);
273         }
274
275         /* At least one CPU was found. */
276         if (mp_ncpus == 1) {
277                 /*
278                  * One CPU was found, so this must be a UP system with
279                  * an I/O APIC.
280                  */
281                 mp_maxid = 0;
282                 return (0);
283         }
284
285         /* At least two CPUs were found. */
286         return (1);
287 }
288
289 /*
290  * Initialize the IPI handlers and start up the AP's.
291  */
292 void
293 cpu_mp_start(void)
294 {
295         int i;
296
297         /* Initialize the logical ID to APIC ID table. */
298         for (i = 0; i < MAXCPU; i++)
299                 cpu_apic_ids[i] = -1;
300
301         /* Install an inter-CPU IPI for TLB invalidation */
302         setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0);
303         setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0);
304         setidt(IPI_INVLRNG, IDTVEC(invlrng), SDT_SYSIGT, SEL_KPL, 0);
305
306         /* Install an inter-CPU IPI for forwarding hardclock() */
307         setidt(IPI_HARDCLOCK, IDTVEC(hardclock), SDT_SYSIGT, SEL_KPL, 0);
308         
309         /* Install an inter-CPU IPI for forwarding statclock() */
310         setidt(IPI_STATCLOCK, IDTVEC(statclock), SDT_SYSIGT, SEL_KPL, 0);
311         
312         /* Install an inter-CPU IPI for all-CPU rendezvous */
313         setidt(IPI_RENDEZVOUS, IDTVEC(rendezvous), SDT_SYSIGT, SEL_KPL, 0);
314
315         /* Install an inter-CPU IPI for forcing an additional software trap */
316         setidt(IPI_AST, IDTVEC(cpuast), SDT_SYSIGT, SEL_KPL, 0);
317
318         /* Install an inter-CPU IPI for CPU stop/restart */
319         setidt(IPI_STOP, IDTVEC(cpustop), SDT_SYSIGT, SEL_KPL, 0);
320
321         /* Set boot_cpu_id if needed. */
322         if (boot_cpu_id == -1) {
323                 boot_cpu_id = PCPU_GET(apic_id);
324                 cpu_info[boot_cpu_id].cpu_bsp = 1;
325         } else
326                 KASSERT(boot_cpu_id == PCPU_GET(apic_id),
327                     ("BSP's APIC ID doesn't match boot_cpu_id"));
328         cpu_apic_ids[0] = boot_cpu_id;
329
330         /* Start each Application Processor */
331         start_all_aps();
332
333         /* Setup the initial logical CPUs info. */
334         logical_cpus = logical_cpus_mask = 0;
335         if (cpu_feature & CPUID_HTT)
336                 logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
337
338         set_logical_apic_ids();
339 }
340
341
342 /*
343  * Print various information about the SMP system hardware and setup.
344  */
345 void
346 cpu_mp_announce(void)
347 {
348         int i, x;
349
350         /* List CPUs */
351         printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
352         for (i = 1, x = 0; x < MAXCPU; x++) {
353                 if (cpu_info[x].cpu_present && !cpu_info[x].cpu_bsp) {
354                         KASSERT(i < mp_ncpus,
355                             ("mp_ncpus and actual cpus are out of whack"));
356                         printf(" cpu%d (AP): APIC ID: %2d\n", i++, x);
357                 }
358         }
359 }
360
361 /*
362  * AP CPU's call this to initialize themselves.
363  */
364 void
365 init_secondary(void)
366 {
367         struct pcpu *pc;
368         u_int64_t msr, cr0;
369         int cpu, gsel_tss;
370
371         /* Set by the startup code for us to use */
372         cpu = bootAP;
373
374         /* Init tss */
375         common_tss[cpu] = common_tss[0];
376         common_tss[cpu].tss_rsp0 = 0;   /* not used until after switch */
377
378         gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu];
379         ssdtosyssd(&gdt_segs[GPROC0_SEL],
380            (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
381
382         lgdt(&r_gdt);                   /* does magic intra-segment return */
383
384         /* Get per-cpu data */
385         pc = &__pcpu[cpu];
386
387         /* prime data page for it to use */
388         pcpu_init(pc, cpu, sizeof(struct pcpu));
389         pc->pc_apic_id = cpu_apic_ids[cpu];
390         pc->pc_prvspace = pc;
391         pc->pc_curthread = 0;
392         pc->pc_tssp = &common_tss[cpu];
393         pc->pc_rsp0 = 0;
394
395         wrmsr(MSR_FSBASE, 0);           /* User value */
396         wrmsr(MSR_GSBASE, (u_int64_t)pc);
397         wrmsr(MSR_KGSBASE, (u_int64_t)pc);      /* XXX User value while we're in the kernel */
398
399         lidt(&r_idt);
400
401         gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
402         ltr(gsel_tss);
403
404         /*
405          * Set to a known state:
406          * Set by mpboot.s: CR0_PG, CR0_PE
407          * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
408          */
409         cr0 = rcr0();
410         cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
411         load_cr0(cr0);
412
413         /* Set up the fast syscall stuff */
414         msr = rdmsr(MSR_EFER) | EFER_SCE;
415         wrmsr(MSR_EFER, msr);
416         wrmsr(MSR_LSTAR, (u_int64_t)IDTVEC(fast_syscall));
417         wrmsr(MSR_CSTAR, (u_int64_t)IDTVEC(fast_syscall32));
418         msr = ((u_int64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
419               ((u_int64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48);
420         wrmsr(MSR_STAR, msr);
421         wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D);
422
423         /* Disable local apic just to be sure. */
424         lapic_disable();
425
426         /* signal our startup to the BSP. */
427         mp_naps++;
428
429         /* Spin until the BSP releases the AP's. */
430         while (!aps_ready)
431                 ia32_pause();
432
433         /* set up CPU registers and state */
434         cpu_setregs();
435
436         /* set up SSE/NX registers */
437         initializecpu();
438
439         /* set up FPU state on the AP */
440         fpuinit();
441
442         /* A quick check from sanity claus */
443         if (PCPU_GET(apic_id) != lapic_id()) {
444                 printf("SMP: cpuid = %d\n", PCPU_GET(cpuid));
445                 printf("SMP: actual apic_id = %d\n", lapic_id());
446                 printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
447                 panic("cpuid mismatch! boom!!");
448         }
449
450         mtx_lock_spin(&ap_boot_mtx);
451
452         /* Init local apic for irq's */
453         lapic_setup();
454
455         /* Set memory range attributes for this CPU to match the BSP */
456         mem_range_AP_init();
457
458         smp_cpus++;
459
460         CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", PCPU_GET(cpuid));
461         printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid));
462
463         /* Determine if we are a logical CPU. */
464         if (logical_cpus > 1 && PCPU_GET(apic_id) % logical_cpus != 0)
465                 logical_cpus_mask |= PCPU_GET(cpumask);
466         
467         /* Build our map of 'other' CPUs. */
468         PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
469
470         if (bootverbose)
471                 lapic_dump("AP");
472
473         if (smp_cpus == mp_ncpus) {
474                 /* enable IPI's, tlb shootdown, freezes etc */
475                 atomic_store_rel_int(&smp_started, 1);
476                 smp_active = 1;  /* historic */
477         }
478
479         mtx_unlock_spin(&ap_boot_mtx);
480
481         /* wait until all the AP's are up */
482         while (smp_started == 0)
483                 ia32_pause();
484
485         /* ok, now grab sched_lock and enter the scheduler */
486         mtx_lock_spin(&sched_lock);
487
488         binuptime(PCPU_PTR(switchtime));
489         PCPU_SET(switchticks, ticks);
490
491         cpu_throw(NULL, choosethread());        /* doesn't return */
492
493         panic("scheduler returned us to %s", __func__);
494         /* NOTREACHED */
495 }
496
497 /*******************************************************************
498  * local functions and data
499  */
500
501 /*
502  * Set the APIC logical IDs.
503  *
504  * We want to cluster logical CPU's within the same APIC ID cluster.
505  * Since logical CPU's are aligned simply filling in the clusters in
506  * APIC ID order works fine.  Note that this does not try to balance
507  * the number of CPU's in each cluster. (XXX?)
508  */
509 static void
510 set_logical_apic_ids(void)
511 {
512         u_int apic_id, cluster, cluster_id;
513
514         /* Force us to allocate cluster 0 at the start. */
515         cluster = -1;
516         cluster_id = APIC_MAX_INTRACLUSTER_ID;
517         for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
518                 if (!cpu_info[apic_id].cpu_present)
519                         continue;
520                 if (cluster_id == APIC_MAX_INTRACLUSTER_ID) {
521                         cluster = ioapic_next_logical_cluster();
522                         cluster_id = 0;
523                 } else
524                         cluster_id++;
525                 if (bootverbose)
526                         printf("APIC ID: physical %u, logical %u:%u\n",
527                             apic_id, cluster, cluster_id);
528                 lapic_set_logical_id(apic_id, cluster, cluster_id);
529         }
530 }
531
532 /*
533  * start each AP in our list
534  */
535 static int
536 start_all_aps(void)
537 {
538         u_char mpbiosreason;
539         u_int32_t mpbioswarmvec;
540         int apic_id, cpu, i;
541         u_int64_t *pt4, *pt3, *pt2;
542         vm_offset_t va = boot_address + KERNBASE;
543
544         mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
545
546         /* install the AP 1st level boot code */
547         pmap_kenter(va, boot_address);
548         pmap_invalidate_page(kernel_pmap, va);
549         bcopy(mptramp_start, (void *)va, bootMP_size);
550
551         /* Locate the page tables, they'll be below the trampoline */
552         pt4 = (u_int64_t *)(uintptr_t)(mptramp_pagetables + KERNBASE);
553         pt3 = pt4 + (PAGE_SIZE) / sizeof(u_int64_t);
554         pt2 = pt3 + (PAGE_SIZE) / sizeof(u_int64_t);
555
556         /* Create the initial 1GB replicated page tables */
557         for (i = 0; i < 512; i++) {
558                 /* Each slot of the level 4 pages points to the same level 3 page */
559                 pt4[i] = (u_int64_t)(uintptr_t)(mptramp_pagetables + PAGE_SIZE);
560                 pt4[i] |= PG_V | PG_RW | PG_U;
561
562                 /* Each slot of the level 3 pages points to the same level 2 page */
563                 pt3[i] = (u_int64_t)(uintptr_t)(mptramp_pagetables + (2 * PAGE_SIZE));
564                 pt3[i] |= PG_V | PG_RW | PG_U;
565
566                 /* The level 2 page slots are mapped with 2MB pages for 1GB. */
567                 pt2[i] = i * (2 * 1024 * 1024);
568                 pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
569         }
570
571         /* save the current value of the warm-start vector */
572         mpbioswarmvec = *((u_int32_t *) WARMBOOT_OFF);
573         outb(CMOS_REG, BIOS_RESET);
574         mpbiosreason = inb(CMOS_DATA);
575
576         /* setup a vector to our boot code */
577         *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
578         *((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4);
579         outb(CMOS_REG, BIOS_RESET);
580         outb(CMOS_DATA, BIOS_WARM);     /* 'warm-start' */
581
582         /* start each AP */
583         cpu = 0;
584         for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
585                 if (!cpu_info[apic_id].cpu_present ||
586                     cpu_info[apic_id].cpu_bsp)
587                         continue;
588                 cpu++;
589
590                 /* save APIC ID for this logical ID */
591                 cpu_apic_ids[cpu] = apic_id;
592
593                 /* allocate and set up an idle stack data page */
594                 bootstacks[cpu] = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
595
596                 bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8;
597                 bootAP = cpu;
598
599                 /* attempt to start the Application Processor */
600                 if (!start_ap(apic_id)) {
601                         /* restore the warmstart vector */
602                         *(u_int32_t *) WARMBOOT_OFF = mpbioswarmvec;
603                         panic("AP #%d (PHY# %d) failed!", cpu, apic_id);
604                 }
605
606                 all_cpus |= (1 << cpu);         /* record AP in CPU map */
607         }
608
609         /* build our map of 'other' CPUs */
610         PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
611
612         /* restore the warmstart vector */
613         *(u_int32_t *) WARMBOOT_OFF = mpbioswarmvec;
614
615         outb(CMOS_REG, BIOS_RESET);
616         outb(CMOS_DATA, mpbiosreason);
617
618         /* number of APs actually started */
619         return mp_naps;
620 }
621
622
623 /*
624  * This function starts the AP (application processor) identified
625  * by the APIC ID 'physicalCpu'.  It does quite a "song and dance"
626  * to accomplish this.  This is necessary because of the nuances
627  * of the different hardware we might encounter.  It isn't pretty,
628  * but it seems to work.
629  */
630 static int
631 start_ap(int apic_id)
632 {
633         int vector, ms;
634         int cpus;
635
636         /* calculate the vector */
637         vector = (boot_address >> 12) & 0xff;
638
639         /* used as a watchpoint to signal AP startup */
640         cpus = mp_naps;
641
642         /*
643          * first we do an INIT/RESET IPI this INIT IPI might be run, reseting
644          * and running the target CPU. OR this INIT IPI might be latched (P5
645          * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be
646          * ignored.
647          */
648
649         /* do an INIT IPI: assert RESET */
650         lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
651             APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id);
652
653         /* wait for pending status end */
654         lapic_ipi_wait(-1);
655
656         /* do an INIT IPI: deassert RESET */
657         lapic_ipi_raw(APIC_DEST_ALLESELF | APIC_TRIGMOD_LEVEL |
658             APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, 0);
659
660         /* wait for pending status end */
661         DELAY(10000);           /* wait ~10mS */
662         lapic_ipi_wait(-1);
663
664         /*
665          * next we do a STARTUP IPI: the previous INIT IPI might still be
666          * latched, (P5 bug) this 1st STARTUP would then terminate
667          * immediately, and the previously started INIT IPI would continue. OR
668          * the previous INIT IPI has already run. and this STARTUP IPI will
669          * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
670          * will run.
671          */
672
673         /* do a STARTUP IPI */
674         lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
675             APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
676             vector, apic_id);
677         lapic_ipi_wait(-1);
678         DELAY(200);             /* wait ~200uS */
679
680         /*
681          * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
682          * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
683          * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
684          * recognized after hardware RESET or INIT IPI.
685          */
686
687         lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
688             APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
689             vector, apic_id);
690         lapic_ipi_wait(-1);
691         DELAY(200);             /* wait ~200uS */
692
693         /* Wait up to 5 seconds for it to start. */
694         for (ms = 0; ms < 50; ms++) {
695                 if (mp_naps > cpus)
696                         return 1;       /* return SUCCESS */
697                 DELAY(100000);
698         }
699         return 0;               /* return FAILURE */
700 }
701
702 /*
703  * Flush the TLB on all other CPU's
704  */
705 static void
706 smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2)
707 {
708         u_int ncpu;
709
710         ncpu = mp_ncpus - 1;    /* does not shootdown self */
711         if (ncpu < 1)
712                 return;         /* no other cpus */
713         mtx_assert(&smp_ipi_mtx, MA_OWNED);
714         smp_tlb_addr1 = addr1;
715         smp_tlb_addr2 = addr2;
716         atomic_store_rel_int(&smp_tlb_wait, 0);
717         ipi_all_but_self(vector);
718         while (smp_tlb_wait < ncpu)
719                 ia32_pause();
720 }
721
722 /*
723  * This is about as magic as it gets.  fortune(1) has got similar code
724  * for reversing bits in a word.  Who thinks up this stuff??
725  *
726  * Yes, it does appear to be consistently faster than:
727  * while (i = ffs(m)) {
728  *      m >>= i;
729  *      bits++;
730  * }
731  * and
732  * while (lsb = (m & -m)) {     // This is magic too
733  *      m &= ~lsb;              // or: m ^= lsb
734  *      bits++;
735  * }
736  * Both of these latter forms do some very strange things on gcc-3.1 with
737  * -mcpu=pentiumpro and/or -march=pentiumpro and/or -O or -O2.
738  * There is probably an SSE or MMX popcnt instruction.
739  *
740  * I wonder if this should be in libkern?
741  *
742  * XXX Stop the presses!  Another one:
743  * static __inline u_int32_t
744  * popcnt1(u_int32_t v)
745  * {
746  *      v -= ((v >> 1) & 0x55555555);
747  *      v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
748  *      v = (v + (v >> 4)) & 0x0F0F0F0F;
749  *      return (v * 0x01010101) >> 24;
750  * }
751  * The downside is that it has a multiply.  With a pentium3 with
752  * -mcpu=pentiumpro and -march=pentiumpro then gcc-3.1 will use
753  * an imull, and in that case it is faster.  In most other cases
754  * it appears slightly slower.
755  *
756  * Another variant (also from fortune):
757  * #define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)
758  * #define  BX_(x)     ((x) - (((x)>>1)&0x77777777)            \
759  *                          - (((x)>>2)&0x33333333)            \
760  *                          - (((x)>>3)&0x11111111))
761  */
762 static __inline u_int32_t
763 popcnt(u_int32_t m)
764 {
765
766         m = (m & 0x55555555) + ((m & 0xaaaaaaaa) >> 1);
767         m = (m & 0x33333333) + ((m & 0xcccccccc) >> 2);
768         m = (m & 0x0f0f0f0f) + ((m & 0xf0f0f0f0) >> 4);
769         m = (m & 0x00ff00ff) + ((m & 0xff00ff00) >> 8);
770         m = (m & 0x0000ffff) + ((m & 0xffff0000) >> 16);
771         return m;
772 }
773
774 static void
775 smp_targeted_tlb_shootdown(u_int mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2)
776 {
777         int ncpu, othercpus;
778
779         othercpus = mp_ncpus - 1;
780         if (mask == (u_int)-1) {
781                 ncpu = othercpus;
782                 if (ncpu < 1)
783                         return;
784         } else {
785                 mask &= ~PCPU_GET(cpumask);
786                 if (mask == 0)
787                         return;
788                 ncpu = popcnt(mask);
789                 if (ncpu > othercpus) {
790                         /* XXX this should be a panic offence */
791                         printf("SMP: tlb shootdown to %d other cpus (only have %d)\n",
792                             ncpu, othercpus);
793                         ncpu = othercpus;
794                 }
795                 /* XXX should be a panic, implied by mask == 0 above */
796                 if (ncpu < 1)
797                         return;
798         }
799         mtx_assert(&smp_ipi_mtx, MA_OWNED);
800         smp_tlb_addr1 = addr1;
801         smp_tlb_addr2 = addr2;
802         atomic_store_rel_int(&smp_tlb_wait, 0);
803         if (mask == (u_int)-1)
804                 ipi_all_but_self(vector);
805         else
806                 ipi_selected(mask, vector);
807         while (smp_tlb_wait < ncpu)
808                 ia32_pause();
809 }
810
811 void
812 smp_invltlb(void)
813 {
814
815         if (smp_started)
816                 smp_tlb_shootdown(IPI_INVLTLB, 0, 0);
817 }
818
819 void
820 smp_invlpg(vm_offset_t addr)
821 {
822
823         if (smp_started)
824                 smp_tlb_shootdown(IPI_INVLPG, addr, 0);
825 }
826
827 void
828 smp_invlpg_range(vm_offset_t addr1, vm_offset_t addr2)
829 {
830
831         if (smp_started)
832                 smp_tlb_shootdown(IPI_INVLRNG, addr1, addr2);
833 }
834
835 void
836 smp_masked_invltlb(u_int mask)
837 {
838
839         if (smp_started)
840                 smp_targeted_tlb_shootdown(mask, IPI_INVLTLB, 0, 0);
841 }
842
843 void
844 smp_masked_invlpg(u_int mask, vm_offset_t addr)
845 {
846
847         if (smp_started)
848                 smp_targeted_tlb_shootdown(mask, IPI_INVLPG, addr, 0);
849 }
850
851 void
852 smp_masked_invlpg_range(u_int mask, vm_offset_t addr1, vm_offset_t addr2)
853 {
854
855         if (smp_started)
856                 smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, addr1, addr2);
857 }
858
859
860 /*
861  * For statclock, we send an IPI to all CPU's to have them call this
862  * function.
863  */
864 void
865 forwarded_statclock(struct clockframe frame)
866 {
867         struct thread *td;
868
869         CTR0(KTR_SMP, "forwarded_statclock");
870         td = curthread;
871         td->td_intr_nesting_level++;
872         if (profprocs != 0)
873                 profclock(&frame);
874         if (pscnt == psdiv)
875                 statclock(&frame);
876         td->td_intr_nesting_level--;
877 }
878
879 void
880 forward_statclock(void)
881 {
882         int map;
883
884         CTR0(KTR_SMP, "forward_statclock");
885
886         if (!smp_started || cold || panicstr)
887                 return;
888
889         map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask);
890         if (map != 0)
891                 ipi_selected(map, IPI_STATCLOCK);
892 }
893
894 /*
895  * For each hardclock(), we send an IPI to all other CPU's to have them
896  * execute this function.  It would be nice to reduce contention on
897  * sched_lock if we could simply peek at the CPU to determine the user/kernel
898  * state and call hardclock_process() on the CPU receiving the clock interrupt
899  * and then just use a simple IPI to handle any ast's if needed.
900  */
901 void
902 forwarded_hardclock(struct clockframe frame)
903 {
904         struct thread *td;
905
906         CTR0(KTR_SMP, "forwarded_hardclock");
907         td = curthread;
908         td->td_intr_nesting_level++;
909         hardclock_process(&frame);
910         td->td_intr_nesting_level--;
911 }
912
913 void 
914 forward_hardclock(void)
915 {
916         u_int map;
917
918         CTR0(KTR_SMP, "forward_hardclock");
919
920         if (!smp_started || cold || panicstr)
921                 return;
922
923         map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask);
924         if (map != 0)
925                 ipi_selected(map, IPI_HARDCLOCK);
926 }
927
928 /*
929  * send an IPI to a set of cpus.
930  */
931 void
932 ipi_selected(u_int32_t cpus, u_int ipi)
933 {
934         int cpu;
935
936         CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi);
937         while ((cpu = ffs(cpus)) != 0) {
938                 cpu--;
939                 KASSERT(cpu_apic_ids[cpu] != -1,
940                     ("IPI to non-existent CPU %d", cpu));
941                 lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]);
942                 cpus &= ~(1 << cpu);
943         }
944 }
945
946 /*
947  * send an IPI INTerrupt containing 'vector' to all CPUs, including myself
948  */
949 void
950 ipi_all(u_int ipi)
951 {
952
953         CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
954         lapic_ipi_vectored(ipi, APIC_IPI_DEST_ALL);
955 }
956
957 /*
958  * send an IPI to all CPUs EXCEPT myself
959  */
960 void
961 ipi_all_but_self(u_int ipi)
962 {
963
964         CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
965         lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
966 }
967
968 /*
969  * send an IPI to myself
970  */
971 void
972 ipi_self(u_int ipi)
973 {
974
975         CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
976         lapic_ipi_vectored(ipi, APIC_IPI_DEST_SELF);
977 }
978
979 /*
980  * This is called once the rest of the system is up and running and we're
981  * ready to let the AP's out of the pen.
982  */
983 static void
984 release_aps(void *dummy __unused)
985 {
986
987         if (mp_ncpus == 1) 
988                 return;
989         mtx_lock_spin(&sched_lock);
990         atomic_store_rel_int(&aps_ready, 1);
991         while (smp_started == 0)
992                 ia32_pause();
993         mtx_unlock_spin(&sched_lock);
994 }
995 SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
996
997 static int
998 sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS)
999 {
1000         u_int mask;
1001         int error;
1002
1003         mask = hlt_cpus_mask;
1004         error = sysctl_handle_int(oidp, &mask, 0, req);
1005         if (error || !req->newptr)
1006                 return (error);
1007
1008         if (logical_cpus_mask != 0 &&
1009             (mask & logical_cpus_mask) == logical_cpus_mask)
1010                 hlt_logical_cpus = 1;
1011         else
1012                 hlt_logical_cpus = 0;
1013
1014         if ((mask & all_cpus) == all_cpus)
1015                 mask &= ~(1<<0);
1016         hlt_cpus_mask = mask;
1017         return (error);
1018 }
1019 SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW,
1020     0, 0, sysctl_hlt_cpus, "IU",
1021     "Bitmap of CPUs to halt.  101 (binary) will halt CPUs 0 and 2.");
1022
1023 static int
1024 sysctl_hlt_logical_cpus(SYSCTL_HANDLER_ARGS)
1025 {
1026         int disable, error;
1027
1028         disable = hlt_logical_cpus;
1029         error = sysctl_handle_int(oidp, &disable, 0, req);
1030         if (error || !req->newptr)
1031                 return (error);
1032
1033         if (disable)
1034                 hlt_cpus_mask |= logical_cpus_mask;
1035         else
1036                 hlt_cpus_mask &= ~logical_cpus_mask;
1037
1038         if ((hlt_cpus_mask & all_cpus) == all_cpus)
1039                 hlt_cpus_mask &= ~(1<<0);
1040
1041         hlt_logical_cpus = disable;
1042         return (error);
1043 }
1044
1045 static void
1046 cpu_hlt_setup(void *dummy __unused)
1047 {
1048
1049         if (logical_cpus_mask != 0) {
1050                 TUNABLE_INT_FETCH("machdep.hlt_logical_cpus",
1051                     &hlt_logical_cpus);
1052                 sysctl_ctx_init(&logical_cpu_clist);
1053                 SYSCTL_ADD_PROC(&logical_cpu_clist,
1054                     SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO,
1055                     "hlt_logical_cpus", CTLTYPE_INT|CTLFLAG_RW, 0, 0,
1056                     sysctl_hlt_logical_cpus, "IU", "");
1057                 SYSCTL_ADD_UINT(&logical_cpu_clist,
1058                     SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO,
1059                     "logical_cpus_mask", CTLTYPE_INT|CTLFLAG_RD,
1060                     &logical_cpus_mask, 0, "");
1061
1062                 if (hlt_logical_cpus)
1063                         hlt_cpus_mask |= logical_cpus_mask;
1064         }
1065 }
1066 SYSINIT(cpu_hlt, SI_SUB_SMP, SI_ORDER_ANY, cpu_hlt_setup, NULL);
1067
1068 int
1069 mp_grab_cpu_hlt(void)
1070 {
1071         u_int mask = PCPU_GET(cpumask);
1072 #ifdef MP_WATCHDOG
1073         u_int cpuid = PCPU_GET(cpuid);
1074 #endif
1075         int retval;
1076
1077 #ifdef MP_WATCHDOG
1078         ap_watchdog(cpuid);
1079 #endif
1080
1081         retval = mask & hlt_cpus_mask;
1082         while (mask & hlt_cpus_mask)
1083                 __asm __volatile("sti; hlt" : : : "memory");
1084         return (retval);
1085 }