i386: Move ioapic function declarations from smp.h to apic/ioapic.h
[dragonfly.git] / sys / platform / pc32 / 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  * $FreeBSD: src/sys/i386/i386/mp_machdep.c,v 1.115.2.15 2003/03/14 21:22:35 jhb Exp $
26  * $DragonFly: src/sys/platform/pc32/i386/mp_machdep.c,v 1.60 2008/06/07 12:03:52 mneumann Exp $
27  */
28
29 #include "opt_cpu.h"
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/sysctl.h>
35 #include <sys/malloc.h>
36 #include <sys/memrange.h>
37 #include <sys/cons.h>   /* cngetc() */
38 #include <sys/machintr.h>
39
40 #include <vm/vm.h>
41 #include <vm/vm_param.h>
42 #include <vm/pmap.h>
43 #include <vm/vm_kern.h>
44 #include <vm/vm_extern.h>
45 #include <sys/lock.h>
46 #include <vm/vm_map.h>
47 #include <sys/user.h>
48 #ifdef GPROF 
49 #include <sys/gmon.h>
50 #endif
51
52 #include <sys/mplock2.h>
53
54 #include <machine/smp.h>
55 #include <machine_base/apic/apicreg.h>
56 #include <machine/atomic.h>
57 #include <machine/cpufunc.h>
58 #include <machine/cputypes.h>
59 #include <machine_base/apic/ioapic_abi.h>
60 #include <machine_base/apic/lapic.h>
61 #include <machine_base/apic/ioapic.h>
62 #include <machine/psl.h>
63 #include <machine/segments.h>
64 #include <machine/tss.h>
65 #include <machine/specialreg.h>
66 #include <machine/globaldata.h>
67 #include <machine/pmap_inval.h>
68
69 #include <machine/md_var.h>             /* setidt() */
70 #include <machine_base/icu/icu.h>       /* IPIs */
71 #include <machine/intr_machdep.h>       /* IPIs */
72
73 #define WARMBOOT_TARGET         0
74 #define WARMBOOT_OFF            (KERNBASE + 0x0467)
75 #define WARMBOOT_SEG            (KERNBASE + 0x0469)
76
77 #define BIOS_BASE               (0xf0000)
78 #define BIOS_BASE2              (0xe0000)
79 #define BIOS_SIZE               (0x10000)
80 #define BIOS_COUNT              (BIOS_SIZE/4)
81
82 #define CMOS_REG                (0x70)
83 #define CMOS_DATA               (0x71)
84 #define BIOS_RESET              (0x0f)
85 #define BIOS_WARM               (0x0a)
86
87 #define PROCENTRY_FLAG_EN       0x01
88 #define PROCENTRY_FLAG_BP       0x02
89 #define IOAPICENTRY_FLAG_EN     0x01
90
91
92 /* MP Floating Pointer Structure */
93 typedef struct MPFPS {
94         char    signature[4];
95         u_int32_t pap;
96         u_char  length;
97         u_char  spec_rev;
98         u_char  checksum;
99         u_char  mpfb1;
100         u_char  mpfb2;
101         u_char  mpfb3;
102         u_char  mpfb4;
103         u_char  mpfb5;
104 }      *mpfps_t;
105
106 /* MP Configuration Table Header */
107 typedef struct MPCTH {
108         char    signature[4];
109         u_short base_table_length;
110         u_char  spec_rev;
111         u_char  checksum;
112         u_char  oem_id[8];
113         u_char  product_id[12];
114         void   *oem_table_pointer;
115         u_short oem_table_size;
116         u_short entry_count;
117         void   *apic_address;
118         u_short extended_table_length;
119         u_char  extended_table_checksum;
120         u_char  reserved;
121 }      *mpcth_t;
122
123
124 typedef struct PROCENTRY {
125         u_char  type;
126         u_char  apic_id;
127         u_char  apic_version;
128         u_char  cpu_flags;
129         u_long  cpu_signature;
130         u_long  feature_flags;
131         u_long  reserved1;
132         u_long  reserved2;
133 }      *proc_entry_ptr;
134
135 typedef struct BUSENTRY {
136         u_char  type;
137         u_char  bus_id;
138         char    bus_type[6];
139 }      *bus_entry_ptr;
140
141 typedef struct IOAPICENTRY {
142         u_char  type;
143         u_char  apic_id;
144         u_char  apic_version;
145         u_char  apic_flags;
146         void   *apic_address;
147 }      *io_apic_entry_ptr;
148
149 typedef struct INTENTRY {
150         u_char  type;
151         u_char  int_type;
152         u_short int_flags;
153         u_char  src_bus_id;
154         u_char  src_bus_irq;
155         u_char  dst_apic_id;
156         u_char  dst_apic_int;
157 }      *int_entry_ptr;
158
159 /* descriptions of MP basetable entries */
160 typedef struct BASETABLE_ENTRY {
161         u_char  type;
162         u_char  length;
163         char    name[16];
164 }       basetable_entry;
165
166 struct mptable_pos {
167         mpfps_t         mp_fps;
168         mpcth_t         mp_cth;
169         vm_size_t       mp_cth_mapsz;
170 };
171
172 #define MPTABLE_POS_USE_DEFAULT(mpt) \
173         ((mpt)->mp_fps->mpfb1 != 0 || (mpt)->mp_cth == NULL)
174
175 struct mptable_bus {
176         int             mb_id;
177         int             mb_type;        /* MPTABLE_BUS_ */
178         TAILQ_ENTRY(mptable_bus) mb_link;
179 };
180
181 #define MPTABLE_BUS_ISA         0
182 #define MPTABLE_BUS_PCI         1
183
184 struct mptable_bus_info {
185         TAILQ_HEAD(, mptable_bus) mbi_list;
186 };
187
188 struct mptable_pci_int {
189         int             mpci_bus;
190         int             mpci_dev;
191         int             mpci_pin;
192
193         int             mpci_ioapic_idx;
194         int             mpci_ioapic_pin;
195         TAILQ_ENTRY(mptable_pci_int) mpci_link;
196 };
197
198 struct mptable_ioapic {
199         int             mio_idx;
200         int             mio_apic_id;
201         uint32_t        mio_addr;
202         int             mio_gsi_base;
203         int             mio_npin;
204         TAILQ_ENTRY(mptable_ioapic) mio_link;
205 };
206
207 typedef int     (*mptable_iter_func)(void *, const void *, int);
208
209 /*
210  * this code MUST be enabled here and in mpboot.s.
211  * it follows the very early stages of AP boot by placing values in CMOS ram.
212  * it NORMALLY will never be needed and thus the primitive method for enabling.
213  *
214  */
215 #if defined(CHECK_POINTS)
216 #define CHECK_READ(A)    (outb(CMOS_REG, (A)), inb(CMOS_DATA))
217 #define CHECK_WRITE(A,D) (outb(CMOS_REG, (A)), outb(CMOS_DATA, (D)))
218
219 #define CHECK_INIT(D);                          \
220         CHECK_WRITE(0x34, (D));                 \
221         CHECK_WRITE(0x35, (D));                 \
222         CHECK_WRITE(0x36, (D));                 \
223         CHECK_WRITE(0x37, (D));                 \
224         CHECK_WRITE(0x38, (D));                 \
225         CHECK_WRITE(0x39, (D));
226
227 #define CHECK_PRINT(S);                         \
228         kprintf("%s: %d, %d, %d, %d, %d, %d\n", \
229            (S),                                 \
230            CHECK_READ(0x34),                    \
231            CHECK_READ(0x35),                    \
232            CHECK_READ(0x36),                    \
233            CHECK_READ(0x37),                    \
234            CHECK_READ(0x38),                    \
235            CHECK_READ(0x39));
236
237 #else                           /* CHECK_POINTS */
238
239 #define CHECK_INIT(D)
240 #define CHECK_PRINT(S)
241
242 #endif                          /* CHECK_POINTS */
243
244 /*
245  * Values to send to the POST hardware.
246  */
247 #define MP_BOOTADDRESS_POST     0x10
248 #define MP_PROBE_POST           0x11
249 #define MPTABLE_PASS1_POST      0x12
250
251 #define MP_START_POST           0x13
252 #define MP_ENABLE_POST          0x14
253 #define MPTABLE_PASS2_POST      0x15
254
255 #define START_ALL_APS_POST      0x16
256 #define INSTALL_AP_TRAMP_POST   0x17
257 #define START_AP_POST           0x18
258
259 #define MP_ANNOUNCE_POST        0x19
260
261 /** XXX FIXME: where does this really belong, isa.h/isa.c perhaps? */
262 int     current_postcode;
263
264 /** XXX FIXME: what system files declare these??? */
265 extern struct region_descriptor r_gdt, r_idt;
266
267 int     mp_naps;                /* # of Applications processors */
268 extern  int nkpt;
269
270 u_int32_t cpu_apic_versions[MAXCPU];
271 int64_t tsc0_offset;
272 extern int64_t tsc_offsets[];
273
274 extern u_long ebda_addr;
275
276 #ifdef SMP /* APIC-IO */
277 struct apic_intmapinfo  int_to_apicintpin[APIC_INTMAPSIZE];
278 #endif
279
280 /*
281  * APIC ID logical/physical mapping structures.
282  * We oversize these to simplify boot-time config.
283  */
284 int     cpu_num_to_apic_id[NAPICID];
285 int     apic_id_to_logical[NAPICID];
286
287 /* AP uses this during bootstrap.  Do not staticize.  */
288 char *bootSTK;
289 static int bootAP;
290
291 /* Hotwire a 0->4MB V==P mapping */
292 extern pt_entry_t *KPTphys;
293
294 /*
295  * SMP page table page.  Setup by locore to point to a page table
296  * page from which we allocate per-cpu privatespace areas io_apics,
297  * and so forth.
298  */
299
300 #define IO_MAPPING_START_INDEX  \
301                 (SMP_MAXCPU * sizeof(struct privatespace) / PAGE_SIZE)
302
303 extern pt_entry_t *SMPpt;
304 static int SMPpt_alloc_index = IO_MAPPING_START_INDEX;
305
306 struct pcb stoppcbs[MAXCPU];
307
308 static basetable_entry basetable_entry_types[] =
309 {
310         {0, 20, "Processor"},
311         {1, 8, "Bus"},
312         {2, 8, "I/O APIC"},
313         {3, 8, "I/O INT"},
314         {4, 8, "Local INT"}
315 };
316
317 /*
318  * Local data and functions.
319  */
320
321 static u_int    boot_address;
322 static u_int    base_memory;
323 static int      mp_finish;
324 static int      mp_finish_lapic;
325
326 static void     mp_enable(u_int boot_addr);
327
328 static int      mptable_iterate_entries(const mpcth_t,
329                     mptable_iter_func, void *);
330 static int      mptable_search(void);
331 static int      mptable_search_sig(u_int32_t target, int count);
332 static int      mptable_hyperthread_fixup(cpumask_t, int);
333 static int      mptable_map(struct mptable_pos *);
334 static void     mptable_unmap(struct mptable_pos *);
335 static void     mptable_bus_info_alloc(const mpcth_t,
336                     struct mptable_bus_info *);
337 static void     mptable_bus_info_free(struct mptable_bus_info *);
338
339 static int      mptable_lapic_probe(struct lapic_enumerator *);
340 static void     mptable_lapic_enumerate(struct lapic_enumerator *);
341 static void     mptable_lapic_default(void);
342
343 static int      mptable_ioapic_probe(struct ioapic_enumerator *);
344 static void     mptable_ioapic_enumerate(struct ioapic_enumerator *);
345
346 static int      start_all_aps(u_int boot_addr);
347 static void     install_ap_tramp(u_int boot_addr);
348 static int      start_ap(struct mdglobaldata *gd, u_int boot_addr, int smibest);
349 static int      smitest(void);
350
351 static cpumask_t smp_startup_mask = 1;  /* which cpus have been started */
352 static cpumask_t smp_lapic_mask = 1;    /* which cpus have lapic been inited */
353 cpumask_t smp_active_mask = 1;  /* which cpus are ready for IPIs etc? */
354 SYSCTL_INT(_machdep, OID_AUTO, smp_active, CTLFLAG_RD, &smp_active_mask, 0, "");
355
356 int                     imcr_present;
357
358 static vm_paddr_t       mptable_fps_phyaddr;
359 static int              mptable_use_default;
360 static TAILQ_HEAD(mptable_pci_int_list, mptable_pci_int) mptable_pci_int_list =
361         TAILQ_HEAD_INITIALIZER(mptable_pci_int_list);
362 static TAILQ_HEAD(mptable_ioapic_list, mptable_ioapic) mptable_ioapic_list =
363         TAILQ_HEAD_INITIALIZER(mptable_ioapic_list);
364
365 /*
366  * Calculate usable address in base memory for AP trampoline code.
367  */
368 u_int
369 mp_bootaddress(u_int basemem)
370 {
371         POSTCODE(MP_BOOTADDRESS_POST);
372
373         base_memory = basemem;
374
375         boot_address = base_memory & ~0xfff;    /* round down to 4k boundary */
376         if ((base_memory - boot_address) < bootMP_size)
377                 boot_address -= 4096;   /* not enough, lower by 4k */
378
379         return boot_address;
380 }
381
382
383 static void
384 mptable_probe(void)
385 {
386         struct mptable_pos mpt;
387         int error;
388
389         KKASSERT(mptable_fps_phyaddr == 0);
390
391         mptable_fps_phyaddr = mptable_search();
392         if (mptable_fps_phyaddr == 0)
393                 return;
394
395         error = mptable_map(&mpt);
396         if (error) {
397                 mptable_fps_phyaddr = 0;
398                 return;
399         }
400
401         if (MPTABLE_POS_USE_DEFAULT(&mpt)) {
402                 kprintf("MPTABLE: use default configuration\n");
403                 mptable_use_default = 1;
404         }
405         if (mpt.mp_fps->mpfb2 & 0x80)
406                 imcr_present = 1;
407
408         mptable_unmap(&mpt);
409 }
410 SYSINIT(mptable_probe, SI_BOOT2_PRESMP, SI_ORDER_FIRST, mptable_probe, 0);
411
412 /*
413  * Look for an Intel MP spec table (ie, SMP capable hardware).
414  */
415 static int
416 mptable_search(void)
417 {
418         int     x;
419         u_int32_t target;
420  
421         /*
422          * Make sure our SMPpt[] page table is big enough to hold all the
423          * mappings we need.
424          */
425         KKASSERT(IO_MAPPING_START_INDEX < NPTEPG - 2);
426
427         POSTCODE(MP_PROBE_POST);
428
429         /* see if EBDA exists */
430         if (ebda_addr != 0) {
431                 /* search first 1K of EBDA */
432                 target = (u_int32_t)ebda_addr;
433                 if ((x = mptable_search_sig(target, 1024 / 4)) > 0)
434                         return x;
435         } else {
436                 /* last 1K of base memory, effective 'top of base' passed in */
437                 target = (u_int32_t)(base_memory - 0x400);
438                 if ((x = mptable_search_sig(target, 1024 / 4)) > 0)
439                         return x;
440         }
441
442         /* search the BIOS */
443         target = (u_int32_t)BIOS_BASE;
444         if ((x = mptable_search_sig(target, BIOS_COUNT)) > 0)
445                 return x;
446
447         /* search the extended BIOS */
448         target = (u_int32_t)BIOS_BASE2;
449         if ((x = mptable_search_sig(target, BIOS_COUNT)) > 0)
450                 return x;
451
452         /* nothing found */
453         return 0;
454 }
455
456 static int
457 mptable_iterate_entries(const mpcth_t cth, mptable_iter_func func, void *arg)
458 {
459         int count, total_size;
460         const void *position;
461
462         KKASSERT(cth->base_table_length >= sizeof(struct MPCTH));
463         total_size = cth->base_table_length - sizeof(struct MPCTH);
464         position = (const uint8_t *)cth + sizeof(struct MPCTH);
465         count = cth->entry_count;
466
467         while (count--) {
468                 int type, error;
469
470                 KKASSERT(total_size >= 0);
471                 if (total_size == 0) {
472                         kprintf("invalid base MP table, "
473                                 "entry count and length mismatch\n");
474                         return EINVAL;
475                 }
476
477                 type = *(const uint8_t *)position;
478                 switch (type) {
479                 case 0: /* processor_entry */
480                 case 1: /* bus_entry */
481                 case 2: /* io_apic_entry */
482                 case 3: /* int_entry */
483                 case 4: /* int_entry */
484                         break;
485                 default:
486                         kprintf("unknown base MP table entry type %d\n", type);
487                         return EINVAL;
488                 }
489
490                 if (total_size < basetable_entry_types[type].length) {
491                         kprintf("invalid base MP table length, "
492                                 "does not contain all entries\n");
493                         return EINVAL;
494                 }
495                 total_size -= basetable_entry_types[type].length;
496
497                 error = func(arg, position, type);
498                 if (error)
499                         return error;
500
501                 position = (const uint8_t *)position +
502                     basetable_entry_types[type].length;
503         }
504         return 0;
505 }
506
507
508 /*
509  * Startup the SMP processors.
510  */
511 void
512 mp_start(void)
513 {
514         POSTCODE(MP_START_POST);
515         mp_enable(boot_address);
516 }
517
518
519 /*
520  * Print various information about the SMP system hardware and setup.
521  */
522 void
523 mp_announce(void)
524 {
525         int     x;
526
527         POSTCODE(MP_ANNOUNCE_POST);
528
529         kprintf("DragonFly/MP: Multiprocessor motherboard\n");
530         kprintf(" cpu0 (BSP): apic id: %2d", CPU_TO_ID(0));
531         kprintf(", version: 0x%08x\n", cpu_apic_versions[0]);
532         for (x = 1; x <= mp_naps; ++x) {
533                 kprintf(" cpu%d (AP):  apic id: %2d", x, CPU_TO_ID(x));
534                 kprintf(", version: 0x%08x\n", cpu_apic_versions[x]);
535         }
536
537         if (!apic_io_enable)
538                 kprintf(" Warning: APIC I/O disabled\n");
539 }
540
541 /*
542  * AP cpu's call this to sync up protected mode.
543  *
544  * WARNING!  We must ensure that the cpu is sufficiently initialized to
545  * be able to use to the FP for our optimized bzero/bcopy code before
546  * we enter more mainstream C code.
547  *
548  * WARNING! %fs is not set up on entry.  This routine sets up %fs.
549  */
550 void
551 init_secondary(void)
552 {
553         int     gsel_tss;
554         int     x, myid = bootAP;
555         u_int   cr0;
556         struct mdglobaldata *md;
557         struct privatespace *ps;
558
559         ps = &CPU_prvspace[myid];
560
561         gdt_segs[GPRIV_SEL].ssd_base = (int)ps;
562         gdt_segs[GPROC0_SEL].ssd_base =
563                 (int) &ps->mdglobaldata.gd_common_tss;
564         ps->mdglobaldata.mi.gd_prvspace = ps;
565
566         for (x = 0; x < NGDT; x++) {
567                 ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
568         }
569
570         r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
571         r_gdt.rd_base = (int) &gdt[myid * NGDT];
572         lgdt(&r_gdt);                   /* does magic intra-segment return */
573
574         lidt(&r_idt);
575
576         lldt(_default_ldt);
577         mdcpu->gd_currentldt = _default_ldt;
578
579         gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
580         gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS;
581
582         md = mdcpu;     /* loaded through %fs:0 (mdglobaldata.mi.gd_prvspace)*/
583
584         md->gd_common_tss.tss_esp0 = 0; /* not used until after switch */
585         md->gd_common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
586         md->gd_common_tss.tss_ioopt = (sizeof md->gd_common_tss) << 16;
587         md->gd_tss_gdt = &gdt[myid * NGDT + GPROC0_SEL].sd;
588         md->gd_common_tssd = *md->gd_tss_gdt;
589         ltr(gsel_tss);
590
591         /*
592          * Set to a known state:
593          * Set by mpboot.s: CR0_PG, CR0_PE
594          * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
595          */
596         cr0 = rcr0();
597         cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
598         load_cr0(cr0);
599         pmap_set_opt();         /* PSE/4MB pages, etc */
600
601         /* set up CPU registers and state */
602         cpu_setregs();
603
604         /* set up FPU state on the AP */
605         npxinit(__INITIAL_NPXCW__);
606
607         /* set up SSE registers */
608         enable_sse();
609 }
610
611 /*******************************************************************
612  * local functions and data
613  */
614
615 /*
616  * start the SMP system
617  */
618 static void
619 mp_enable(u_int boot_addr)
620 {
621         POSTCODE(MP_ENABLE_POST);
622
623         lapic_config();
624
625         /* Initialize BSP's local APIC */
626         lapic_init(TRUE);
627
628         /* start each Application Processor */
629         start_all_aps(boot_addr);
630
631         if (apic_io_enable)
632                 ioapic_config();
633
634         /* Finalize PIC */
635         MachIntrABI.finalize();
636 }
637
638
639 /*
640  * look for the MP spec signature
641  */
642
643 /* string defined by the Intel MP Spec as identifying the MP table */
644 #define MP_SIG          0x5f504d5f      /* _MP_ */
645 #define NEXT(X)         ((X) += 4)
646 static int
647 mptable_search_sig(u_int32_t target, int count)
648 {
649         vm_size_t map_size;
650         u_int32_t *addr;
651         int x, ret;
652
653         KKASSERT(target != 0);
654
655         map_size = count * sizeof(u_int32_t);
656         addr = pmap_mapdev((vm_paddr_t)target, map_size);
657
658         ret = 0;
659         for (x = 0; x < count; NEXT(x)) {
660                 if (addr[x] == MP_SIG) {
661                         /* make array index a byte index */
662                         ret = target + (x * sizeof(u_int32_t));
663                         break;
664                 }
665         }
666
667         pmap_unmapdev((vm_offset_t)addr, map_size);
668         return ret;
669 }
670
671 static int processor_entry      (const struct PROCENTRY *entry, int cpu);
672
673 /*
674  * Check if we should perform a hyperthreading "fix-up" to
675  * enumerate any logical CPU's that aren't already listed
676  * in the table.
677  *
678  * XXX: We assume that all of the physical CPUs in the
679  * system have the same number of logical CPUs.
680  *
681  * XXX: We assume that APIC ID's are allocated such that
682  * the APIC ID's for a physical processor are aligned
683  * with the number of logical CPU's in the processor.
684  */
685 static int
686 mptable_hyperthread_fixup(cpumask_t id_mask, int cpu_count)
687 {
688         int i, id, lcpus_max, logical_cpus;
689
690         if ((cpu_feature & CPUID_HTT) == 0)
691                 return 0;
692
693         lcpus_max = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
694         if (lcpus_max <= 1)
695                 return 0;
696
697         if (cpu_vendor_id == CPU_VENDOR_INTEL) {
698                 /*
699                  * INSTRUCTION SET REFERENCE, A-M (#253666)
700                  * Page 3-181, Table 3-20
701                  * "The nearest power-of-2 integer that is not smaller
702                  *  than EBX[23:16] is the number of unique initial APIC
703                  *  IDs reserved for addressing different logical
704                  *  processors in a physical package."
705                  */
706                 for (i = 0; ; ++i) {
707                         if ((1 << i) >= lcpus_max) {
708                                 lcpus_max = 1 << i;
709                                 break;
710                         }
711                 }
712         }
713
714         KKASSERT(cpu_count != 0);
715         if (cpu_count == lcpus_max) {
716                 /* We have nothing to fix */
717                 return 0;
718         } else if (cpu_count == 1) {
719                 /* XXX this may be incorrect */
720                 logical_cpus = lcpus_max;
721         } else {
722                 int cur, prev, dist;
723
724                 /*
725                  * Calculate the distances between two nearest
726                  * APIC IDs.  If all such distances are same,
727                  * then it is the number of missing cpus that
728                  * we are going to fill later.
729                  */
730                 dist = cur = prev = -1;
731                 for (id = 0; id < MAXCPU; ++id) {
732                         if ((id_mask & CPUMASK(id)) == 0)
733                                 continue;
734
735                         cur = id;
736                         if (prev >= 0) {
737                                 int new_dist = cur - prev;
738
739                                 if (dist < 0)
740                                         dist = new_dist;
741
742                                 /*
743                                  * Make sure that all distances
744                                  * between two nearest APIC IDs
745                                  * are same.
746                                  */
747                                 if (dist != new_dist)
748                                         return 0;
749                         }
750                         prev = cur;
751                 }
752                 if (dist == 1)
753                         return 0;
754
755                 /* Must be power of 2 */
756                 if (dist & (dist - 1))
757                         return 0;
758
759                 /* Can't exceed CPU package capacity */
760                 if (dist > lcpus_max)
761                         logical_cpus = lcpus_max;
762                 else
763                         logical_cpus = dist;
764         }
765
766         /*
767          * For each APIC ID of a CPU that is set in the mask,
768          * scan the other candidate APIC ID's for this
769          * physical processor.  If any of those ID's are
770          * already in the table, then kill the fixup.
771          */
772         for (id = 0; id < MAXCPU; id++) {
773                 if ((id_mask & CPUMASK(id)) == 0)
774                         continue;
775                 /* First, make sure we are on a logical_cpus boundary. */
776                 if (id % logical_cpus != 0)
777                         return 0;
778                 for (i = id + 1; i < id + logical_cpus; i++)
779                         if ((id_mask & CPUMASK(i)) != 0)
780                                 return 0;
781         }
782         return logical_cpus;
783 }
784
785 static int
786 mptable_map(struct mptable_pos *mpt)
787 {
788         mpfps_t fps = NULL;
789         mpcth_t cth = NULL;
790         vm_size_t cth_mapsz = 0;
791
792         KKASSERT(mptable_fps_phyaddr != 0);
793
794         bzero(mpt, sizeof(*mpt));
795
796         fps = pmap_mapdev(mptable_fps_phyaddr, sizeof(*fps));
797         if (fps->pap != 0) {
798                 /*
799                  * Map configuration table header to get
800                  * the base table size
801                  */
802                 cth = pmap_mapdev(fps->pap, sizeof(*cth));
803                 cth_mapsz = cth->base_table_length;
804                 pmap_unmapdev((vm_offset_t)cth, sizeof(*cth));
805
806                 if (cth_mapsz < sizeof(*cth)) {
807                         kprintf("invalid base MP table length %d\n",
808                                 (int)cth_mapsz);
809                         pmap_unmapdev((vm_offset_t)fps, sizeof(*fps));
810                         return EINVAL;
811                 }
812
813                 /*
814                  * Map the base table
815                  */
816                 cth = pmap_mapdev(fps->pap, cth_mapsz);
817         }
818
819         mpt->mp_fps = fps;
820         mpt->mp_cth = cth;
821         mpt->mp_cth_mapsz = cth_mapsz;
822
823         return 0;
824 }
825
826 static void
827 mptable_unmap(struct mptable_pos *mpt)
828 {
829         if (mpt->mp_cth != NULL) {
830                 pmap_unmapdev((vm_offset_t)mpt->mp_cth, mpt->mp_cth_mapsz);
831                 mpt->mp_cth = NULL;
832                 mpt->mp_cth_mapsz = 0;
833         }
834         if (mpt->mp_fps != NULL) {
835                 pmap_unmapdev((vm_offset_t)mpt->mp_fps, sizeof(*mpt->mp_fps));
836                 mpt->mp_fps = NULL;
837         }
838 }
839
840 void
841 mp_set_cpuids(int cpu_id, int apic_id)
842 {
843         CPU_TO_ID(cpu_id) = apic_id;
844         ID_TO_CPU(apic_id) = cpu_id;
845 }
846
847 static int
848 processor_entry(const struct PROCENTRY *entry, int cpu)
849 {
850         KKASSERT(cpu > 0);
851
852         /* check for usability */
853         if (!(entry->cpu_flags & PROCENTRY_FLAG_EN))
854                 return 0;
855
856         /* check for BSP flag */
857         if (entry->cpu_flags & PROCENTRY_FLAG_BP) {
858                 mp_set_cpuids(0, entry->apic_id);
859                 return 0;       /* its already been counted */
860         }
861
862         /* add another AP to list, if less than max number of CPUs */
863         else if (cpu < MAXCPU) {
864                 mp_set_cpuids(cpu, entry->apic_id);
865                 return 1;
866         }
867
868         return 0;
869 }
870
871 /*
872  * Map a physical memory address representing I/O into KVA.  The I/O
873  * block is assumed not to cross a page boundary.
874  */
875 void *
876 ioapic_map(vm_paddr_t pa)
877 {
878         vm_offset_t vaddr;
879         int pgeflag;
880         int i;
881
882         KKASSERT(pa < 0x100000000LL);
883
884         pgeflag = 0;    /* not used for SMP yet */
885
886         /*
887          * If the requested physical address has already been incidently
888          * mapped, just use the existing mapping.  Otherwise create a new
889          * mapping.
890          */
891         for (i = IO_MAPPING_START_INDEX; i < SMPpt_alloc_index; ++i) {
892                 if (((vm_offset_t)SMPpt[i] & PG_FRAME) ==
893                     ((vm_offset_t)pa & PG_FRAME)) {
894                         break;
895                 }
896         }
897         if (i == SMPpt_alloc_index) {
898                 if (i == NPTEPG - 2) {
899                         panic("permanent_io_mapping: We ran out of space"
900                               " in SMPpt[]!");
901                 }
902                 SMPpt[i] = (pt_entry_t)(PG_V | PG_RW | PG_N | pgeflag |
903                            ((vm_offset_t)pa & PG_FRAME));
904                 ++SMPpt_alloc_index;
905         }
906         vaddr = (vm_offset_t)CPU_prvspace + (i * PAGE_SIZE) +
907                 ((vm_offset_t)pa & PAGE_MASK);
908         return ((void *)vaddr);
909 }
910
911 /*
912  * start each AP in our list
913  */
914 static int
915 start_all_aps(u_int boot_addr)
916 {
917         int     x, i, pg;
918         int     shift;
919         int     smicount;
920         int     smibest;
921         int     smilast;
922         u_char  mpbiosreason;
923         u_long  mpbioswarmvec;
924         struct mdglobaldata *gd;
925         struct privatespace *ps;
926         char *stack;
927         uintptr_t kptbase;
928
929         POSTCODE(START_ALL_APS_POST);
930
931         /* install the AP 1st level boot code */
932         install_ap_tramp(boot_addr);
933
934
935         /* save the current value of the warm-start vector */
936         mpbioswarmvec = *((u_long *) WARMBOOT_OFF);
937         outb(CMOS_REG, BIOS_RESET);
938         mpbiosreason = inb(CMOS_DATA);
939
940         /* setup a vector to our boot code */
941         *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
942         *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4);
943         outb(CMOS_REG, BIOS_RESET);
944         outb(CMOS_DATA, BIOS_WARM);     /* 'warm-start' */
945
946         /*
947          * If we have a TSC we can figure out the SMI interrupt rate.
948          * The SMI does not necessarily use a constant rate.  Spend
949          * up to 250ms trying to figure it out.
950          */
951         smibest = 0;
952         if (cpu_feature & CPUID_TSC) {
953                 set_apic_timer(275000);
954                 smilast = read_apic_timer();
955                 for (x = 0; x < 20 && read_apic_timer(); ++x) {
956                         smicount = smitest();
957                         if (smibest == 0 || smilast - smicount < smibest)
958                                 smibest = smilast - smicount;
959                         smilast = smicount;
960                 }
961                 if (smibest > 250000)
962                         smibest = 0;
963                 if (smibest) {
964                         smibest = smibest * (int64_t)1000000 /
965                                   get_apic_timer_frequency();
966                 }
967         }
968         if (smibest)
969                 kprintf("SMI Frequency (worst case): %d Hz (%d us)\n",
970                         1000000 / smibest, smibest);
971
972
973         /* set up temporary P==V mapping for AP boot */
974         /* XXX this is a hack, we should boot the AP on its own stack/PTD */
975         kptbase = (uintptr_t)(void *)KPTphys;
976         for (x = 0; x < NKPT; x++) {
977                 PTD[x] = (pd_entry_t)(PG_V | PG_RW |
978                     ((kptbase + x * PAGE_SIZE) & PG_FRAME));
979         }
980         cpu_invltlb();
981
982         /* start each AP */
983         for (x = 1; x <= mp_naps; ++x) {
984
985                 /* This is a bit verbose, it will go away soon.  */
986
987                 /* first page of AP's private space */
988                 pg = x * i386_btop(sizeof(struct privatespace));
989
990                 /* allocate new private data page(s) */
991                 gd = (struct mdglobaldata *)kmem_alloc(&kernel_map, 
992                                 MDGLOBALDATA_BASEALLOC_SIZE);
993                 /* wire it into the private page table page */
994                 for (i = 0; i < MDGLOBALDATA_BASEALLOC_SIZE; i += PAGE_SIZE) {
995                         SMPpt[pg + i / PAGE_SIZE] = (pt_entry_t)
996                             (PG_V | PG_RW | vtophys_pte((char *)gd + i));
997                 }
998                 pg += MDGLOBALDATA_BASEALLOC_PAGES;
999
1000                 SMPpt[pg + 0] = 0;              /* *gd_CMAP1 */
1001                 SMPpt[pg + 1] = 0;              /* *gd_CMAP2 */
1002                 SMPpt[pg + 2] = 0;              /* *gd_CMAP3 */
1003                 SMPpt[pg + 3] = 0;              /* *gd_PMAP1 */
1004
1005                 /* allocate and set up an idle stack data page */
1006                 stack = (char *)kmem_alloc(&kernel_map, UPAGES*PAGE_SIZE);
1007                 for (i = 0; i < UPAGES; i++) {
1008                         SMPpt[pg + 4 + i] = (pt_entry_t)
1009                             (PG_V | PG_RW | vtophys_pte(PAGE_SIZE * i + stack));
1010                 }
1011
1012                 gd = &CPU_prvspace[x].mdglobaldata;     /* official location */
1013                 bzero(gd, sizeof(*gd));
1014                 gd->mi.gd_prvspace = ps = &CPU_prvspace[x];
1015
1016                 /* prime data page for it to use */
1017                 mi_gdinit(&gd->mi, x);
1018                 cpu_gdinit(gd, x);
1019                 gd->gd_CMAP1 = &SMPpt[pg + 0];
1020                 gd->gd_CMAP2 = &SMPpt[pg + 1];
1021                 gd->gd_CMAP3 = &SMPpt[pg + 2];
1022                 gd->gd_PMAP1 = &SMPpt[pg + 3];
1023                 gd->gd_CADDR1 = ps->CPAGE1;
1024                 gd->gd_CADDR2 = ps->CPAGE2;
1025                 gd->gd_CADDR3 = ps->CPAGE3;
1026                 gd->gd_PADDR1 = (unsigned *)ps->PPAGE1;
1027
1028                 /*
1029                  * Per-cpu pmap for get_ptbase().
1030                  */
1031                 gd->gd_GDADDR1= (unsigned *)
1032                         kmem_alloc_nofault(&kernel_map, SEG_SIZE, SEG_SIZE);
1033                 gd->gd_GDMAP1 = &PTD[(vm_offset_t)gd->gd_GDADDR1 >> PDRSHIFT];
1034
1035                 gd->mi.gd_ipiq = (void *)kmem_alloc(&kernel_map, sizeof(lwkt_ipiq) * (mp_naps + 1));
1036                 bzero(gd->mi.gd_ipiq, sizeof(lwkt_ipiq) * (mp_naps + 1));
1037
1038                 /*
1039                  * Setup the AP boot stack
1040                  */
1041                 bootSTK = &ps->idlestack[UPAGES*PAGE_SIZE/2];
1042                 bootAP = x;
1043
1044                 /* attempt to start the Application Processor */
1045                 CHECK_INIT(99); /* setup checkpoints */
1046                 if (!start_ap(gd, boot_addr, smibest)) {
1047                         kprintf("AP #%d (PHY# %d) failed!\n", x, CPU_TO_ID(x));
1048                         CHECK_PRINT("trace");   /* show checkpoints */
1049                         /* better panic as the AP may be running loose */
1050                         kprintf("panic y/n? [y] ");
1051                         if (cngetc() != 'n')
1052                                 panic("bye-bye");
1053                 }
1054                 CHECK_PRINT("trace");           /* show checkpoints */
1055
1056                 /* record its version info */
1057                 cpu_apic_versions[x] = cpu_apic_versions[0];
1058         }
1059
1060         /* set ncpus to 1 + highest logical cpu.  Not all may have come up */
1061         ncpus = x;
1062
1063         /* ncpus2 -- ncpus rounded down to the nearest power of 2 */
1064         for (shift = 0; (1 << shift) <= ncpus; ++shift)
1065                 ;
1066         --shift;
1067         ncpus2_shift = shift;
1068         ncpus2 = 1 << shift;
1069         ncpus2_mask = ncpus2 - 1;
1070
1071         /* ncpus_fit -- ncpus rounded up to the nearest power of 2 */
1072         if ((1 << shift) < ncpus)
1073                 ++shift;
1074         ncpus_fit = 1 << shift;
1075         ncpus_fit_mask = ncpus_fit - 1;
1076
1077         /* build our map of 'other' CPUs */
1078         mycpu->gd_other_cpus = smp_startup_mask & ~CPUMASK(mycpu->gd_cpuid);
1079         mycpu->gd_ipiq = (void *)kmem_alloc(&kernel_map, sizeof(lwkt_ipiq) * ncpus);
1080         bzero(mycpu->gd_ipiq, sizeof(lwkt_ipiq) * ncpus);
1081
1082         /* fill in our (BSP) APIC version */
1083         cpu_apic_versions[0] = lapic.version;
1084
1085         /* restore the warmstart vector */
1086         *(u_long *) WARMBOOT_OFF = mpbioswarmvec;
1087         outb(CMOS_REG, BIOS_RESET);
1088         outb(CMOS_DATA, mpbiosreason);
1089
1090         /*
1091          * NOTE!  The idlestack for the BSP was setup by locore.  Finish
1092          * up, clean out the P==V mapping we did earlier.
1093          */
1094         for (x = 0; x < NKPT; x++)
1095                 PTD[x] = 0;
1096         pmap_set_opt();
1097
1098         /*
1099          * Wait all APs to finish initializing LAPIC
1100          */
1101         mp_finish_lapic = 1;
1102         if (bootverbose)
1103                 kprintf("SMP: Waiting APs LAPIC initialization\n");
1104         if (cpu_feature & CPUID_TSC)
1105                 tsc0_offset = rdtsc();
1106         tsc_offsets[0] = 0;
1107         rel_mplock();
1108         while (smp_lapic_mask != smp_startup_mask) {
1109                 cpu_lfence();
1110                 if (cpu_feature & CPUID_TSC)
1111                         tsc0_offset = rdtsc();
1112         }
1113         while (try_mplock() == 0)
1114                 ;
1115
1116         /* number of APs actually started */
1117         return ncpus - 1;
1118 }
1119
1120 /*
1121  * load the 1st level AP boot code into base memory.
1122  */
1123
1124 /* targets for relocation */
1125 extern void bigJump(void);
1126 extern void bootCodeSeg(void);
1127 extern void bootDataSeg(void);
1128 extern void MPentry(void);
1129 extern u_int MP_GDT;
1130 extern u_int mp_gdtbase;
1131
1132 static void
1133 install_ap_tramp(u_int boot_addr)
1134 {
1135         int     x;
1136         int     size = *(int *) ((u_long) & bootMP_size);
1137         u_char *src = (u_char *) ((u_long) bootMP);
1138         u_char *dst = (u_char *) boot_addr + KERNBASE;
1139         u_int   boot_base = (u_int) bootMP;
1140         u_int8_t *dst8;
1141         u_int16_t *dst16;
1142         u_int32_t *dst32;
1143
1144         POSTCODE(INSTALL_AP_TRAMP_POST);
1145
1146         for (x = 0; x < size; ++x)
1147                 *dst++ = *src++;
1148
1149         /*
1150          * modify addresses in code we just moved to basemem. unfortunately we
1151          * need fairly detailed info about mpboot.s for this to work.  changes
1152          * to mpboot.s might require changes here.
1153          */
1154
1155         /* boot code is located in KERNEL space */
1156         dst = (u_char *) boot_addr + KERNBASE;
1157
1158         /* modify the lgdt arg */
1159         dst32 = (u_int32_t *) (dst + ((u_int) & mp_gdtbase - boot_base));
1160         *dst32 = boot_addr + ((u_int) & MP_GDT - boot_base);
1161
1162         /* modify the ljmp target for MPentry() */
1163         dst32 = (u_int32_t *) (dst + ((u_int) bigJump - boot_base) + 1);
1164         *dst32 = ((u_int) MPentry - KERNBASE);
1165
1166         /* modify the target for boot code segment */
1167         dst16 = (u_int16_t *) (dst + ((u_int) bootCodeSeg - boot_base));
1168         dst8 = (u_int8_t *) (dst16 + 1);
1169         *dst16 = (u_int) boot_addr & 0xffff;
1170         *dst8 = ((u_int) boot_addr >> 16) & 0xff;
1171
1172         /* modify the target for boot data segment */
1173         dst16 = (u_int16_t *) (dst + ((u_int) bootDataSeg - boot_base));
1174         dst8 = (u_int8_t *) (dst16 + 1);
1175         *dst16 = (u_int) boot_addr & 0xffff;
1176         *dst8 = ((u_int) boot_addr >> 16) & 0xff;
1177 }
1178
1179
1180 /*
1181  * This function starts the AP (application processor) identified
1182  * by the APIC ID 'physicalCpu'.  It does quite a "song and dance"
1183  * to accomplish this.  This is necessary because of the nuances
1184  * of the different hardware we might encounter.  It ain't pretty,
1185  * but it seems to work.
1186  *
1187  * NOTE: eventually an AP gets to ap_init(), which is called just 
1188  * before the AP goes into the LWKT scheduler's idle loop.
1189  */
1190 static int
1191 start_ap(struct mdglobaldata *gd, u_int boot_addr, int smibest)
1192 {
1193         int     physical_cpu;
1194         int     vector;
1195         u_long  icr_lo, icr_hi;
1196
1197         POSTCODE(START_AP_POST);
1198
1199         /* get the PHYSICAL APIC ID# */
1200         physical_cpu = CPU_TO_ID(gd->mi.gd_cpuid);
1201
1202         /* calculate the vector */
1203         vector = (boot_addr >> 12) & 0xff;
1204
1205         /* We don't want anything interfering */
1206         cpu_disable_intr();
1207
1208         /* Make sure the target cpu sees everything */
1209         wbinvd();
1210
1211         /*
1212          * Try to detect when a SMI has occurred, wait up to 200ms.
1213          *
1214          * If a SMI occurs during an AP reset but before we issue
1215          * the STARTUP command, the AP may brick.  To work around
1216          * this problem we hold off doing the AP startup until
1217          * after we have detected the SMI.  Hopefully another SMI
1218          * will not occur before we finish the AP startup.
1219          *
1220          * Retries don't seem to help.  SMIs have a window of opportunity
1221          * and if USB->legacy keyboard emulation is enabled in the BIOS
1222          * the interrupt rate can be quite high.
1223          *
1224          * NOTE: Don't worry about the L1 cache load, it might bloat
1225          *       ldelta a little but ndelta will be so huge when the SMI
1226          *       occurs the detection logic will still work fine.
1227          */
1228         if (smibest) {
1229                 set_apic_timer(200000);
1230                 smitest();
1231         }
1232
1233         /*
1234          * first we do an INIT/RESET IPI this INIT IPI might be run, reseting
1235          * and running the target CPU. OR this INIT IPI might be latched (P5
1236          * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be
1237          * ignored.
1238          *
1239          * see apic/apicreg.h for icr bit definitions.
1240          *
1241          * TIME CRITICAL CODE, DO NOT DO ANY KPRINTFS IN THE HOT PATH.
1242          */
1243
1244         /*
1245          * Setup the address for the target AP.  We can setup
1246          * icr_hi once and then just trigger operations with
1247          * icr_lo.
1248          */
1249         icr_hi = lapic.icr_hi & ~APIC_ID_MASK;
1250         icr_hi |= (physical_cpu << 24);
1251         icr_lo = lapic.icr_lo & 0xfff00000;
1252         lapic.icr_hi = icr_hi;
1253
1254         /*
1255          * Do an INIT IPI: assert RESET
1256          *
1257          * Use edge triggered mode to assert INIT
1258          */
1259         lapic.icr_lo = icr_lo | 0x0000c500;
1260         while (lapic.icr_lo & APIC_DELSTAT_MASK)
1261                  /* spin */ ;
1262
1263         /*
1264          * The spec calls for a 10ms delay but we may have to use a
1265          * MUCH lower delay to avoid bricking an AP due to a fast SMI
1266          * interrupt.  We have other loops here too and dividing by 2
1267          * doesn't seem to be enough even after subtracting 350us,
1268          * so we divide by 4.
1269          *
1270          * Our minimum delay is 150uS, maximum is 10ms.  If no SMI
1271          * interrupt was detected we use the full 10ms.
1272          */
1273         if (smibest == 0)
1274                 u_sleep(10000);
1275         else if (smibest < 150 * 4 + 350)
1276                 u_sleep(150);
1277         else if ((smibest - 350) / 4 < 10000)
1278                 u_sleep((smibest - 350) / 4);
1279         else
1280                 u_sleep(10000);
1281
1282         /*
1283          * Do an INIT IPI: deassert RESET
1284          *
1285          * Use level triggered mode to deassert.  It is unclear
1286          * why we need to do this.
1287          */
1288         lapic.icr_lo = icr_lo | 0x00008500;
1289         while (lapic.icr_lo & APIC_DELSTAT_MASK)
1290                  /* spin */ ;
1291         u_sleep(150);                           /* wait 150us */
1292
1293         /*
1294          * Next we do a STARTUP IPI: the previous INIT IPI might still be
1295          * latched, (P5 bug) this 1st STARTUP would then terminate
1296          * immediately, and the previously started INIT IPI would continue. OR
1297          * the previous INIT IPI has already run. and this STARTUP IPI will
1298          * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
1299          * will run.
1300          */
1301         lapic.icr_lo = icr_lo | 0x00000600 | vector;
1302         while (lapic.icr_lo & APIC_DELSTAT_MASK)
1303                  /* spin */ ;
1304         u_sleep(200);           /* wait ~200uS */
1305
1306         /*
1307          * Finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
1308          * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
1309          * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
1310          * recognized after hardware RESET or INIT IPI.
1311          */
1312         lapic.icr_lo = icr_lo | 0x00000600 | vector;
1313         while (lapic.icr_lo & APIC_DELSTAT_MASK)
1314                  /* spin */ ;
1315
1316         /* Resume normal operation */
1317         cpu_enable_intr();
1318
1319         /* wait for it to start, see ap_init() */
1320         set_apic_timer(5000000);/* == 5 seconds */
1321         while (read_apic_timer()) {
1322                 if (smp_startup_mask & CPUMASK(gd->mi.gd_cpuid))
1323                         return 1;       /* return SUCCESS */
1324         }
1325
1326         return 0;               /* return FAILURE */
1327 }
1328
1329 static
1330 int
1331 smitest(void)
1332 {
1333         int64_t ltsc;
1334         int64_t ntsc;
1335         int64_t ldelta;
1336         int64_t ndelta;
1337         int count;
1338
1339         ldelta = 0;
1340         ndelta = 0;
1341         while (read_apic_timer()) {
1342                 ltsc = rdtsc();
1343                 for (count = 0; count < 100; ++count)
1344                         ntsc = rdtsc(); /* force loop to occur */
1345                 if (ldelta) {
1346                         ndelta = ntsc - ltsc;
1347                         if (ldelta > ndelta)
1348                                 ldelta = ndelta;
1349                         if (ndelta > ldelta * 2)
1350                                 break;
1351                 } else {
1352                         ldelta = ntsc - ltsc;
1353                 }
1354         }
1355         return(read_apic_timer());
1356 }
1357
1358 /*
1359  * Lazy flush the TLB on all other CPU's.  DEPRECATED.
1360  *
1361  * If for some reason we were unable to start all cpus we cannot safely
1362  * use broadcast IPIs.
1363  */
1364
1365 static cpumask_t smp_invltlb_req;
1366 #define SMP_INVLTLB_DEBUG
1367
1368 void
1369 smp_invltlb(void)
1370 {
1371 #ifdef SMP
1372         struct mdglobaldata *md = mdcpu;
1373 #ifdef SMP_INVLTLB_DEBUG
1374         long count = 0;
1375         long xcount = 0;
1376 #endif
1377
1378         crit_enter_gd(&md->mi);
1379         md->gd_invltlb_ret = 0;
1380         ++md->mi.gd_cnt.v_smpinvltlb;
1381         atomic_set_cpumask(&smp_invltlb_req, md->mi.gd_cpumask);
1382 #ifdef SMP_INVLTLB_DEBUG
1383 again:
1384 #endif
1385         if (smp_startup_mask == smp_active_mask) {
1386                 all_but_self_ipi(XINVLTLB_OFFSET);
1387         } else {
1388                 selected_apic_ipi(smp_active_mask & ~md->mi.gd_cpumask,
1389                                   XINVLTLB_OFFSET, APIC_DELMODE_FIXED);
1390         }
1391
1392 #ifdef SMP_INVLTLB_DEBUG
1393         if (xcount)
1394                 kprintf("smp_invltlb: ipi sent\n");
1395 #endif
1396         while ((md->gd_invltlb_ret & smp_active_mask & ~md->mi.gd_cpumask) !=
1397                (smp_active_mask & ~md->mi.gd_cpumask)) {
1398                 cpu_mfence();
1399                 cpu_pause();
1400 #ifdef SMP_INVLTLB_DEBUG
1401                 /* DEBUGGING */
1402                 if (++count == 400000000) {
1403                         print_backtrace(-1);
1404                         kprintf("smp_invltlb: endless loop %08lx %08lx, "
1405                                 "rflags %016lx retry",
1406                                 (long)md->gd_invltlb_ret,
1407                                 (long)smp_invltlb_req,
1408                                 (long)read_eflags());
1409                         __asm __volatile ("sti");
1410                         ++xcount;
1411                         if (xcount > 2)
1412                                 lwkt_process_ipiq();
1413                         if (xcount > 3) {
1414                                 int bcpu = BSFCPUMASK(~md->gd_invltlb_ret &
1415                                                       ~md->mi.gd_cpumask &
1416                                                       smp_active_mask);
1417                                 globaldata_t xgd;
1418                                 kprintf("bcpu %d\n", bcpu);
1419                                 xgd = globaldata_find(bcpu);
1420                                 kprintf("thread %p %s\n", xgd->gd_curthread, xgd->gd_curthread->td_comm);
1421                         }
1422                         if (xcount > 5)
1423                                 panic("giving up");
1424                         count = 0;
1425                         goto again;
1426                 }
1427 #endif
1428         }
1429         atomic_clear_cpumask(&smp_invltlb_req, md->mi.gd_cpumask);
1430         crit_exit_gd(&md->mi);
1431 #endif
1432 }
1433
1434 #ifdef SMP
1435
1436 /*
1437  * Called from Xinvltlb assembly with interrupts disabled.  We didn't
1438  * bother to bump the critical section count or nested interrupt count
1439  * so only do very low level operations here.
1440  */
1441 void
1442 smp_invltlb_intr(void)
1443 {
1444         struct mdglobaldata *md = mdcpu;
1445         struct mdglobaldata *omd;
1446         cpumask_t mask;
1447         int cpu;
1448
1449         mask = smp_invltlb_req;
1450         cpu_mfence();
1451         cpu_invltlb();
1452         while (mask) {
1453                 cpu = BSFCPUMASK(mask);
1454                 mask &= ~CPUMASK(cpu);
1455                 omd = (struct mdglobaldata *)globaldata_find(cpu);
1456                 atomic_set_cpumask(&omd->gd_invltlb_ret, md->mi.gd_cpumask);
1457         }
1458 }
1459
1460 #endif
1461
1462 /*
1463  * When called the executing CPU will send an IPI to all other CPUs
1464  *  requesting that they halt execution.
1465  *
1466  * Usually (but not necessarily) called with 'other_cpus' as its arg.
1467  *
1468  *  - Signals all CPUs in map to stop.
1469  *  - Waits for each to stop.
1470  *
1471  * Returns:
1472  *  -1: error
1473  *   0: NA
1474  *   1: ok
1475  *
1476  * XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
1477  *            from executing at same time.
1478  */
1479 int
1480 stop_cpus(cpumask_t map)
1481 {
1482         map &= smp_active_mask;
1483
1484         /* send the Xcpustop IPI to all CPUs in map */
1485         selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
1486         
1487         while ((stopped_cpus & map) != map)
1488                 /* spin */ ;
1489
1490         return 1;
1491 }
1492
1493
1494 /*
1495  * Called by a CPU to restart stopped CPUs. 
1496  *
1497  * Usually (but not necessarily) called with 'stopped_cpus' as its arg.
1498  *
1499  *  - Signals all CPUs in map to restart.
1500  *  - Waits for each to restart.
1501  *
1502  * Returns:
1503  *  -1: error
1504  *   0: NA
1505  *   1: ok
1506  */
1507 int
1508 restart_cpus(cpumask_t map)
1509 {
1510         /* signal other cpus to restart */
1511         started_cpus = map & smp_active_mask;
1512
1513         while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
1514                 /* spin */ ;
1515
1516         return 1;
1517 }
1518
1519 /*
1520  * This is called once the mpboot code has gotten us properly relocated
1521  * and the MMU turned on, etc.   ap_init() is actually the idle thread,
1522  * and when it returns the scheduler will call the real cpu_idle() main
1523  * loop for the idlethread.  Interrupts are disabled on entry and should
1524  * remain disabled at return.
1525  */
1526 void
1527 ap_init(void)
1528 {
1529         u_int   apic_id;
1530
1531         /*
1532          * Adjust smp_startup_mask to signal the BSP that we have started
1533          * up successfully.  Note that we do not yet hold the BGL.  The BSP
1534          * is waiting for our signal.
1535          *
1536          * We can't set our bit in smp_active_mask yet because we are holding
1537          * interrupts physically disabled and remote cpus could deadlock
1538          * trying to send us an IPI.
1539          */
1540         smp_startup_mask |= CPUMASK(mycpu->gd_cpuid);
1541         cpu_mfence();
1542
1543         /*
1544          * Interlock for LAPIC initialization.  Wait until mp_finish_lapic is
1545          * non-zero, then get the MP lock.
1546          *
1547          * Note: We are in a critical section.
1548          *
1549          * Note: we are the idle thread, we can only spin.
1550          *
1551          * Note: The load fence is memory volatile and prevents the compiler
1552          * from improperly caching mp_finish_lapic, and the cpu from improperly
1553          * caching it.
1554          */
1555         while (mp_finish_lapic == 0)
1556                 cpu_lfence();
1557         while (try_mplock() == 0)
1558                 ;
1559
1560         if (cpu_feature & CPUID_TSC) {
1561                 /*
1562                  * The BSP is constantly updating tsc0_offset, figure out
1563                  * the relative difference to synchronize ktrdump.
1564                  */
1565                 tsc_offsets[mycpu->gd_cpuid] = rdtsc() - tsc0_offset;
1566         }
1567
1568         /* BSP may have changed PTD while we're waiting for the lock */
1569         cpu_invltlb();
1570
1571 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
1572         lidt(&r_idt);
1573 #endif
1574
1575         /* Build our map of 'other' CPUs. */
1576         mycpu->gd_other_cpus = smp_startup_mask & ~CPUMASK(mycpu->gd_cpuid);
1577
1578         /* A quick check from sanity claus */
1579         apic_id = (apic_id_to_logical[(lapic.id & 0xff000000) >> 24]);
1580         if (mycpu->gd_cpuid != apic_id) {
1581                 kprintf("SMP: cpuid = %d\n", mycpu->gd_cpuid);
1582                 kprintf("SMP: apic_id = %d\n", apic_id);
1583                 kprintf("PTD[MPPTDI] = %p\n", (void *)PTD[MPPTDI]);
1584                 panic("cpuid mismatch! boom!!");
1585         }
1586
1587         /* Initialize AP's local APIC for irq's */
1588         lapic_init(FALSE);
1589
1590         /* LAPIC initialization is done */
1591         smp_lapic_mask |= CPUMASK(mycpu->gd_cpuid);
1592         cpu_mfence();
1593
1594         /* Let BSP move onto the next initialization stage */
1595         rel_mplock();
1596
1597         /*
1598          * Interlock for finalization.  Wait until mp_finish is non-zero,
1599          * then get the MP lock.
1600          *
1601          * Note: We are in a critical section.
1602          *
1603          * Note: we are the idle thread, we can only spin.
1604          *
1605          * Note: The load fence is memory volatile and prevents the compiler
1606          * from improperly caching mp_finish, and the cpu from improperly
1607          * caching it.
1608          */
1609         while (mp_finish == 0)
1610                 cpu_lfence();
1611         while (try_mplock() == 0)
1612                 ;
1613
1614         /* BSP may have changed PTD while we're waiting for the lock */
1615         cpu_invltlb();
1616
1617         /* Set memory range attributes for this CPU to match the BSP */
1618         mem_range_AP_init();
1619
1620         /*
1621          * Once we go active we must process any IPIQ messages that may
1622          * have been queued, because no actual IPI will occur until we
1623          * set our bit in the smp_active_mask.  If we don't the IPI
1624          * message interlock could be left set which would also prevent
1625          * further IPIs.
1626          *
1627          * The idle loop doesn't expect the BGL to be held and while
1628          * lwkt_switch() normally cleans things up this is a special case
1629          * because we returning almost directly into the idle loop.
1630          *
1631          * The idle thread is never placed on the runq, make sure
1632          * nothing we've done put it there.
1633          */
1634         KKASSERT(get_mplock_count(curthread) == 1);
1635         smp_active_mask |= CPUMASK(mycpu->gd_cpuid);
1636
1637         /*
1638          * Enable interrupts here.  idle_restore will also do it, but
1639          * doing it here lets us clean up any strays that got posted to
1640          * the CPU during the AP boot while we are still in a critical
1641          * section.
1642          */
1643         __asm __volatile("sti; pause; pause"::);
1644         bzero(mdcpu->gd_ipending, sizeof(mdcpu->gd_ipending));
1645
1646         initclocks_pcpu();      /* clock interrupts (via IPIs) */
1647         lwkt_process_ipiq();
1648
1649         /*
1650          * Releasing the mp lock lets the BSP finish up the SMP init
1651          */
1652         rel_mplock();
1653         KKASSERT((curthread->td_flags & TDF_RUNQ) == 0);
1654 }
1655
1656 /*
1657  * Get SMP fully working before we start initializing devices.
1658  */
1659 static
1660 void
1661 ap_finish(void)
1662 {
1663         mp_finish = 1;
1664         if (bootverbose)
1665                 kprintf("Finish MP startup\n");
1666         rel_mplock();
1667         while (smp_active_mask != smp_startup_mask)
1668                 cpu_lfence();
1669         while (try_mplock() == 0)
1670                 ;
1671         if (bootverbose)
1672                 kprintf("Active CPU Mask: %08x\n", smp_active_mask);
1673 }
1674
1675 SYSINIT(finishsmp, SI_BOOT2_FINISH_SMP, SI_ORDER_FIRST, ap_finish, NULL)
1676
1677 void
1678 cpu_send_ipiq(int dcpu)
1679 {
1680         if (CPUMASK(dcpu) & smp_active_mask)
1681                 single_apic_ipi(dcpu, XIPIQ_OFFSET, APIC_DELMODE_FIXED);
1682 }
1683
1684 #if 0   /* single_apic_ipi_passive() not working yet */
1685 /*
1686  * Returns 0 on failure, 1 on success
1687  */
1688 int
1689 cpu_send_ipiq_passive(int dcpu)
1690 {
1691         int r = 0;
1692         if (CPUMASK(dcpu) & smp_active_mask) {
1693                 r = single_apic_ipi_passive(dcpu, XIPIQ_OFFSET,
1694                                         APIC_DELMODE_FIXED);
1695         }
1696         return(r);
1697 }
1698 #endif
1699
1700 static int
1701 mptable_bus_info_callback(void *xarg, const void *pos, int type)
1702 {
1703         struct mptable_bus_info *bus_info = xarg;
1704         const struct BUSENTRY *ent;
1705         struct mptable_bus *bus;
1706
1707         if (type != 1)
1708                 return 0;
1709
1710         ent = pos;
1711         TAILQ_FOREACH(bus, &bus_info->mbi_list, mb_link) {
1712                 if (bus->mb_id == ent->bus_id) {
1713                         kprintf("mptable_bus_info_alloc: duplicated bus id "
1714                                 "(%d)\n", bus->mb_id);
1715                         return EINVAL;
1716                 }
1717         }
1718
1719         bus = NULL;
1720         if (strncmp(ent->bus_type, "PCI", 3) == 0) {
1721                 bus = kmalloc(sizeof(*bus), M_TEMP, M_WAITOK | M_ZERO);
1722                 bus->mb_type = MPTABLE_BUS_PCI;
1723         } else if (strncmp(ent->bus_type, "ISA", 3) == 0) {
1724                 bus = kmalloc(sizeof(*bus), M_TEMP, M_WAITOK | M_ZERO);
1725                 bus->mb_type = MPTABLE_BUS_ISA;
1726         }
1727
1728         if (bus != NULL) {
1729                 bus->mb_id = ent->bus_id;
1730                 TAILQ_INSERT_TAIL(&bus_info->mbi_list, bus, mb_link);
1731         }
1732         return 0;
1733 }
1734
1735 static void
1736 mptable_bus_info_alloc(const mpcth_t cth, struct mptable_bus_info *bus_info)
1737 {
1738         int error;
1739
1740         bzero(bus_info, sizeof(*bus_info));
1741         TAILQ_INIT(&bus_info->mbi_list);
1742
1743         error = mptable_iterate_entries(cth, mptable_bus_info_callback, bus_info);
1744         if (error)
1745                 mptable_bus_info_free(bus_info);
1746 }
1747
1748 static void
1749 mptable_bus_info_free(struct mptable_bus_info *bus_info)
1750 {
1751         struct mptable_bus *bus;
1752
1753         while ((bus = TAILQ_FIRST(&bus_info->mbi_list)) != NULL) {
1754                 TAILQ_REMOVE(&bus_info->mbi_list, bus, mb_link);
1755                 kfree(bus, M_TEMP);
1756         }
1757 }
1758
1759 struct mptable_lapic_cbarg1 {
1760         int     cpu_count;
1761         int     ht_fixup;
1762         u_int   ht_apicid_mask;
1763 };
1764
1765 static int
1766 mptable_lapic_pass1_callback(void *xarg, const void *pos, int type)
1767 {
1768         const struct PROCENTRY *ent;
1769         struct mptable_lapic_cbarg1 *arg = xarg;
1770
1771         if (type != 0)
1772                 return 0;
1773         ent = pos;
1774
1775         if ((ent->cpu_flags & PROCENTRY_FLAG_EN) == 0)
1776                 return 0;
1777
1778         arg->cpu_count++;
1779         if (ent->apic_id < 32) {
1780                 arg->ht_apicid_mask |= 1 << ent->apic_id;
1781         } else if (arg->ht_fixup) {
1782                 kprintf("MPTABLE: lapic id > 32, disable HTT fixup\n");
1783                 arg->ht_fixup = 0;
1784         }
1785         return 0;
1786 }
1787
1788 struct mptable_lapic_cbarg2 {
1789         int     cpu;
1790         int     logical_cpus;
1791         int     found_bsp;
1792 };
1793
1794 static int
1795 mptable_lapic_pass2_callback(void *xarg, const void *pos, int type)
1796 {
1797         const struct PROCENTRY *ent;
1798         struct mptable_lapic_cbarg2 *arg = xarg;
1799
1800         if (type != 0)
1801                 return 0;
1802         ent = pos;
1803
1804         if (ent->cpu_flags & PROCENTRY_FLAG_BP) {
1805                 KKASSERT(!arg->found_bsp);
1806                 arg->found_bsp = 1;
1807         }
1808
1809         if (processor_entry(ent, arg->cpu))
1810                 arg->cpu++;
1811
1812         if (arg->logical_cpus) {
1813                 struct PROCENTRY proc;
1814                 int i;
1815
1816                 /*
1817                  * Create fake mptable processor entries
1818                  * and feed them to processor_entry() to
1819                  * enumerate the logical CPUs.
1820                  */
1821                 bzero(&proc, sizeof(proc));
1822                 proc.type = 0;
1823                 proc.cpu_flags = PROCENTRY_FLAG_EN;
1824                 proc.apic_id = ent->apic_id;
1825
1826                 for (i = 1; i < arg->logical_cpus; i++) {
1827                         proc.apic_id++;
1828                         processor_entry(&proc, arg->cpu);
1829                         arg->cpu++;
1830                 }
1831         }
1832         return 0;
1833 }
1834
1835 static void
1836 mptable_lapic_default(void)
1837 {
1838         int ap_apicid, bsp_apicid;
1839
1840         mp_naps = 1; /* exclude BSP */
1841
1842         /* Map local apic before the id field is accessed */
1843         lapic_map(DEFAULT_APIC_BASE);
1844
1845         bsp_apicid = APIC_ID(lapic.id);
1846         ap_apicid = (bsp_apicid == 0) ? 1 : 0;
1847
1848         /* BSP */
1849         mp_set_cpuids(0, bsp_apicid);
1850         /* one and only AP */
1851         mp_set_cpuids(1, ap_apicid);
1852 }
1853
1854 /*
1855  * Configure:
1856  *     mp_naps
1857  *     ID_TO_CPU(N), APIC ID to logical CPU table
1858  *     CPU_TO_ID(N), logical CPU to APIC ID table
1859  */
1860 static void
1861 mptable_lapic_enumerate(struct lapic_enumerator *e)
1862 {
1863         struct mptable_pos mpt;
1864         struct mptable_lapic_cbarg1 arg1;
1865         struct mptable_lapic_cbarg2 arg2;
1866         mpcth_t cth;
1867         int error, logical_cpus = 0;
1868         vm_offset_t lapic_addr;
1869
1870         if (mptable_use_default) {
1871                 mptable_lapic_default();
1872                 return;
1873         }
1874
1875         error = mptable_map(&mpt);
1876         if (error)
1877                 panic("mptable_lapic_enumerate mptable_map failed\n");
1878         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
1879
1880         cth = mpt.mp_cth;
1881
1882         /* Save local apic address */
1883         lapic_addr = (vm_offset_t)cth->apic_address;
1884         KKASSERT(lapic_addr != 0);
1885
1886         /*
1887          * Find out how many CPUs do we have
1888          */
1889         bzero(&arg1, sizeof(arg1));
1890         arg1.ht_fixup = 1; /* Apply ht fixup by default */
1891
1892         error = mptable_iterate_entries(cth,
1893                     mptable_lapic_pass1_callback, &arg1);
1894         if (error)
1895                 panic("mptable_iterate_entries(lapic_pass1) failed\n");
1896         KKASSERT(arg1.cpu_count != 0);
1897
1898         /* See if we need to fixup HT logical CPUs. */
1899         if (arg1.ht_fixup) {
1900                 logical_cpus = mptable_hyperthread_fixup(arg1.ht_apicid_mask,
1901                                                          arg1.cpu_count);
1902                 if (logical_cpus != 0)
1903                         arg1.cpu_count *= logical_cpus;
1904         }
1905         mp_naps = arg1.cpu_count;
1906
1907         /* Qualify the numbers again, after possible HT fixup */
1908         if (mp_naps > MAXCPU) {
1909                 kprintf("Warning: only using %d of %d available CPUs!\n",
1910                         MAXCPU, mp_naps);
1911                 mp_naps = MAXCPU;
1912         }
1913
1914         --mp_naps;      /* subtract the BSP */
1915
1916         /*
1917          * Link logical CPU id to local apic id
1918          */
1919         bzero(&arg2, sizeof(arg2));
1920         arg2.cpu = 1;
1921         arg2.logical_cpus = logical_cpus;
1922
1923         error = mptable_iterate_entries(cth,
1924                     mptable_lapic_pass2_callback, &arg2);
1925         if (error)
1926                 panic("mptable_iterate_entries(lapic_pass2) failed\n");
1927         KKASSERT(arg2.found_bsp);
1928
1929         /* Map local apic */
1930         lapic_map(lapic_addr);
1931
1932         mptable_unmap(&mpt);
1933 }
1934
1935 struct mptable_lapic_probe_cbarg {
1936         int     cpu_count;
1937         int     found_bsp;
1938 };
1939
1940 static int
1941 mptable_lapic_probe_callback(void *xarg, const void *pos, int type)
1942 {
1943         const struct PROCENTRY *ent;
1944         struct mptable_lapic_probe_cbarg *arg = xarg;
1945
1946         if (type != 0)
1947                 return 0;
1948         ent = pos;
1949
1950         if ((ent->cpu_flags & PROCENTRY_FLAG_EN) == 0)
1951                 return 0;
1952         arg->cpu_count++;
1953
1954         if (ent->cpu_flags & PROCENTRY_FLAG_BP) {
1955                 if (arg->found_bsp) {
1956                         kprintf("more than one BSP in base MP table\n");
1957                         return EINVAL;
1958                 }
1959                 arg->found_bsp = 1;
1960         }
1961         return 0;
1962 }
1963
1964 static int
1965 mptable_lapic_probe(struct lapic_enumerator *e)
1966 {
1967         struct mptable_pos mpt;
1968         struct mptable_lapic_probe_cbarg arg;
1969         mpcth_t cth;
1970         int error;
1971
1972         if (mptable_fps_phyaddr == 0)
1973                 return ENXIO;
1974
1975         if (mptable_use_default)
1976                 return 0;
1977
1978         error = mptable_map(&mpt);
1979         if (error)
1980                 return error;
1981         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
1982
1983         error = EINVAL;
1984         cth = mpt.mp_cth;
1985
1986         if (cth->apic_address == 0)
1987                 goto done;
1988
1989         bzero(&arg, sizeof(arg));
1990         error = mptable_iterate_entries(cth,
1991                     mptable_lapic_probe_callback, &arg);
1992         if (!error) {
1993                 if (arg.cpu_count == 0) {
1994                         kprintf("MP table contains no processor entries\n");
1995                         error = EINVAL;
1996                 } else if (!arg.found_bsp) {
1997                         kprintf("MP table does not contains BSP entry\n");
1998                         error = EINVAL;
1999                 }
2000         }
2001 done:
2002         mptable_unmap(&mpt);
2003         return error;
2004 }
2005
2006 static struct lapic_enumerator  mptable_lapic_enumerator = {
2007         .lapic_prio = LAPIC_ENUM_PRIO_MPTABLE,
2008         .lapic_probe = mptable_lapic_probe,
2009         .lapic_enumerate = mptable_lapic_enumerate
2010 };
2011
2012 static void
2013 mptable_lapic_enum_register(void)
2014 {
2015         lapic_enumerator_register(&mptable_lapic_enumerator);
2016 }
2017 SYSINIT(mptable_lapic, SI_BOOT2_PRESMP, SI_ORDER_ANY,
2018         mptable_lapic_enum_register, 0);
2019
2020 static int
2021 mptable_ioapic_list_callback(void *xarg, const void *pos, int type)
2022 {
2023         const struct IOAPICENTRY *ent;
2024         struct mptable_ioapic *nioapic, *ioapic;
2025
2026         if (type != 2)
2027                 return 0;
2028         ent = pos;
2029
2030         if ((ent->apic_flags & IOAPICENTRY_FLAG_EN) == 0)
2031                 return 0;
2032
2033         if (ent->apic_address == 0) {
2034                 kprintf("mptable_ioapic_create_list: zero IOAPIC addr\n");
2035                 return EINVAL;
2036         }
2037
2038         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
2039                 if (ioapic->mio_apic_id == ent->apic_id) {
2040                         kprintf("mptable_ioapic_create_list: duplicated "
2041                                 "apic id %d\n", ioapic->mio_apic_id);
2042                         return EINVAL;
2043                 }
2044                 if (ioapic->mio_addr == (uint32_t)ent->apic_address) {
2045                         kprintf("mptable_ioapic_create_list: overlapped "
2046                                 "IOAPIC addr 0x%08x", ioapic->mio_addr);
2047                         return EINVAL;
2048                 }
2049         }
2050
2051         nioapic = kmalloc(sizeof(*nioapic), M_DEVBUF, M_WAITOK | M_ZERO);
2052         nioapic->mio_apic_id = ent->apic_id;
2053         nioapic->mio_addr = (uint32_t)ent->apic_address;
2054
2055         /*
2056          * Create IOAPIC list in ascending order of APIC ID
2057          */
2058         TAILQ_FOREACH_REVERSE(ioapic, &mptable_ioapic_list,
2059             mptable_ioapic_list, mio_link) {
2060                 if (nioapic->mio_apic_id > ioapic->mio_apic_id) {
2061                         TAILQ_INSERT_AFTER(&mptable_ioapic_list,
2062                             ioapic, nioapic, mio_link);
2063                         break;
2064                 }
2065         }
2066         if (ioapic == NULL)
2067                 TAILQ_INSERT_HEAD(&mptable_ioapic_list, nioapic, mio_link);
2068
2069         return 0;
2070 }
2071
2072 static void
2073 mptable_ioapic_create_list(void)
2074 {
2075         struct mptable_ioapic *ioapic;
2076         struct mptable_pos mpt;
2077         int idx, error;
2078
2079         if (mptable_fps_phyaddr == 0)
2080                 return;
2081
2082         if (mptable_use_default) {
2083                 ioapic = kmalloc(sizeof(*ioapic), M_DEVBUF, M_WAITOK | M_ZERO);
2084                 ioapic->mio_idx = 0;
2085                 ioapic->mio_apic_id = 0;        /* NOTE: any value is ok here */
2086                 ioapic->mio_addr = 0xfec00000;  /* XXX magic number */
2087
2088                 TAILQ_INSERT_HEAD(&mptable_ioapic_list, ioapic, mio_link);
2089                 return;
2090         }
2091
2092         error = mptable_map(&mpt);
2093         if (error)
2094                 panic("mptable_ioapic_create_list: mptable_map failed\n");
2095         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
2096
2097         error = mptable_iterate_entries(mpt.mp_cth,
2098                     mptable_ioapic_list_callback, NULL);
2099         if (error) {
2100                 while ((ioapic = TAILQ_FIRST(&mptable_ioapic_list)) != NULL) {
2101                         TAILQ_REMOVE(&mptable_ioapic_list, ioapic, mio_link);
2102                         kfree(ioapic, M_DEVBUF);
2103                 }
2104                 goto done;
2105         }
2106
2107         /*
2108          * Assign index number for each IOAPIC
2109          */
2110         idx = 0;
2111         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
2112                 ioapic->mio_idx = idx;
2113                 ++idx;
2114         }
2115 done:
2116         mptable_unmap(&mpt);
2117 }
2118 SYSINIT(mptable_ioapic_list, SI_BOOT2_PRESMP, SI_ORDER_SECOND,
2119         mptable_ioapic_create_list, 0);
2120
2121 static int
2122 mptable_pci_int_callback(void *xarg, const void *pos, int type)
2123 {
2124         const struct mptable_bus_info *bus_info = xarg;
2125         const struct mptable_ioapic *ioapic;
2126         const struct mptable_bus *bus;
2127         struct mptable_pci_int *pci_int;
2128         const struct INTENTRY *ent;
2129         int pci_pin, pci_dev;
2130
2131         if (type != 3)
2132                 return 0;
2133         ent = pos;
2134
2135         if (ent->int_type != 0)
2136                 return 0;
2137
2138         TAILQ_FOREACH(bus, &bus_info->mbi_list, mb_link) {
2139                 if (bus->mb_type == MPTABLE_BUS_PCI &&
2140                     bus->mb_id == ent->src_bus_id)
2141                         break;
2142         }
2143         if (bus == NULL)
2144                 return 0;
2145
2146         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
2147                 if (ioapic->mio_apic_id == ent->dst_apic_id)
2148                         break;
2149         }
2150         if (ioapic == NULL) {
2151                 kprintf("MPTABLE: warning PCI int dst apic id %d "
2152                         "does not exist\n", ent->dst_apic_id);
2153                 return 0;
2154         }
2155
2156         pci_pin = ent->src_bus_irq & 0x3;
2157         pci_dev = (ent->src_bus_irq >> 2) & 0x1f;
2158
2159         TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link) {
2160                 if (pci_int->mpci_bus == ent->src_bus_id &&
2161                     pci_int->mpci_dev == pci_dev &&
2162                     pci_int->mpci_pin == pci_pin) {
2163                         if (pci_int->mpci_ioapic_idx == ioapic->mio_idx &&
2164                             pci_int->mpci_ioapic_pin == ent->dst_apic_int) {
2165                                 kprintf("MPTABLE: warning duplicated "
2166                                         "PCI int entry for "
2167                                         "bus %d, dev %d, pin %d\n",
2168                                         pci_int->mpci_bus,
2169                                         pci_int->mpci_dev,
2170                                         pci_int->mpci_pin);
2171                                 return 0;
2172                         } else {
2173                                 kprintf("mptable_pci_int_register: "
2174                                         "conflict PCI int entry for "
2175                                         "bus %d, dev %d, pin %d, "
2176                                         "IOAPIC %d.%d -> %d.%d\n",
2177                                         pci_int->mpci_bus,
2178                                         pci_int->mpci_dev,
2179                                         pci_int->mpci_pin,
2180                                         pci_int->mpci_ioapic_idx,
2181                                         pci_int->mpci_ioapic_pin,
2182                                         ioapic->mio_idx,
2183                                         ent->dst_apic_int);
2184                                 return EINVAL;
2185                         }
2186                 }
2187         }
2188
2189         pci_int = kmalloc(sizeof(*pci_int), M_DEVBUF, M_WAITOK | M_ZERO);
2190
2191         pci_int->mpci_bus = ent->src_bus_id;
2192         pci_int->mpci_dev = pci_dev;
2193         pci_int->mpci_pin = pci_pin;
2194         pci_int->mpci_ioapic_idx = ioapic->mio_idx;
2195         pci_int->mpci_ioapic_pin = ent->dst_apic_int;
2196
2197         TAILQ_INSERT_TAIL(&mptable_pci_int_list, pci_int, mpci_link);
2198
2199         return 0;
2200 }
2201
2202 static void
2203 mptable_pci_int_register(void)
2204 {
2205         struct mptable_bus_info bus_info;
2206         const struct mptable_bus *bus;
2207         struct mptable_pci_int *pci_int;
2208         struct mptable_pos mpt;
2209         int error, force_pci0, npcibus;
2210         mpcth_t cth;
2211
2212         if (mptable_fps_phyaddr == 0)
2213                 return;
2214
2215         if (mptable_use_default)
2216                 return;
2217
2218         if (TAILQ_EMPTY(&mptable_ioapic_list))
2219                 return;
2220
2221         error = mptable_map(&mpt);
2222         if (error)
2223                 panic("mptable_pci_int_register: mptable_map failed\n");
2224         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
2225
2226         cth = mpt.mp_cth;
2227
2228         mptable_bus_info_alloc(cth, &bus_info);
2229         if (TAILQ_EMPTY(&bus_info.mbi_list))
2230                 goto done;
2231
2232         force_pci0 = 0;
2233         npcibus = 0;
2234         TAILQ_FOREACH(bus, &bus_info.mbi_list, mb_link) {
2235                 if (bus->mb_type == MPTABLE_BUS_PCI)
2236                         ++npcibus;
2237         }
2238         if (npcibus == 0) {
2239                 mptable_bus_info_free(&bus_info);
2240                 goto done;
2241         } else if (npcibus == 1) {
2242                 force_pci0 = 1;
2243         }
2244
2245         error = mptable_iterate_entries(cth,
2246                     mptable_pci_int_callback, &bus_info);
2247
2248         mptable_bus_info_free(&bus_info);
2249
2250         if (error) {
2251                 while ((pci_int = TAILQ_FIRST(&mptable_pci_int_list)) != NULL) {
2252                         TAILQ_REMOVE(&mptable_pci_int_list, pci_int, mpci_link);
2253                         kfree(pci_int, M_DEVBUF);
2254                 }
2255                 goto done;
2256         }
2257
2258         if (force_pci0) {
2259                 TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link)
2260                         pci_int->mpci_bus = 0;
2261         }
2262 done:
2263         mptable_unmap(&mpt);
2264 }
2265 SYSINIT(mptable_pci, SI_BOOT2_PRESMP, SI_ORDER_ANY,
2266         mptable_pci_int_register, 0);
2267
2268 struct mptable_ioapic_probe_cbarg {
2269         const struct mptable_bus_info *bus_info;
2270 };
2271
2272 static int
2273 mptable_ioapic_probe_callback(void *xarg, const void *pos, int type)
2274 {
2275         struct mptable_ioapic_probe_cbarg *arg = xarg;
2276         const struct mptable_ioapic *ioapic;
2277         const struct mptable_bus *bus;
2278         const struct INTENTRY *ent;
2279
2280         if (type != 3)
2281                 return 0;
2282         ent = pos;
2283
2284         if (ent->int_type != 0)
2285                 return 0;
2286
2287         TAILQ_FOREACH(bus, &arg->bus_info->mbi_list, mb_link) {
2288                 if (bus->mb_type == MPTABLE_BUS_ISA &&
2289                     bus->mb_id == ent->src_bus_id)
2290                         break;
2291         }
2292         if (bus == NULL)
2293                 return 0;
2294
2295         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
2296                 if (ioapic->mio_apic_id == ent->dst_apic_id)
2297                         break;
2298         }
2299         if (ioapic == NULL) {
2300                 kprintf("MPTABLE: warning ISA int dst apic id %d "
2301                         "does not exist\n", ent->dst_apic_id);
2302                 return 0;
2303         }
2304
2305         /* XXX magic number */
2306         if (ent->src_bus_irq >= 16) {
2307                 kprintf("mptable_ioapic_probe: invalid ISA irq (%d)\n",
2308                         ent->src_bus_irq);
2309                 return EINVAL;
2310         }
2311         return 0;
2312 }
2313
2314 static int
2315 mptable_ioapic_probe(struct ioapic_enumerator *e)
2316 {
2317         struct mptable_ioapic_probe_cbarg arg;
2318         struct mptable_bus_info bus_info;
2319         struct mptable_pos mpt;
2320         mpcth_t cth;
2321         int error;
2322
2323         if (mptable_fps_phyaddr == 0)
2324                 return ENXIO;
2325
2326         if (mptable_use_default)
2327                 return 0;
2328
2329         if (TAILQ_EMPTY(&mptable_ioapic_list))
2330                 return ENXIO;
2331
2332         error = mptable_map(&mpt);
2333         if (error)
2334                 panic("mptable_ioapic_probe: mptable_map failed\n");
2335         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
2336
2337         cth = mpt.mp_cth;
2338
2339         mptable_bus_info_alloc(cth, &bus_info);
2340
2341         bzero(&arg, sizeof(arg));
2342         arg.bus_info = &bus_info;
2343
2344         error = mptable_iterate_entries(cth,
2345                     mptable_ioapic_probe_callback, &arg);
2346
2347         mptable_bus_info_free(&bus_info);
2348         mptable_unmap(&mpt);
2349
2350         return error;
2351 }
2352
2353 struct mptable_ioapic_int_cbarg {
2354         const struct mptable_bus_info *bus_info;
2355         int     ioapic_nint;
2356 };
2357
2358 static int
2359 mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
2360 {
2361         struct mptable_ioapic_int_cbarg *arg = xarg;
2362         const struct mptable_ioapic *ioapic;
2363         const struct mptable_bus *bus;
2364         const struct INTENTRY *ent;
2365         int gsi;
2366
2367         if (type != 3)
2368                 return 0;
2369
2370         arg->ioapic_nint++;
2371
2372         ent = pos;
2373         if (ent->int_type != 0)
2374                 return 0;
2375
2376         TAILQ_FOREACH(bus, &arg->bus_info->mbi_list, mb_link) {
2377                 if (bus->mb_type == MPTABLE_BUS_ISA &&
2378                     bus->mb_id == ent->src_bus_id)
2379                         break;
2380         }
2381         if (bus == NULL)
2382                 return 0;
2383
2384         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
2385                 if (ioapic->mio_apic_id == ent->dst_apic_id)
2386                         break;
2387         }
2388         if (ioapic == NULL) {
2389                 kprintf("MPTABLE: warning ISA int dst apic id %d "
2390                         "does not exist\n", ent->dst_apic_id);
2391                 return 0;
2392         }
2393
2394         if (ent->dst_apic_int >= ioapic->mio_npin) {
2395                 panic("mptable_ioapic_enumerate: invalid I/O APIC "
2396                       "pin %d, should be < %d",
2397                       ent->dst_apic_int, ioapic->mio_npin);
2398         }
2399         gsi = ioapic->mio_gsi_base + ent->dst_apic_int;
2400
2401         if (ent->src_bus_irq != gsi) {
2402                 if (bootverbose) {
2403                         kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
2404                                 ent->src_bus_irq, gsi);
2405                 }
2406                 ioapic_intsrc(ent->src_bus_irq, gsi,
2407                     INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
2408         }
2409         return 0;
2410 }
2411
2412 static void
2413 mptable_ioapic_enumerate(struct ioapic_enumerator *e)
2414 {
2415         struct mptable_bus_info bus_info;
2416         struct mptable_ioapic *ioapic;
2417         struct mptable_pos mpt;
2418         mpcth_t cth;
2419         int error;
2420
2421         KKASSERT(mptable_fps_phyaddr != 0);
2422         KKASSERT(!TAILQ_EMPTY(&mptable_ioapic_list));
2423
2424         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
2425                 const struct mptable_ioapic *prev_ioapic;
2426                 uint32_t ver;
2427                 void *addr;
2428
2429                 addr = ioapic_map(ioapic->mio_addr);
2430
2431                 ver = ioapic_read(addr, IOAPIC_VER);
2432                 ioapic->mio_npin = ((ver & IOART_VER_MAXREDIR)
2433                                     >> MAXREDIRSHIFT) + 1;
2434
2435                 prev_ioapic = TAILQ_PREV(ioapic,
2436                                 mptable_ioapic_list, mio_link);
2437                 if (prev_ioapic == NULL) {
2438                         ioapic->mio_gsi_base = 0;
2439                 } else {
2440                         ioapic->mio_gsi_base =
2441                                 prev_ioapic->mio_gsi_base +
2442                                 prev_ioapic->mio_npin;
2443                 }
2444                 ioapic_add(addr, ioapic->mio_gsi_base,
2445                     ioapic->mio_npin);
2446
2447                 if (bootverbose) {
2448                         kprintf("MPTABLE: IOAPIC addr 0x%08x, "
2449                                 "apic id %d, idx %d, gsi base %d, npin %d\n",
2450                                 ioapic->mio_addr,
2451                                 ioapic->mio_apic_id,
2452                                 ioapic->mio_idx,
2453                                 ioapic->mio_gsi_base,
2454                                 ioapic->mio_npin);
2455                 }
2456         }
2457
2458         if (mptable_use_default) {
2459                 if (bootverbose)
2460                         kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (default)\n");
2461                 ioapic_intsrc(0, 2, INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
2462                 return;
2463         }
2464
2465         error = mptable_map(&mpt);
2466         if (error)
2467                 panic("mptable_ioapic_probe: mptable_map failed\n");
2468         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
2469
2470         cth = mpt.mp_cth;
2471
2472         mptable_bus_info_alloc(cth, &bus_info);
2473
2474         if (TAILQ_EMPTY(&bus_info.mbi_list)) {
2475                 if (bootverbose)
2476                         kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (no bus)\n");
2477                 ioapic_intsrc(0, 2, INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
2478         } else {
2479                 struct mptable_ioapic_int_cbarg arg;
2480
2481                 bzero(&arg, sizeof(arg));
2482                 arg.bus_info = &bus_info;
2483
2484                 error = mptable_iterate_entries(cth,
2485                             mptable_ioapic_int_callback, &arg);
2486                 if (error)
2487                         panic("mptable_ioapic_int failed\n");
2488
2489                 if (arg.ioapic_nint == 0) {
2490                         if (bootverbose) {
2491                                 kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 "
2492                                         "(no int)\n");
2493                         }
2494                         ioapic_intsrc(0, 2, INTR_TRIGGER_EDGE,
2495                             INTR_POLARITY_HIGH);
2496                 }
2497         }
2498
2499         mptable_bus_info_free(&bus_info);
2500
2501         mptable_unmap(&mpt);
2502 }
2503
2504 static struct ioapic_enumerator mptable_ioapic_enumerator = {
2505         .ioapic_prio = IOAPIC_ENUM_PRIO_MPTABLE,
2506         .ioapic_probe = mptable_ioapic_probe,
2507         .ioapic_enumerate = mptable_ioapic_enumerate
2508 };
2509
2510 static void
2511 mptable_ioapic_enum_register(void)
2512 {
2513         ioapic_enumerator_register(&mptable_ioapic_enumerator);
2514 }
2515 SYSINIT(mptable_ioapic, SI_BOOT2_PRESMP, SI_ORDER_ANY,
2516         mptable_ioapic_enum_register, 0);
2517
2518 void
2519 mptable_pci_int_dump(void)
2520 {
2521         const struct mptable_pci_int *pci_int;
2522
2523         TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link) {
2524                 kprintf("MPTABLE: %d:%d INT%c -> IOAPIC %d.%d\n",
2525                         pci_int->mpci_bus,
2526                         pci_int->mpci_dev,
2527                         pci_int->mpci_pin + 'A',
2528                         pci_int->mpci_ioapic_idx,
2529                         pci_int->mpci_ioapic_pin);
2530         }
2531 }
2532
2533 int
2534 mptable_pci_int_route(int bus, int dev, int pin, int intline)
2535 {
2536         const struct mptable_pci_int *pci_int;
2537         int irq = -1;
2538
2539         KKASSERT(pin >= 1);
2540         --pin;  /* zero based */
2541
2542         TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link) {
2543                 if (pci_int->mpci_bus == bus &&
2544                     pci_int->mpci_dev == dev &&
2545                     pci_int->mpci_pin == pin)
2546                         break;
2547         }
2548         if (pci_int != NULL) {
2549                 int gsi;
2550
2551                 gsi = ioapic_gsi(pci_int->mpci_ioapic_idx,
2552                         pci_int->mpci_ioapic_pin);
2553                 if (gsi >= 0) {
2554                         irq = ioapic_abi_find_gsi(gsi,
2555                                 INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
2556                 }
2557         }
2558
2559         if (irq < 0) {
2560                 if (bootverbose) {
2561                         kprintf("MPTABLE: fixed interrupt routing "
2562                                 "for %d:%d INT%c\n", bus, dev, pin + 'A');
2563                 }
2564
2565                 irq = ioapic_abi_find_irq(intline,
2566                         INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
2567         }
2568
2569         if (irq >= 0 && bootverbose) {
2570                 kprintf("MPTABLE: %d:%d INT%c routed to irq %d\n",
2571                         bus, dev, pin + 'A', irq);
2572         }
2573         return irq;
2574 }