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