ioapic: Allow interrupt trigger mode override in MADT
[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  * $DragonFly: src/sys/platform/pc32/i386/mp_machdep.c,v 1.60 2008/06/07 12:03:52 mneumann Exp $
27  */
28
29 #include "opt_cpu.h"
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/sysctl.h>
35 #include <sys/malloc.h>
36 #include <sys/memrange.h>
37 #include <sys/cons.h>   /* cngetc() */
38 #include <sys/machintr.h>
39
40 #include <sys/mplock2.h>
41
42 #include <vm/vm.h>
43 #include <vm/vm_param.h>
44 #include <vm/pmap.h>
45 #include <vm/vm_kern.h>
46 #include <vm/vm_extern.h>
47 #include <sys/lock.h>
48 #include <vm/vm_map.h>
49 #include <sys/user.h>
50 #ifdef GPROF 
51 #include <sys/gmon.h>
52 #endif
53
54 #include <machine/smp.h>
55 #include <machine_base/apic/apicreg.h>
56 #include <machine/atomic.h>
57 #include <machine/cpufunc.h>
58 #include <machine_base/apic/mpapic.h>
59 #include <machine/psl.h>
60 #include <machine/segments.h>
61 #include <machine/tss.h>
62 #include <machine/specialreg.h>
63 #include <machine/globaldata.h>
64 #include <machine/pmap_inval.h>
65
66 #include <machine/md_var.h>             /* setidt() */
67 #include <machine_base/icu/icu.h>       /* IPIs */
68 #include <machine_base/apic/ioapic_abi.h>
69 #include <machine/intr_machdep.h>       /* IPIs */
70
71 #define FIXUP_EXTRA_APIC_INTS   8       /* additional entries we may create */
72
73 #define WARMBOOT_TARGET         0
74 #define WARMBOOT_OFF            (KERNBASE + 0x0467)
75 #define WARMBOOT_SEG            (KERNBASE + 0x0469)
76
77 #define BIOS_BASE               (0xf0000)
78 #define BIOS_BASE2              (0xe0000)
79 #define BIOS_SIZE               (0x10000)
80 #define BIOS_COUNT              (BIOS_SIZE/4)
81
82 #define CMOS_REG                (0x70)
83 #define CMOS_DATA               (0x71)
84 #define BIOS_RESET              (0x0f)
85 #define BIOS_WARM               (0x0a)
86
87 #define PROCENTRY_FLAG_EN       0x01
88 #define PROCENTRY_FLAG_BP       0x02
89 #define IOAPICENTRY_FLAG_EN     0x01
90
91
92 /* MP Floating Pointer Structure */
93 typedef struct MPFPS {
94         char    signature[4];
95         u_int32_t pap;
96         u_char  length;
97         u_char  spec_rev;
98         u_char  checksum;
99         u_char  mpfb1;
100         u_char  mpfb2;
101         u_char  mpfb3;
102         u_char  mpfb4;
103         u_char  mpfb5;
104 }      *mpfps_t;
105
106 /* MP Configuration Table Header */
107 typedef struct MPCTH {
108         char    signature[4];
109         u_short base_table_length;
110         u_char  spec_rev;
111         u_char  checksum;
112         u_char  oem_id[8];
113         u_char  product_id[12];
114         u_int32_t oem_table_pointer;
115         u_short oem_table_size;
116         u_short entry_count;
117         u_int32_t apic_address;
118         u_short extended_table_length;
119         u_char  extended_table_checksum;
120         u_char  reserved;
121 }      *mpcth_t;
122
123
124 typedef struct PROCENTRY {
125         u_char  type;
126         u_char  apic_id;
127         u_char  apic_version;
128         u_char  cpu_flags;
129         u_int32_t cpu_signature;
130         u_int32_t feature_flags;
131         u_int32_t reserved1;
132         u_int32_t reserved2;
133 }      *proc_entry_ptr;
134
135 typedef struct BUSENTRY {
136         u_char  type;
137         u_char  bus_id;
138         char    bus_type[6];
139 }      *bus_entry_ptr;
140
141 typedef struct IOAPICENTRY {
142         u_char  type;
143         u_char  apic_id;
144         u_char  apic_version;
145         u_char  apic_flags;
146         u_int32_t apic_address;
147 }      *io_apic_entry_ptr;
148
149 typedef struct INTENTRY {
150         u_char  type;
151         u_char  int_type;
152         u_short int_flags;
153         u_char  src_bus_id;
154         u_char  src_bus_irq;
155         u_char  dst_apic_id;
156         u_char  dst_apic_int;
157 }      *int_entry_ptr;
158
159 /* descriptions of MP basetable entries */
160 typedef struct BASETABLE_ENTRY {
161         u_char  type;
162         u_char  length;
163         char    name[16];
164 }       basetable_entry;
165
166 struct mptable_pos {
167         mpfps_t         mp_fps;
168         mpcth_t         mp_cth;
169         vm_size_t       mp_cth_mapsz;   
170 };
171
172 #define MPTABLE_POS_USE_DEFAULT(mpt) \
173         ((mpt)->mp_fps->mpfb1 != 0 || (mpt)->mp_cth == NULL)
174
175 struct mptable_bus {
176         int             mb_id;
177         int             mb_type;        /* MPTABLE_BUS_ */
178         TAILQ_ENTRY(mptable_bus) mb_link;
179 };
180
181 #define MPTABLE_BUS_ISA         0
182 #define MPTABLE_BUS_PCI         1
183
184 struct mptable_bus_info {
185         TAILQ_HEAD(, mptable_bus) mbi_list;
186 };
187
188 struct mptable_pci_int {
189         int             mpci_bus;
190         int             mpci_dev;
191         int             mpci_pin;
192
193         int             mpci_ioapic_idx;
194         int             mpci_ioapic_pin;
195         TAILQ_ENTRY(mptable_pci_int) mpci_link;
196 };
197
198 struct mptable_ioapic {
199         int             mio_idx;
200         int             mio_apic_id;
201         uint32_t        mio_addr;
202         int             mio_gsi_base;
203         int             mio_npin;
204         TAILQ_ENTRY(mptable_ioapic) mio_link;
205 };
206
207 typedef int     (*mptable_iter_func)(void *, const void *, int);
208
209 /*
210  * this code MUST be enabled here and in mpboot.s.
211  * it follows the very early stages of AP boot by placing values in CMOS ram.
212  * it NORMALLY will never be needed and thus the primitive method for enabling.
213  *
214  */
215 #if defined(CHECK_POINTS)
216 #define CHECK_READ(A)    (outb(CMOS_REG, (A)), inb(CMOS_DATA))
217 #define CHECK_WRITE(A,D) (outb(CMOS_REG, (A)), outb(CMOS_DATA, (D)))
218
219 #define CHECK_INIT(D);                          \
220         CHECK_WRITE(0x34, (D));                 \
221         CHECK_WRITE(0x35, (D));                 \
222         CHECK_WRITE(0x36, (D));                 \
223         CHECK_WRITE(0x37, (D));                 \
224         CHECK_WRITE(0x38, (D));                 \
225         CHECK_WRITE(0x39, (D));
226
227 #define CHECK_PRINT(S);                         \
228         kprintf("%s: %d, %d, %d, %d, %d, %d\n", \
229            (S),                                 \
230            CHECK_READ(0x34),                    \
231            CHECK_READ(0x35),                    \
232            CHECK_READ(0x36),                    \
233            CHECK_READ(0x37),                    \
234            CHECK_READ(0x38),                    \
235            CHECK_READ(0x39));
236
237 #else                           /* CHECK_POINTS */
238
239 #define CHECK_INIT(D)
240 #define CHECK_PRINT(S)
241
242 #endif                          /* CHECK_POINTS */
243
244 /*
245  * Values to send to the POST hardware.
246  */
247 #define MP_BOOTADDRESS_POST     0x10
248 #define MP_PROBE_POST           0x11
249 #define MPTABLE_PASS1_POST      0x12
250
251 #define MP_START_POST           0x13
252 #define MP_ENABLE_POST          0x14
253 #define MPTABLE_PASS2_POST      0x15
254
255 #define START_ALL_APS_POST      0x16
256 #define INSTALL_AP_TRAMP_POST   0x17
257 #define START_AP_POST           0x18
258
259 #define MP_ANNOUNCE_POST        0x19
260
261 /** XXX FIXME: where does this really belong, isa.h/isa.c perhaps? */
262 int     current_postcode;
263
264 /** XXX FIXME: what system files declare these??? */
265 extern struct region_descriptor r_gdt, r_idt;
266
267 int     mp_naps;                /* # of Applications processors */
268 #ifdef SMP /* APIC-IO */
269 static int      mp_nbusses;     /* # of busses */
270 int     mp_napics;              /* # of IO APICs */
271 vm_offset_t io_apic_address[NAPICID];   /* NAPICID is more than enough */
272 u_int32_t *io_apic_versions;
273 #endif
274 extern  int nkpt;
275
276 u_int32_t cpu_apic_versions[NAPICID];   /* populated during mptable scan */
277 int64_t tsc0_offset;
278 extern int64_t tsc_offsets[];
279
280 extern u_long ebda_addr;
281
282 #ifdef SMP /* APIC-IO */
283 struct apic_intmapinfo  int_to_apicintpin[APIC_INTMAPSIZE];
284 #endif
285
286 /*
287  * APIC ID logical/physical mapping structures.
288  * We oversize these to simplify boot-time config.
289  */
290 int     cpu_num_to_apic_id[NAPICID];
291 #ifdef SMP /* APIC-IO */
292 int     io_num_to_apic_id[NAPICID];
293 #endif
294 int     apic_id_to_logical[NAPICID];
295
296 /* AP uses this during bootstrap.  Do not staticize.  */
297 char *bootSTK;
298 static int bootAP;
299
300 struct pcb stoppcbs[MAXCPU];
301
302 extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
303
304 static basetable_entry basetable_entry_types[] =
305 {
306         {0, 20, "Processor"},
307         {1, 8, "Bus"},
308         {2, 8, "I/O APIC"},
309         {3, 8, "I/O INT"},
310         {4, 8, "Local INT"}
311 };
312
313 /*
314  * Local data and functions.
315  */
316
317 static u_int    boot_address;
318 static u_int    base_memory;
319 static int      mp_finish;
320 static int      mp_finish_lapic;
321
322 static void     mp_enable(u_int boot_addr);
323
324 static int      mptable_iterate_entries(const mpcth_t,
325                     mptable_iter_func, void *);
326 static int      mptable_search(void);
327 static long     mptable_search_sig(u_int32_t target, int count);
328 static int      mptable_hyperthread_fixup(cpumask_t, int);
329 #ifdef SMP /* APIC-IO */
330 static void     mptable_pass1(struct mptable_pos *);
331 static void     mptable_pass2(struct mptable_pos *);
332 static void     mptable_default(int type);
333 static void     mptable_fix(void);
334 #endif
335 static int      mptable_map(struct mptable_pos *);
336 static void     mptable_unmap(struct mptable_pos *);
337 static void     mptable_bus_info_alloc(const mpcth_t,
338                     struct mptable_bus_info *);
339 static void     mptable_bus_info_free(struct mptable_bus_info *);
340
341 static int      mptable_lapic_probe(struct lapic_enumerator *);
342 static void     mptable_lapic_enumerate(struct lapic_enumerator *);
343 static void     mptable_lapic_default(void);
344
345 static int      mptable_ioapic_probe(struct ioapic_enumerator *);
346 static void     mptable_ioapic_enumerate(struct ioapic_enumerator *);
347
348 #ifdef SMP /* APIC-IO */
349 static void     setup_apic_irq_mapping(void);
350 static int      apic_int_is_bus_type(int intr, int bus_type);
351 #endif
352 static int      start_all_aps(u_int boot_addr);
353 #if 0
354 static void     install_ap_tramp(u_int boot_addr);
355 #endif
356 static int      start_ap(struct mdglobaldata *gd, u_int boot_addr, int smibest);
357 static int      smitest(void);
358
359 static cpumask_t smp_startup_mask = 1;  /* which cpus have been started */
360 static cpumask_t smp_lapic_mask = 1;    /* which cpus have lapic been inited */
361 cpumask_t smp_active_mask = 1;  /* which cpus are ready for IPIs etc? */
362 SYSCTL_INT(_machdep, OID_AUTO, smp_active, CTLFLAG_RD, &smp_active_mask, 0, "");
363 static u_int    bootMP_size;
364
365 int                     imcr_present;
366
367 static vm_paddr_t       mptable_fps_phyaddr;
368 static int              mptable_use_default;
369 static TAILQ_HEAD(mptable_pci_int_list, mptable_pci_int) mptable_pci_int_list =
370         TAILQ_HEAD_INITIALIZER(mptable_pci_int_list);
371 static TAILQ_HEAD(mptable_ioapic_list, mptable_ioapic) mptable_ioapic_list =
372         TAILQ_HEAD_INITIALIZER(mptable_ioapic_list);
373
374 /*
375  * Calculate usable address in base memory for AP trampoline code.
376  */
377 u_int
378 mp_bootaddress(u_int basemem)
379 {
380         POSTCODE(MP_BOOTADDRESS_POST);
381
382         base_memory = basemem;
383
384         bootMP_size = mptramp_end - mptramp_start;
385         boot_address = trunc_page(basemem * 1024); /* round down to 4k boundary */
386         if (((basemem * 1024) - boot_address) < bootMP_size)
387                 boot_address -= PAGE_SIZE;      /* not enough, lower by 4k */
388         /* 3 levels of page table pages */
389         mptramp_pagetables = boot_address - (PAGE_SIZE * 3);
390
391         return mptramp_pagetables;
392 }
393
394
395 static void
396 mptable_probe(void)
397 {
398         struct mptable_pos mpt;
399         int error;
400
401         KKASSERT(mptable_fps_phyaddr == 0);
402
403         mptable_fps_phyaddr = mptable_search();
404         if (mptable_fps_phyaddr == 0)
405                 return;
406
407         error = mptable_map(&mpt);
408         if (error) {
409                 mptable_fps_phyaddr = 0;
410                 return;
411         }
412
413         if (MPTABLE_POS_USE_DEFAULT(&mpt)) {
414                 kprintf("MPTABLE: use default configuration\n");
415                 mptable_use_default = 1;
416         }
417         if (mpt.mp_fps->mpfb2 & 0x80)
418                 imcr_present = 1;
419
420         mptable_unmap(&mpt);
421 }
422 SYSINIT(mptable_probe, SI_BOOT2_PRESMP, SI_ORDER_FIRST, mptable_probe, 0);
423
424 /*
425  * Look for an Intel MP spec table (ie, SMP capable hardware).
426  */
427 static int
428 mptable_search(void)
429 {
430         long    x;
431         u_int32_t target;
432  
433         POSTCODE(MP_PROBE_POST);
434
435         /* see if EBDA exists */
436         if (ebda_addr != 0) {
437                 /* search first 1K of EBDA */
438                 target = (u_int32_t)ebda_addr;
439                 if ((x = mptable_search_sig(target, 1024 / 4)) > 0)
440                         return x;
441         } else {
442                 /* last 1K of base memory, effective 'top of base' passed in */
443                 target = (u_int32_t)(base_memory - 0x400);
444                 if ((x = mptable_search_sig(target, 1024 / 4)) > 0)
445                         return x;
446         }
447
448         /* search the BIOS */
449         target = (u_int32_t)BIOS_BASE;
450         if ((x = mptable_search_sig(target, BIOS_COUNT)) > 0)
451                 return x;
452
453         /* search the extended BIOS */
454         target = (u_int32_t)BIOS_BASE2;
455         if ((x = mptable_search_sig(target, BIOS_COUNT)) > 0)
456                 return x;
457
458         /* nothing found */
459         return 0;
460 }
461
462 static int
463 mptable_iterate_entries(const mpcth_t cth, mptable_iter_func func, void *arg)
464 {
465         int count, total_size;
466         const void *position;
467
468         KKASSERT(cth->base_table_length >= sizeof(struct MPCTH));
469         total_size = cth->base_table_length - sizeof(struct MPCTH);
470         position = (const uint8_t *)cth + sizeof(struct MPCTH);
471         count = cth->entry_count;
472
473         while (count--) {
474                 int type, error;
475
476                 KKASSERT(total_size >= 0);
477                 if (total_size == 0) {
478                         kprintf("invalid base MP table, "
479                                 "entry count and length mismatch\n");
480                         return EINVAL;
481                 }
482
483                 type = *(const uint8_t *)position;
484                 switch (type) {
485                 case 0: /* processor_entry */
486                 case 1: /* bus_entry */
487                 case 2: /* io_apic_entry */
488                 case 3: /* int_entry */
489                 case 4: /* int_entry */
490                         break;
491                 default:
492                         kprintf("unknown base MP table entry type %d\n", type);
493                         return EINVAL;
494                 }
495
496                 if (total_size < basetable_entry_types[type].length) {
497                         kprintf("invalid base MP table length, "
498                                 "does not contain all entries\n");
499                         return EINVAL;
500                 }
501                 total_size -= basetable_entry_types[type].length;
502
503                 error = func(arg, position, type);
504                 if (error)
505                         return error;
506
507                 position = (const uint8_t *)position +
508                     basetable_entry_types[type].length;
509         }
510         return 0;
511 }
512
513
514 /*
515  * Startup the SMP processors.
516  */
517 void
518 mp_start(void)
519 {
520         POSTCODE(MP_START_POST);
521         mp_enable(boot_address);
522 }
523
524
525 /*
526  * Print various information about the SMP system hardware and setup.
527  */
528 void
529 mp_announce(void)
530 {
531         int     x;
532
533         POSTCODE(MP_ANNOUNCE_POST);
534
535         kprintf("DragonFly/MP: Multiprocessor motherboard\n");
536         kprintf(" cpu0 (BSP): apic id: %2d", CPU_TO_ID(0));
537         kprintf(", version: 0x%08x\n", cpu_apic_versions[0]);
538         for (x = 1; x <= mp_naps; ++x) {
539                 kprintf(" cpu%d (AP):  apic id: %2d", x, CPU_TO_ID(x));
540                 kprintf(", version: 0x%08x\n", cpu_apic_versions[x]);
541         }
542
543 if (apic_io_enable) {
544         if (ioapic_use_old) {
545                 for (x = 0; x < mp_napics; ++x) {
546                         kprintf(" io%d (APIC): apic id: %2d", x, IO_TO_ID(x));
547                         kprintf(", version: 0x%08x", io_apic_versions[x]);
548                         kprintf(", at 0x%08lx\n", io_apic_address[x]);
549                 }
550         }
551 } else {
552         kprintf(" Warning: APIC I/O disabled\n");
553 }
554 }
555
556 /*
557  * AP cpu's call this to sync up protected mode.
558  *
559  * WARNING! %gs is not set up on entry.  This routine sets up %gs.
560  */
561 void
562 init_secondary(void)
563 {
564         int     gsel_tss;
565         int     x, myid = bootAP;
566         u_int64_t msr, cr0;
567         struct mdglobaldata *md;
568         struct privatespace *ps;
569
570         ps = &CPU_prvspace[myid];
571
572         gdt_segs[GPROC0_SEL].ssd_base =
573                 (long) &ps->mdglobaldata.gd_common_tss;
574         ps->mdglobaldata.mi.gd_prvspace = ps;
575
576         /* We fill the 32-bit segment descriptors */
577         for (x = 0; x < NGDT; x++) {
578                 if (x != GPROC0_SEL && x != (GPROC0_SEL + 1))
579                         ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x]);
580         }
581         /* And now a 64-bit one */
582         ssdtosyssd(&gdt_segs[GPROC0_SEL],
583             (struct system_segment_descriptor *)&gdt[myid * NGDT + GPROC0_SEL]);
584
585         r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
586         r_gdt.rd_base = (long) &gdt[myid * NGDT];
587         lgdt(&r_gdt);                   /* does magic intra-segment return */
588
589         /* lgdt() destroys the GSBASE value, so we load GSBASE after lgdt() */
590         wrmsr(MSR_FSBASE, 0);           /* User value */
591         wrmsr(MSR_GSBASE, (u_int64_t)ps);
592         wrmsr(MSR_KGSBASE, 0);          /* XXX User value while we're in the kernel */
593
594         lidt(&r_idt);
595
596 #if 0
597         lldt(_default_ldt);
598         mdcpu->gd_currentldt = _default_ldt;
599 #endif
600
601         gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
602         gdt[myid * NGDT + GPROC0_SEL].sd_type = SDT_SYSTSS;
603
604         md = mdcpu;     /* loaded through %gs:0 (mdglobaldata.mi.gd_prvspace)*/
605
606         md->gd_common_tss.tss_rsp0 = 0; /* not used until after switch */
607 #if 0 /* JG XXX */
608         md->gd_common_tss.tss_ioopt = (sizeof md->gd_common_tss) << 16;
609 #endif
610         md->gd_tss_gdt = &gdt[myid * NGDT + GPROC0_SEL];
611         md->gd_common_tssd = *md->gd_tss_gdt;
612
613         /* double fault stack */
614         md->gd_common_tss.tss_ist1 =
615                 (long)&md->mi.gd_prvspace->idlestack[
616                         sizeof(md->mi.gd_prvspace->idlestack)];
617
618         ltr(gsel_tss);
619
620         /*
621          * Set to a known state:
622          * Set by mpboot.s: CR0_PG, CR0_PE
623          * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
624          */
625         cr0 = rcr0();
626         cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
627         load_cr0(cr0);
628
629         /* Set up the fast syscall stuff */
630         msr = rdmsr(MSR_EFER) | EFER_SCE;
631         wrmsr(MSR_EFER, msr);
632         wrmsr(MSR_LSTAR, (u_int64_t)IDTVEC(fast_syscall));
633         wrmsr(MSR_CSTAR, (u_int64_t)IDTVEC(fast_syscall32));
634         msr = ((u_int64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
635               ((u_int64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48);
636         wrmsr(MSR_STAR, msr);
637         wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D);
638
639         pmap_set_opt();         /* PSE/4MB pages, etc */
640 #if JGXXX
641         /* Initialize the PAT MSR. */
642         pmap_init_pat();
643 #endif
644
645         /* set up CPU registers and state */
646         cpu_setregs();
647
648         /* set up SSE/NX registers */
649         initializecpu();
650
651         /* set up FPU state on the AP */
652         npxinit(__INITIAL_NPXCW__);
653
654         /* disable the APIC, just to be SURE */
655         lapic->svr &= ~APIC_SVR_ENABLE;
656
657         /* data returned to BSP */
658         cpu_apic_versions[0] = lapic->version;
659 }
660
661 /*******************************************************************
662  * local functions and data
663  */
664
665 /*
666  * start the SMP system
667  */
668 static void
669 mp_enable(u_int boot_addr)
670 {
671         int     apic;
672         u_int   ux;
673         struct mptable_pos mpt;
674
675         POSTCODE(MP_ENABLE_POST);
676
677         lapic_config();
678
679         /* Initialize BSP's local APIC */
680         lapic_init(TRUE);
681
682         /* start each Application Processor */
683         start_all_aps(boot_addr);
684
685         if (apic_io_enable)
686                 ioapic_config();
687
688 if (apic_io_enable && ioapic_use_old) {
689         register_t ef;
690
691         if (!mptable_fps_phyaddr)
692                 panic("no MP table, disable APIC_IO! (set hw.apic_io_enable=0)\n");
693
694         crit_enter();
695
696         ef = read_rflags();
697         cpu_disable_intr();
698
699         /*
700          * Switch to I/O APIC MachIntrABI and reconfigure
701          * the default IDT entries.
702          */
703         MachIntrABI = MachIntrABI_IOAPIC;
704         MachIntrABI.setdefault();
705
706         mptable_map(&mpt);
707
708         /*
709          * Examine the MP table for needed info
710          */
711         mptable_pass1(&mpt);
712         mptable_pass2(&mpt);
713
714         mptable_unmap(&mpt);
715
716         /* Post scan cleanup */
717         mptable_fix();
718
719         setup_apic_irq_mapping();
720
721         /* fill the LOGICAL io_apic_versions table */
722         for (apic = 0; apic < mp_napics; ++apic) {
723                 ux = ioapic_read(ioapic[apic], IOAPIC_VER);
724                 io_apic_versions[apic] = ux;
725                 io_apic_set_id(apic, IO_TO_ID(apic));
726         }
727
728         /* program each IO APIC in the system */
729         for (apic = 0; apic < mp_napics; ++apic)
730                 if (io_apic_setup(apic) < 0)
731                         panic("IO APIC setup failure");
732
733         write_rflags(ef);
734
735         MachIntrABI.cleanup();
736
737         crit_exit();
738 }
739
740         /* Finalize PIC */
741         MachIntrABI.finalize();
742 }
743
744
745 /*
746  * look for the MP spec signature
747  */
748
749 /* string defined by the Intel MP Spec as identifying the MP table */
750 #define MP_SIG          0x5f504d5f      /* _MP_ */
751 #define NEXT(X)         ((X) += 4)
752 static long
753 mptable_search_sig(u_int32_t target, int count)
754 {
755         vm_size_t map_size;
756         u_int32_t *addr;
757         int x, ret;
758
759         KKASSERT(target != 0);
760
761         map_size = count * sizeof(u_int32_t);
762         addr = pmap_mapdev((vm_paddr_t)target, map_size);
763
764         ret = 0;
765         for (x = 0; x < count; NEXT(x)) {
766                 if (addr[x] == MP_SIG) {
767                         /* make array index a byte index */
768                         ret = target + (x * sizeof(u_int32_t));
769                         break;
770                 }
771         }
772
773         pmap_unmapdev((vm_offset_t)addr, map_size);
774         return ret;
775 }
776
777
778 typedef struct BUSDATA {
779         u_char  bus_id;
780         enum busTypes bus_type;
781 }       bus_datum;
782
783 typedef struct INTDATA {
784         u_char  int_type;
785         u_short int_flags;
786         u_char  src_bus_id;
787         u_char  src_bus_irq;
788         u_char  dst_apic_id;
789         u_char  dst_apic_int;
790         u_char  int_vector;
791 }       io_int, local_int;
792
793 typedef struct BUSTYPENAME {
794         u_char  type;
795         char    name[7];
796 }       bus_type_name;
797
798 static bus_type_name bus_type_table[] =
799 {
800         {CBUS, "CBUS"},
801         {CBUSII, "CBUSII"},
802         {EISA, "EISA"},
803         {MCA, "MCA"},
804         {UNKNOWN_BUSTYPE, "---"},
805         {ISA, "ISA"},
806         {MCA, "MCA"},
807         {UNKNOWN_BUSTYPE, "---"},
808         {UNKNOWN_BUSTYPE, "---"},
809         {UNKNOWN_BUSTYPE, "---"},
810         {UNKNOWN_BUSTYPE, "---"},
811         {UNKNOWN_BUSTYPE, "---"},
812         {PCI, "PCI"},
813         {UNKNOWN_BUSTYPE, "---"},
814         {UNKNOWN_BUSTYPE, "---"},
815         {UNKNOWN_BUSTYPE, "---"},
816         {UNKNOWN_BUSTYPE, "---"},
817         {XPRESS, "XPRESS"},
818         {UNKNOWN_BUSTYPE, "---"}
819 };
820
821 /* from MP spec v1.4, table 5-1 */
822 static int default_data[7][5] =
823 {
824 /*   nbus, id0, type0, id1, type1 */
825         {1, 0, ISA, 255, 255},
826         {1, 0, EISA, 255, 255},
827         {1, 0, EISA, 255, 255},
828         {1, 0, MCA, 255, 255},
829         {2, 0, ISA, 1, PCI},
830         {2, 0, EISA, 1, PCI},
831         {2, 0, MCA, 1, PCI}
832 };
833
834 /* the bus data */
835 static bus_datum *bus_data;
836
837 /* the IO INT data, one entry per possible APIC INTerrupt */
838 static io_int  *io_apic_ints;
839 static int nintrs;
840
841 static int processor_entry      (const struct PROCENTRY *entry, int cpu);
842 static int bus_entry            (const struct BUSENTRY *entry, int bus);
843 static int io_apic_entry        (const struct IOAPICENTRY *entry, int apic);
844 static int int_entry            (const struct INTENTRY *entry, int intr);
845 static int lookup_bus_type      (char *name);
846
847 static int
848 mptable_ioapic_pass1_callback(void *xarg, const void *pos, int type)
849 {
850         const struct IOAPICENTRY *ioapic_ent;
851
852         switch (type) {
853         case 1: /* bus_entry */
854                 ++mp_nbusses;
855                 break;
856
857         case 2: /* io_apic_entry */
858                 ioapic_ent = pos;
859                 if (ioapic_ent->apic_flags & IOAPICENTRY_FLAG_EN) {
860                         io_apic_address[mp_napics++] =
861                             (vm_offset_t)ioapic_ent->apic_address;
862                 }
863                 break;
864
865         case 3: /* int_entry */
866                 ++nintrs;
867                 break;
868         }
869         return 0;
870 }
871
872 /*
873  * 1st pass on motherboard's Intel MP specification table.
874  *
875  * determines:
876  *      io_apic_address[N]
877  *      mp_nbusses
878  *      mp_napics
879  *      nintrs
880  */
881 static void
882 mptable_pass1(struct mptable_pos *mpt)
883 {
884         mpfps_t fps;
885         int x;
886
887         POSTCODE(MPTABLE_PASS1_POST);
888
889         fps = mpt->mp_fps;
890         KKASSERT(fps != NULL);
891
892         /* clear various tables */
893         for (x = 0; x < NAPICID; ++x)
894                 io_apic_address[x] = ~0;        /* IO APIC address table */
895
896         mp_nbusses = 0;
897         mp_napics = 0;
898         nintrs = 0;
899
900         /* check for use of 'default' configuration */
901         if (fps->mpfb1 != 0) {
902                 io_apic_address[0] = DEFAULT_IO_APIC_BASE;
903                 mp_nbusses = default_data[fps->mpfb1 - 1][0];
904                 mp_napics = 1;
905                 nintrs = 16;
906         } else {
907                 int error;
908
909                 error = mptable_iterate_entries(mpt->mp_cth,
910                             mptable_ioapic_pass1_callback, NULL);
911                 if (error)
912                         panic("mptable_iterate_entries(ioapic_pass1) failed\n");
913         }
914 }
915
916 struct mptable_ioapic2_cbarg {
917         int     bus;
918         int     apic;
919         int     intr;
920 };
921
922 static int
923 mptable_ioapic_pass2_callback(void *xarg, const void *pos, int type)
924 {
925         struct mptable_ioapic2_cbarg *arg = xarg;
926
927         switch (type) {
928         case 1:
929                 if (bus_entry(pos, arg->bus))
930                         ++arg->bus;
931                 break;
932
933         case 2:
934                 if (io_apic_entry(pos, arg->apic))
935                         ++arg->apic;
936                 break;
937
938         case 3:
939                 if (int_entry(pos, arg->intr))
940                         ++arg->intr;
941                 break;
942         }
943         return 0;
944 }
945
946 /*
947  * 2nd pass on motherboard's Intel MP specification table.
948  *
949  * sets:
950  *      ID_TO_IO(N), phy APIC ID to log CPU/IO table
951  *      IO_TO_ID(N), logical IO to APIC ID table
952  *      bus_data[N]
953  *      io_apic_ints[N]
954  */
955 static void
956 mptable_pass2(struct mptable_pos *mpt)
957 {
958         struct mptable_ioapic2_cbarg arg;
959         mpfps_t fps;
960         int error, x;
961
962         POSTCODE(MPTABLE_PASS2_POST);
963
964         fps = mpt->mp_fps;
965         KKASSERT(fps != NULL);
966
967         MALLOC(io_apic_versions, u_int32_t *, sizeof(u_int32_t) * mp_napics,
968             M_DEVBUF, M_WAITOK);
969         MALLOC(ioapic, volatile ioapic_t **, sizeof(ioapic_t *) * mp_napics,
970             M_DEVBUF, M_WAITOK | M_ZERO);
971         MALLOC(io_apic_ints, io_int *, sizeof(io_int) * (nintrs + FIXUP_EXTRA_APIC_INTS),
972             M_DEVBUF, M_WAITOK);
973         MALLOC(bus_data, bus_datum *, sizeof(bus_datum) * mp_nbusses,
974             M_DEVBUF, M_WAITOK);
975
976         for (x = 0; x < mp_napics; x++)
977                 ioapic[x] = ioapic_map(io_apic_address[x]);
978
979         /* clear various tables */
980         for (x = 0; x < NAPICID; ++x) {
981                 ID_TO_IO(x) = -1;       /* phy APIC ID to log CPU/IO table */
982                 IO_TO_ID(x) = -1;       /* logical IO to APIC ID table */
983         }
984
985         /* clear bus data table */
986         for (x = 0; x < mp_nbusses; ++x)
987                 bus_data[x].bus_id = 0xff;
988
989         /* clear IO APIC INT table */
990         for (x = 0; x < nintrs + FIXUP_EXTRA_APIC_INTS; ++x) {
991                 io_apic_ints[x].int_type = 0xff;
992                 io_apic_ints[x].int_vector = 0xff;
993         }
994
995         /* check for use of 'default' configuration */
996         if (fps->mpfb1 != 0) {
997                 mptable_default(fps->mpfb1);
998                 return;
999         }
1000
1001         bzero(&arg, sizeof(arg));
1002         error = mptable_iterate_entries(mpt->mp_cth,
1003                     mptable_ioapic_pass2_callback, &arg);
1004         if (error)
1005                 panic("mptable_iterate_entries(ioapic_pass2) failed\n");
1006 }
1007
1008 /*
1009  * Check if we should perform a hyperthreading "fix-up" to
1010  * enumerate any logical CPU's that aren't already listed
1011  * in the table.
1012  *
1013  * XXX: We assume that all of the physical CPUs in the
1014  * system have the same number of logical CPUs.
1015  *
1016  * XXX: We assume that APIC ID's are allocated such that
1017  * the APIC ID's for a physical processor are aligned
1018  * with the number of logical CPU's in the processor.
1019  */
1020 static int
1021 mptable_hyperthread_fixup(cpumask_t id_mask, int cpu_count)
1022 {
1023         int i, id, lcpus_max, logical_cpus;
1024
1025         if ((cpu_feature & CPUID_HTT) == 0)
1026                 return 0;
1027
1028         lcpus_max = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
1029         if (lcpus_max <= 1)
1030                 return 0;
1031
1032         if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
1033                 /*
1034                  * INSTRUCTION SET REFERENCE, A-M (#253666)
1035                  * Page 3-181, Table 3-20
1036                  * "The nearest power-of-2 integer that is not smaller
1037                  *  than EBX[23:16] is the number of unique initial APIC
1038                  *  IDs reserved for addressing different logical
1039                  *  processors in a physical package."
1040                  */
1041                 for (i = 0; ; ++i) {
1042                         if ((1 << i) >= lcpus_max) {
1043                                 lcpus_max = 1 << i;
1044                                 break;
1045                         }
1046                 }
1047         }
1048
1049         KKASSERT(cpu_count != 0);
1050         if (cpu_count == lcpus_max) {
1051                 /* We have nothing to fix */
1052                 return 0;
1053         } else if (cpu_count == 1) {
1054                 /* XXX this may be incorrect */
1055                 logical_cpus = lcpus_max;
1056         } else {
1057                 int cur, prev, dist;
1058
1059                 /*
1060                  * Calculate the distances between two nearest
1061                  * APIC IDs.  If all such distances are same,
1062                  * then it is the number of missing cpus that
1063                  * we are going to fill later.
1064                  */
1065                 dist = cur = prev = -1;
1066                 for (id = 0; id < MAXCPU; ++id) {
1067                         if ((id_mask & CPUMASK(id)) == 0)
1068                                 continue;
1069
1070                         cur = id;
1071                         if (prev >= 0) {
1072                                 int new_dist = cur - prev;
1073
1074                                 if (dist < 0)
1075                                         dist = new_dist;
1076
1077                                 /*
1078                                  * Make sure that all distances
1079                                  * between two nearest APIC IDs
1080                                  * are same.
1081                                  */
1082                                 if (dist != new_dist)
1083                                         return 0;
1084                         }
1085                         prev = cur;
1086                 }
1087                 if (dist == 1)
1088                         return 0;
1089
1090                 /* Must be power of 2 */
1091                 if (dist & (dist - 1))
1092                         return 0;
1093
1094                 /* Can't exceed CPU package capacity */
1095                 if (dist > lcpus_max)
1096                         logical_cpus = lcpus_max;
1097                 else
1098                         logical_cpus = dist;
1099         }
1100
1101         /*
1102          * For each APIC ID of a CPU that is set in the mask,
1103          * scan the other candidate APIC ID's for this
1104          * physical processor.  If any of those ID's are
1105          * already in the table, then kill the fixup.
1106          */
1107         for (id = 0; id < MAXCPU; id++) {
1108                 if ((id_mask & CPUMASK(id)) == 0)
1109                         continue;
1110                 /* First, make sure we are on a logical_cpus boundary. */
1111                 if (id % logical_cpus != 0)
1112                         return 0;
1113                 for (i = id + 1; i < id + logical_cpus; i++)
1114                         if ((id_mask & CPUMASK(i)) != 0)
1115                                 return 0;
1116         }
1117         return logical_cpus;
1118 }
1119
1120 static int
1121 mptable_map(struct mptable_pos *mpt)
1122 {
1123         mpfps_t fps = NULL;
1124         mpcth_t cth = NULL;
1125         vm_size_t cth_mapsz = 0;
1126
1127         KKASSERT(mptable_fps_phyaddr != 0);
1128
1129         bzero(mpt, sizeof(*mpt));
1130
1131         fps = pmap_mapdev(mptable_fps_phyaddr, sizeof(*fps));
1132         if (fps->pap != 0) {
1133                 /*
1134                  * Map configuration table header to get
1135                  * the base table size
1136                  */
1137                 cth = pmap_mapdev(fps->pap, sizeof(*cth));
1138                 cth_mapsz = cth->base_table_length;
1139                 pmap_unmapdev((vm_offset_t)cth, sizeof(*cth));
1140
1141                 if (cth_mapsz < sizeof(*cth)) {
1142                         kprintf("invalid base MP table length %d\n",
1143                                 (int)cth_mapsz);
1144                         pmap_unmapdev((vm_offset_t)fps, sizeof(*fps));
1145                         return EINVAL;
1146                 }
1147
1148                 /*
1149                  * Map the base table
1150                  */
1151                 cth = pmap_mapdev(fps->pap, cth_mapsz);
1152         }
1153
1154         mpt->mp_fps = fps;
1155         mpt->mp_cth = cth;
1156         mpt->mp_cth_mapsz = cth_mapsz;
1157
1158         return 0;
1159 }
1160
1161 static void
1162 mptable_unmap(struct mptable_pos *mpt)
1163 {
1164         if (mpt->mp_cth != NULL) {
1165                 pmap_unmapdev((vm_offset_t)mpt->mp_cth, mpt->mp_cth_mapsz);
1166                 mpt->mp_cth = NULL;
1167                 mpt->mp_cth_mapsz = 0;
1168         }
1169         if (mpt->mp_fps != NULL) {
1170                 pmap_unmapdev((vm_offset_t)mpt->mp_fps, sizeof(*mpt->mp_fps));
1171                 mpt->mp_fps = NULL;
1172         }
1173 }
1174
1175 void
1176 assign_apic_irq(int apic, int intpin, int irq)
1177 {
1178         int x;
1179         
1180         if (int_to_apicintpin[irq].ioapic != -1)
1181                 panic("assign_apic_irq: inconsistent table");
1182         
1183         int_to_apicintpin[irq].ioapic = apic;
1184         int_to_apicintpin[irq].int_pin = intpin;
1185         int_to_apicintpin[irq].apic_address = ioapic[apic];
1186         int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
1187         
1188         for (x = 0; x < nintrs; x++) {
1189                 if ((io_apic_ints[x].int_type == 0 || 
1190                      io_apic_ints[x].int_type == 3) &&
1191                     io_apic_ints[x].int_vector == 0xff &&
1192                     io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
1193                     io_apic_ints[x].dst_apic_int == intpin)
1194                         io_apic_ints[x].int_vector = irq;
1195         }
1196 }
1197
1198 void
1199 revoke_apic_irq(int irq)
1200 {
1201         int x;
1202         int oldapic;
1203         int oldintpin;
1204         
1205         if (int_to_apicintpin[irq].ioapic == -1)
1206                 panic("revoke_apic_irq: inconsistent table");
1207         
1208         oldapic = int_to_apicintpin[irq].ioapic;
1209         oldintpin = int_to_apicintpin[irq].int_pin;
1210
1211         int_to_apicintpin[irq].ioapic = -1;
1212         int_to_apicintpin[irq].int_pin = 0;
1213         int_to_apicintpin[irq].apic_address = NULL;
1214         int_to_apicintpin[irq].redirindex = 0;
1215         
1216         for (x = 0; x < nintrs; x++) {
1217                 if ((io_apic_ints[x].int_type == 0 || 
1218                      io_apic_ints[x].int_type == 3) &&
1219                     io_apic_ints[x].int_vector != 0xff &&
1220                     io_apic_ints[x].dst_apic_id == IO_TO_ID(oldapic) &&
1221                     io_apic_ints[x].dst_apic_int == oldintpin)
1222                         io_apic_ints[x].int_vector = 0xff;
1223         }
1224 }
1225
1226 /*
1227  * Allocate an IRQ 
1228  */
1229 static void
1230 allocate_apic_irq(int intr)
1231 {
1232         int apic;
1233         int intpin;
1234         int irq;
1235         
1236         if (io_apic_ints[intr].int_vector != 0xff)
1237                 return;         /* Interrupt handler already assigned */
1238         
1239         if (io_apic_ints[intr].int_type != 0 &&
1240             (io_apic_ints[intr].int_type != 3 ||
1241              (io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
1242               io_apic_ints[intr].dst_apic_int == 0)))
1243                 return;         /* Not INT or ExtInt on != (0, 0) */
1244         
1245         irq = 0;
1246         while (irq < APIC_INTMAPSIZE &&
1247                int_to_apicintpin[irq].ioapic != -1)
1248                 irq++;
1249         
1250         if (irq >= APIC_INTMAPSIZE)
1251                 return;         /* No free interrupt handlers */
1252         
1253         apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
1254         intpin = io_apic_ints[intr].dst_apic_int;
1255         
1256         assign_apic_irq(apic, intpin, irq);
1257 }
1258
1259
1260 static void
1261 swap_apic_id(int apic, int oldid, int newid)
1262 {
1263         int x;
1264         int oapic;
1265         
1266
1267         if (oldid == newid)
1268                 return;                 /* Nothing to do */
1269         
1270         kprintf("Changing APIC ID for IO APIC #%d from %d to %d in MP table\n",
1271                apic, oldid, newid);
1272         
1273         /* Swap physical APIC IDs in interrupt entries */
1274         for (x = 0; x < nintrs; x++) {
1275                 if (io_apic_ints[x].dst_apic_id == oldid)
1276                         io_apic_ints[x].dst_apic_id = newid;
1277                 else if (io_apic_ints[x].dst_apic_id == newid)
1278                         io_apic_ints[x].dst_apic_id = oldid;
1279         }
1280         
1281         /* Swap physical APIC IDs in IO_TO_ID mappings */
1282         for (oapic = 0; oapic < mp_napics; oapic++)
1283                 if (IO_TO_ID(oapic) == newid)
1284                         break;
1285         
1286         if (oapic < mp_napics) {
1287                 kprintf("Changing APIC ID for IO APIC #%d from "
1288                        "%d to %d in MP table\n",
1289                        oapic, newid, oldid);
1290                 IO_TO_ID(oapic) = oldid;
1291         }
1292         IO_TO_ID(apic) = newid;
1293 }
1294
1295
1296 static void
1297 fix_id_to_io_mapping(void)
1298 {
1299         int x;
1300
1301         for (x = 0; x < NAPICID; x++)
1302                 ID_TO_IO(x) = -1;
1303         
1304         for (x = 0; x <= mp_naps; x++) {
1305                 if ((u_int)CPU_TO_ID(x) < NAPICID)
1306                         ID_TO_IO(CPU_TO_ID(x)) = x;
1307         }
1308         
1309         for (x = 0; x < mp_napics; x++) {
1310                 if ((u_int)IO_TO_ID(x) < NAPICID)
1311                         ID_TO_IO(IO_TO_ID(x)) = x;
1312         }
1313 }
1314
1315
1316 static int
1317 first_free_apic_id(void)
1318 {
1319         int freeid, x;
1320         
1321         for (freeid = 0; freeid < NAPICID; freeid++) {
1322                 for (x = 0; x <= mp_naps; x++)
1323                         if (CPU_TO_ID(x) == freeid)
1324                                 break;
1325                 if (x <= mp_naps)
1326                         continue;
1327                 for (x = 0; x < mp_napics; x++)
1328                         if (IO_TO_ID(x) == freeid)
1329                                 break;
1330                 if (x < mp_napics)
1331                         continue;
1332                 return freeid;
1333         }
1334         return freeid;
1335 }
1336
1337
1338 static int
1339 io_apic_id_acceptable(int apic, int id)
1340 {
1341         int cpu;                /* Logical CPU number */
1342         int oapic;              /* Logical IO APIC number for other IO APIC */
1343
1344         if ((u_int)id >= NAPICID)
1345                 return 0;       /* Out of range */
1346         
1347         for (cpu = 0; cpu <= mp_naps; cpu++) {
1348                 if (CPU_TO_ID(cpu) == id)
1349                         return 0;       /* Conflict with CPU */
1350         }
1351         
1352         for (oapic = 0; oapic < mp_napics && oapic < apic; oapic++) {
1353                 if (IO_TO_ID(oapic) == id)
1354                         return 0;       /* Conflict with other APIC */
1355         }
1356         
1357         return 1;               /* ID is acceptable for IO APIC */
1358 }
1359
1360 static
1361 io_int *
1362 io_apic_find_int_entry(int apic, int pin)
1363 {
1364         int     x;
1365
1366         /* search each of the possible INTerrupt sources */
1367         for (x = 0; x < nintrs; ++x) {
1368                 if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
1369                     (pin == io_apic_ints[x].dst_apic_int))
1370                         return (&io_apic_ints[x]);
1371         }
1372         return NULL;
1373 }
1374
1375 /*
1376  * parse an Intel MP specification table
1377  */
1378 static void
1379 mptable_fix(void)
1380 {
1381         int     x;
1382         int     id;
1383         int     apic;           /* IO APIC unit number */
1384         int     freeid;         /* Free physical APIC ID */
1385         int     physid;         /* Current physical IO APIC ID */
1386         io_int *io14;
1387         int     bus_0 = 0;      /* Stop GCC warning */
1388         int     bus_pci = 0;    /* Stop GCC warning */
1389         int     num_pci_bus;
1390
1391         /*
1392          * Fix mis-numbering of the PCI bus and its INT entries if the BIOS
1393          * did it wrong.  The MP spec says that when more than 1 PCI bus
1394          * exists the BIOS must begin with bus entries for the PCI bus and use
1395          * actual PCI bus numbering.  This implies that when only 1 PCI bus
1396          * exists the BIOS can choose to ignore this ordering, and indeed many
1397          * MP motherboards do ignore it.  This causes a problem when the PCI
1398          * sub-system makes requests of the MP sub-system based on PCI bus
1399          * numbers.     So here we look for the situation and renumber the
1400          * busses and associated INTs in an effort to "make it right".
1401          */
1402
1403         /* find bus 0, PCI bus, count the number of PCI busses */
1404         for (num_pci_bus = 0, x = 0; x < mp_nbusses; ++x) {
1405                 if (bus_data[x].bus_id == 0) {
1406                         bus_0 = x;
1407                 }
1408                 if (bus_data[x].bus_type == PCI) {
1409                         ++num_pci_bus;
1410                         bus_pci = x;
1411                 }
1412         }
1413         /*
1414          * bus_0 == slot of bus with ID of 0
1415          * bus_pci == slot of last PCI bus encountered
1416          */
1417
1418         /* check the 1 PCI bus case for sanity */
1419         /* if it is number 0 all is well */
1420         if (num_pci_bus == 1 &&
1421             bus_data[bus_pci].bus_id != 0) {
1422                 
1423                 /* mis-numbered, swap with whichever bus uses slot 0 */
1424
1425                 /* swap the bus entry types */
1426                 bus_data[bus_pci].bus_type = bus_data[bus_0].bus_type;
1427                 bus_data[bus_0].bus_type = PCI;
1428
1429                 /* swap each relevant INTerrupt entry */
1430                 id = bus_data[bus_pci].bus_id;
1431                 for (x = 0; x < nintrs; ++x) {
1432                         if (io_apic_ints[x].src_bus_id == id) {
1433                                 io_apic_ints[x].src_bus_id = 0;
1434                         }
1435                         else if (io_apic_ints[x].src_bus_id == 0) {
1436                                 io_apic_ints[x].src_bus_id = id;
1437                         }
1438                 }
1439         }
1440
1441         /* Assign IO APIC IDs.
1442          * 
1443          * First try the existing ID. If a conflict is detected, try
1444          * the ID in the MP table.  If a conflict is still detected, find
1445          * a free id.
1446          *
1447          * We cannot use the ID_TO_IO table before all conflicts has been
1448          * resolved and the table has been corrected.
1449          */
1450         for (apic = 0; apic < mp_napics; ++apic) { /* For all IO APICs */
1451                 
1452                 /* First try to use the value set by the BIOS */
1453                 physid = io_apic_get_id(apic);
1454                 if (io_apic_id_acceptable(apic, physid)) {
1455                         if (IO_TO_ID(apic) != physid)
1456                                 swap_apic_id(apic, IO_TO_ID(apic), physid);
1457                         continue;
1458                 }
1459
1460                 /* Then check if the value in the MP table is acceptable */
1461                 if (io_apic_id_acceptable(apic, IO_TO_ID(apic)))
1462                         continue;
1463
1464                 /* Last resort, find a free APIC ID and use it */
1465                 freeid = first_free_apic_id();
1466                 if (freeid >= NAPICID)
1467                         panic("No free physical APIC IDs found");
1468                 
1469                 if (io_apic_id_acceptable(apic, freeid)) {
1470                         swap_apic_id(apic, IO_TO_ID(apic), freeid);
1471                         continue;
1472                 }
1473                 panic("Free physical APIC ID not usable");
1474         }
1475         fix_id_to_io_mapping();
1476
1477         /* detect and fix broken Compaq MP table */
1478         if (apic_int_type(0, 0) == -1) {
1479                 kprintf("APIC_IO: MP table broken: 8259->APIC entry missing!\n");
1480                 io_apic_ints[nintrs].int_type = 3;      /* ExtInt */
1481                 io_apic_ints[nintrs].int_vector = 0xff; /* Unassigned */
1482                 /* XXX fixme, set src bus id etc, but it doesn't seem to hurt */
1483                 io_apic_ints[nintrs].dst_apic_id = IO_TO_ID(0);
1484                 io_apic_ints[nintrs].dst_apic_int = 0;  /* Pin 0 */
1485                 nintrs++;
1486         } else if (apic_int_type(0, 0) == 0) {
1487                 kprintf("APIC_IO: MP table broken: ExtINT entry corrupt!\n");
1488                 for (x = 0; x < nintrs; ++x)
1489                         if ((ID_TO_IO(io_apic_ints[x].dst_apic_id) == 0) &&
1490                             (io_apic_ints[x].dst_apic_int) == 0) {
1491                                 io_apic_ints[x].int_type = 3;
1492                                 io_apic_ints[x].int_vector = 0xff;
1493                                 break;
1494                         }
1495         }
1496
1497         /*
1498          * Fix missing IRQ 15 when IRQ 14 is an ISA interrupt.  IDE
1499          * controllers universally come in pairs.  If IRQ 14 is specified
1500          * as an ISA interrupt, then IRQ 15 had better be too.
1501          *
1502          * [ Shuttle XPC / AMD Athlon X2 ]
1503          *      The MPTable is missing an entry for IRQ 15.  Note that the
1504          *      ACPI table has an entry for both 14 and 15.
1505          */
1506         if (apic_int_type(0, 14) == 0 && apic_int_type(0, 15) == -1) {
1507                 kprintf("APIC_IO: MP table broken: IRQ 15 not ISA when IRQ 14 is!\n");
1508                 io14 = io_apic_find_int_entry(0, 14);
1509                 io_apic_ints[nintrs] = *io14;
1510                 io_apic_ints[nintrs].src_bus_irq = 15;
1511                 io_apic_ints[nintrs].dst_apic_int = 15;
1512                 nintrs++;
1513         }
1514 }
1515
1516 /* Assign low level interrupt handlers */
1517 static void
1518 setup_apic_irq_mapping(void)
1519 {
1520         int     x;
1521         int     int_vector;
1522
1523         /* Clear array */
1524         for (x = 0; x < APIC_INTMAPSIZE; x++) {
1525                 int_to_apicintpin[x].ioapic = -1;
1526                 int_to_apicintpin[x].int_pin = 0;
1527                 int_to_apicintpin[x].apic_address = NULL;
1528                 int_to_apicintpin[x].redirindex = 0;
1529
1530                 /* Default to masked */
1531                 int_to_apicintpin[x].flags = IOAPIC_IM_FLAG_MASKED;
1532         }
1533
1534         /* First assign ISA/EISA interrupts */
1535         for (x = 0; x < nintrs; x++) {
1536                 int_vector = io_apic_ints[x].src_bus_irq;
1537                 if (int_vector < APIC_INTMAPSIZE &&
1538                     io_apic_ints[x].int_vector == 0xff && 
1539                     int_to_apicintpin[int_vector].ioapic == -1 &&
1540                     (apic_int_is_bus_type(x, ISA) ||
1541                      apic_int_is_bus_type(x, EISA)) &&
1542                     io_apic_ints[x].int_type == 0) {
1543                         assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), 
1544                                         io_apic_ints[x].dst_apic_int,
1545                                         int_vector);
1546                 }
1547         }
1548
1549         /* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
1550         for (x = 0; x < nintrs; x++) {
1551                 if (io_apic_ints[x].dst_apic_int == 0 &&
1552                     io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
1553                     io_apic_ints[x].int_vector == 0xff && 
1554                     int_to_apicintpin[0].ioapic == -1 &&
1555                     io_apic_ints[x].int_type == 3) {
1556                         assign_apic_irq(0, 0, 0);
1557                         break;
1558                 }
1559         }
1560
1561         /* Assign PCI interrupts */
1562         for (x = 0; x < nintrs; ++x) {
1563                 if (io_apic_ints[x].int_type == 0 &&
1564                     io_apic_ints[x].int_vector == 0xff && 
1565                     apic_int_is_bus_type(x, PCI))
1566                         allocate_apic_irq(x);
1567         }
1568 }
1569
1570 void
1571 mp_set_cpuids(int cpu_id, int apic_id)
1572 {
1573         CPU_TO_ID(cpu_id) = apic_id;
1574         ID_TO_CPU(apic_id) = cpu_id;
1575
1576         if (apic_id > lapic_id_max)
1577                 lapic_id_max = apic_id;
1578 }
1579
1580 static int
1581 processor_entry(const struct PROCENTRY *entry, int cpu)
1582 {
1583         KKASSERT(cpu > 0);
1584
1585         /* check for usability */
1586         if (!(entry->cpu_flags & PROCENTRY_FLAG_EN))
1587                 return 0;
1588
1589         /* check for BSP flag */
1590         if (entry->cpu_flags & PROCENTRY_FLAG_BP) {
1591                 mp_set_cpuids(0, entry->apic_id);
1592                 return 0;       /* its already been counted */
1593         }
1594
1595         /* add another AP to list, if less than max number of CPUs */
1596         else if (cpu < MAXCPU) {
1597                 mp_set_cpuids(cpu, entry->apic_id);
1598                 return 1;
1599         }
1600
1601         return 0;
1602 }
1603
1604 static int
1605 bus_entry(const struct BUSENTRY *entry, int bus)
1606 {
1607         int     x;
1608         char    c, name[8];
1609
1610         /* encode the name into an index */
1611         for (x = 0; x < 6; ++x) {
1612                 if ((c = entry->bus_type[x]) == ' ')
1613                         break;
1614                 name[x] = c;
1615         }
1616         name[x] = '\0';
1617
1618         if ((x = lookup_bus_type(name)) == UNKNOWN_BUSTYPE)
1619                 panic("unknown bus type: '%s'", name);
1620
1621         bus_data[bus].bus_id = entry->bus_id;
1622         bus_data[bus].bus_type = x;
1623
1624         return 1;
1625 }
1626
1627 static int
1628 io_apic_entry(const struct IOAPICENTRY *entry, int apic)
1629 {
1630         if (!(entry->apic_flags & IOAPICENTRY_FLAG_EN))
1631                 return 0;
1632
1633         IO_TO_ID(apic) = entry->apic_id;
1634         ID_TO_IO(entry->apic_id) = apic;
1635
1636         return 1;
1637 }
1638
1639 static int
1640 lookup_bus_type(char *name)
1641 {
1642         int     x;
1643
1644         for (x = 0; x < MAX_BUSTYPE; ++x)
1645                 if (strcmp(bus_type_table[x].name, name) == 0)
1646                         return bus_type_table[x].type;
1647
1648         return UNKNOWN_BUSTYPE;
1649 }
1650
1651 static int
1652 int_entry(const struct INTENTRY *entry, int intr)
1653 {
1654         int apic;
1655
1656         io_apic_ints[intr].int_type = entry->int_type;
1657         io_apic_ints[intr].int_flags = entry->int_flags;
1658         io_apic_ints[intr].src_bus_id = entry->src_bus_id;
1659         io_apic_ints[intr].src_bus_irq = entry->src_bus_irq;
1660         if (entry->dst_apic_id == 255) {
1661                 /* This signal goes to all IO APICS.  Select an IO APIC
1662                    with sufficient number of interrupt pins */
1663                 for (apic = 0; apic < mp_napics; apic++)
1664                         if (((ioapic_read(ioapic[apic], IOAPIC_VER) & 
1665                               IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) >= 
1666                             entry->dst_apic_int)
1667                                 break;
1668                 if (apic < mp_napics)
1669                         io_apic_ints[intr].dst_apic_id = IO_TO_ID(apic);
1670                 else
1671                         io_apic_ints[intr].dst_apic_id = entry->dst_apic_id;
1672         } else
1673                 io_apic_ints[intr].dst_apic_id = entry->dst_apic_id;
1674         io_apic_ints[intr].dst_apic_int = entry->dst_apic_int;
1675
1676         return 1;
1677 }
1678
1679 static int
1680 apic_int_is_bus_type(int intr, int bus_type)
1681 {
1682         int     bus;
1683
1684         for (bus = 0; bus < mp_nbusses; ++bus)
1685                 if ((bus_data[bus].bus_id == io_apic_ints[intr].src_bus_id)
1686                     && ((int) bus_data[bus].bus_type == bus_type))
1687                         return 1;
1688
1689         return 0;
1690 }
1691
1692 /*
1693  * Given a traditional ISA INT mask, return an APIC mask.
1694  */
1695 u_int
1696 isa_apic_mask(u_int isa_mask)
1697 {
1698         int isa_irq;
1699         int apic_pin;
1700
1701 #if defined(SKIP_IRQ15_REDIRECT)
1702         if (isa_mask == (1 << 15)) {
1703                 kprintf("skipping ISA IRQ15 redirect\n");
1704                 return isa_mask;
1705         }
1706 #endif  /* SKIP_IRQ15_REDIRECT */
1707
1708         isa_irq = ffs(isa_mask);                /* find its bit position */
1709         if (isa_irq == 0)                       /* doesn't exist */
1710                 return 0;
1711         --isa_irq;                              /* make it zero based */
1712
1713         apic_pin = isa_apic_irq(isa_irq);       /* look for APIC connection */
1714         if (apic_pin == -1)
1715                 return 0;
1716
1717         return (1 << apic_pin);                 /* convert pin# to a mask */
1718 }
1719
1720 /*
1721  * Determine which APIC pin an ISA/EISA INT is attached to.
1722  */
1723 #define INTTYPE(I)      (io_apic_ints[(I)].int_type)
1724 #define INTPIN(I)       (io_apic_ints[(I)].dst_apic_int)
1725 #define INTIRQ(I)       (io_apic_ints[(I)].int_vector)
1726 #define INTAPIC(I)      (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
1727
1728 #define SRCBUSIRQ(I)    (io_apic_ints[(I)].src_bus_irq)
1729 int
1730 isa_apic_irq(int isa_irq)
1731 {
1732         int     intr;
1733
1734         for (intr = 0; intr < nintrs; ++intr) {         /* check each record */
1735                 if (INTTYPE(intr) == 0) {               /* standard INT */
1736                         if (SRCBUSIRQ(intr) == isa_irq) {
1737                                 if (apic_int_is_bus_type(intr, ISA) ||
1738                                     apic_int_is_bus_type(intr, EISA)) {
1739                                         if (INTIRQ(intr) == 0xff)
1740                                                 return -1; /* unassigned */
1741                                         return INTIRQ(intr);    /* found */
1742                                 }
1743                         }
1744                 }
1745         }
1746         return -1;                                      /* NOT found */
1747 }
1748
1749
1750 /*
1751  * Determine which APIC pin a PCI INT is attached to.
1752  */
1753 #define SRCBUSID(I)     (io_apic_ints[(I)].src_bus_id)
1754 #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
1755 #define SRCBUSLINE(I)   (io_apic_ints[(I)].src_bus_irq & 0x03)
1756 int
1757 pci_apic_irq(int pciBus, int pciDevice, int pciInt)
1758 {
1759         int     intr;
1760
1761         --pciInt;                                       /* zero based */
1762
1763         for (intr = 0; intr < nintrs; ++intr) {         /* check each record */
1764                 if ((INTTYPE(intr) == 0)                /* standard INT */
1765                     && (SRCBUSID(intr) == pciBus)
1766                     && (SRCBUSDEVICE(intr) == pciDevice)
1767                     && (SRCBUSLINE(intr) == pciInt)) {  /* a candidate IRQ */
1768                         if (apic_int_is_bus_type(intr, PCI)) {
1769                                 if (INTIRQ(intr) == 0xff) {
1770                                         kprintf("IOAPIC: pci_apic_irq() "
1771                                                 "failed\n");
1772                                         return -1;      /* unassigned */
1773                                 }
1774                                 return INTIRQ(intr);    /* exact match */
1775                         }
1776                 }
1777         }
1778
1779         return -1;                                      /* NOT found */
1780 }
1781
1782 int
1783 next_apic_irq(int irq) 
1784 {
1785         int intr, ointr;
1786         int bus, bustype;
1787
1788         bus = 0;
1789         bustype = 0;
1790         for (intr = 0; intr < nintrs; intr++) {
1791                 if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
1792                         continue;
1793                 bus = SRCBUSID(intr);
1794                 bustype = apic_bus_type(bus);
1795                 if (bustype != ISA &&
1796                     bustype != EISA &&
1797                     bustype != PCI)
1798                         continue;
1799                 break;
1800         }
1801         if (intr >= nintrs) {
1802                 return -1;
1803         }
1804         for (ointr = intr + 1; ointr < nintrs; ointr++) {
1805                 if (INTTYPE(ointr) != 0)
1806                         continue;
1807                 if (bus != SRCBUSID(ointr))
1808                         continue;
1809                 if (bustype == PCI) {
1810                         if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr))
1811                                 continue;
1812                         if (SRCBUSLINE(intr) != SRCBUSLINE(ointr))
1813                                 continue;
1814                 }
1815                 if (bustype == ISA || bustype == EISA) {
1816                         if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr))
1817                                 continue;
1818                 }
1819                 if (INTPIN(intr) == INTPIN(ointr))
1820                         continue;
1821                 break;
1822         }
1823         if (ointr >= nintrs) {
1824                 return -1;
1825         }
1826         return INTIRQ(ointr);
1827 }
1828 #undef SRCBUSLINE
1829 #undef SRCBUSDEVICE
1830 #undef SRCBUSID
1831 #undef SRCBUSIRQ
1832
1833 #undef INTPIN
1834 #undef INTIRQ
1835 #undef INTAPIC
1836 #undef INTTYPE
1837
1838 /*
1839  * Reprogram the MB chipset to NOT redirect an ISA INTerrupt.
1840  *
1841  * XXX FIXME:
1842  *  Exactly what this means is unclear at this point.  It is a solution
1843  *  for motherboards that redirect the MBIRQ0 pin.  Generically a motherboard
1844  *  could route any of the ISA INTs to upper (>15) IRQ values.  But most would
1845  *  NOT be redirected via MBIRQ0, thus "undirect()ing" them would NOT be an
1846  *  option.
1847  */
1848 int
1849 undirect_isa_irq(int rirq)
1850 {
1851 #if defined(READY)
1852         if (bootverbose)
1853             kprintf("Freeing redirected ISA irq %d.\n", rirq);
1854         /** FIXME: tickle the MB redirector chip */
1855         return /* XXX */;
1856 #else
1857         if (bootverbose)
1858             kprintf("Freeing (NOT implemented) redirected ISA irq %d.\n", rirq);
1859         return 0;
1860 #endif  /* READY */
1861 }
1862
1863
1864 /*
1865  * Reprogram the MB chipset to NOT redirect a PCI INTerrupt
1866  */
1867 int
1868 undirect_pci_irq(int rirq)
1869 {
1870 #if defined(READY)
1871         if (bootverbose)
1872                 kprintf("Freeing redirected PCI irq %d.\n", rirq);
1873
1874         /** FIXME: tickle the MB redirector chip */
1875         return /* XXX */;
1876 #else
1877         if (bootverbose)
1878                 kprintf("Freeing (NOT implemented) redirected PCI irq %d.\n",
1879                        rirq);
1880         return 0;
1881 #endif  /* READY */
1882 }
1883
1884
1885 /*
1886  * given a bus ID, return:
1887  *  the bus type if found
1888  *  -1 if NOT found
1889  */
1890 int
1891 apic_bus_type(int id)
1892 {
1893         int     x;
1894
1895         for (x = 0; x < mp_nbusses; ++x)
1896                 if (bus_data[x].bus_id == id)
1897                         return bus_data[x].bus_type;
1898
1899         return -1;
1900 }
1901
1902 /*
1903  * given a LOGICAL APIC# and pin#, return:
1904  *  the associated src bus ID if found
1905  *  -1 if NOT found
1906  */
1907 int
1908 apic_src_bus_id(int apic, int pin)
1909 {
1910         int     x;
1911
1912         /* search each of the possible INTerrupt sources */
1913         for (x = 0; x < nintrs; ++x)
1914                 if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
1915                     (pin == io_apic_ints[x].dst_apic_int))
1916                         return (io_apic_ints[x].src_bus_id);
1917
1918         return -1;              /* NOT found */
1919 }
1920
1921 /*
1922  * given a LOGICAL APIC# and pin#, return:
1923  *  the associated src bus IRQ if found
1924  *  -1 if NOT found
1925  */
1926 int
1927 apic_src_bus_irq(int apic, int pin)
1928 {
1929         int     x;
1930
1931         for (x = 0; x < nintrs; x++)
1932                 if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
1933                     (pin == io_apic_ints[x].dst_apic_int))
1934                         return (io_apic_ints[x].src_bus_irq);
1935
1936         return -1;              /* NOT found */
1937 }
1938
1939
1940 /*
1941  * given a LOGICAL APIC# and pin#, return:
1942  *  the associated INTerrupt type if found
1943  *  -1 if NOT found
1944  */
1945 int
1946 apic_int_type(int apic, int pin)
1947 {
1948         int     x;
1949
1950         /* search each of the possible INTerrupt sources */
1951         for (x = 0; x < nintrs; ++x) {
1952                 if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
1953                     (pin == io_apic_ints[x].dst_apic_int))
1954                         return (io_apic_ints[x].int_type);
1955         }
1956         return -1;              /* NOT found */
1957 }
1958
1959 /*
1960  * Return the IRQ associated with an APIC pin
1961  */
1962 int 
1963 apic_irq(int apic, int pin)
1964 {
1965         int x;
1966         int res;
1967
1968         for (x = 0; x < nintrs; ++x) {
1969                 if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
1970                     (pin == io_apic_ints[x].dst_apic_int)) {
1971                         res = io_apic_ints[x].int_vector;
1972                         if (res == 0xff)
1973                                 return -1;
1974                         if (apic != int_to_apicintpin[res].ioapic)
1975                                 panic("apic_irq: inconsistent table %d/%d", apic, int_to_apicintpin[res].ioapic);
1976                         if (pin != int_to_apicintpin[res].int_pin)
1977                                 panic("apic_irq inconsistent table (2)");
1978                         return res;
1979                 }
1980         }
1981         return -1;
1982 }
1983
1984
1985 /*
1986  * given a LOGICAL APIC# and pin#, return:
1987  *  the associated trigger mode if found
1988  *  -1 if NOT found
1989  */
1990 int
1991 apic_trigger(int apic, int pin)
1992 {
1993         int     x;
1994
1995         /* search each of the possible INTerrupt sources */
1996         for (x = 0; x < nintrs; ++x)
1997                 if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
1998                     (pin == io_apic_ints[x].dst_apic_int))
1999                         return ((io_apic_ints[x].int_flags >> 2) & 0x03);
2000
2001         return -1;              /* NOT found */
2002 }
2003
2004
2005 /*
2006  * given a LOGICAL APIC# and pin#, return:
2007  *  the associated 'active' level if found
2008  *  -1 if NOT found
2009  */
2010 int
2011 apic_polarity(int apic, int pin)
2012 {
2013         int     x;
2014
2015         /* search each of the possible INTerrupt sources */
2016         for (x = 0; x < nintrs; ++x)
2017                 if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
2018                     (pin == io_apic_ints[x].dst_apic_int))
2019                         return (io_apic_ints[x].int_flags & 0x03);
2020
2021         return -1;              /* NOT found */
2022 }
2023
2024 /*
2025  * set data according to MP defaults
2026  * FIXME: probably not complete yet...
2027  */
2028 static void
2029 mptable_default(int type)
2030 {
2031         int     io_apic_id;
2032         int     pin;
2033
2034 #if 0
2035         kprintf("  MP default config type: %d\n", type);
2036         switch (type) {
2037         case 1:
2038                 kprintf("   bus: ISA, APIC: 82489DX\n");
2039                 break;
2040         case 2:
2041                 kprintf("   bus: EISA, APIC: 82489DX\n");
2042                 break;
2043         case 3:
2044                 kprintf("   bus: EISA, APIC: 82489DX\n");
2045                 break;
2046         case 4:
2047                 kprintf("   bus: MCA, APIC: 82489DX\n");
2048                 break;
2049         case 5:
2050                 kprintf("   bus: ISA+PCI, APIC: Integrated\n");
2051                 break;
2052         case 6:
2053                 kprintf("   bus: EISA+PCI, APIC: Integrated\n");
2054                 break;
2055         case 7:
2056                 kprintf("   bus: MCA+PCI, APIC: Integrated\n");
2057                 break;
2058         default:
2059                 kprintf("   future type\n");
2060                 break;
2061                 /* NOTREACHED */
2062         }
2063 #endif  /* 0 */
2064
2065         /* one and only IO APIC */
2066         io_apic_id = (ioapic_read(ioapic[0], IOAPIC_ID) & APIC_ID_MASK) >> 24;
2067
2068         /*
2069          * sanity check, refer to MP spec section 3.6.6, last paragraph
2070          * necessary as some hardware isn't properly setting up the IO APIC
2071          */
2072 #if defined(REALLY_ANAL_IOAPICID_VALUE)
2073         if (io_apic_id != 2) {
2074 #else
2075         if ((io_apic_id == 0) || (io_apic_id == 1) || (io_apic_id == 15)) {
2076 #endif  /* REALLY_ANAL_IOAPICID_VALUE */
2077                 io_apic_set_id(0, 2);
2078                 io_apic_id = 2;
2079         }
2080         IO_TO_ID(0) = io_apic_id;
2081         ID_TO_IO(io_apic_id) = 0;
2082
2083         /* fill out bus entries */
2084         switch (type) {
2085         case 1:
2086         case 2:
2087         case 3:
2088         case 4:
2089         case 5:
2090         case 6:
2091         case 7:
2092                 bus_data[0].bus_id = default_data[type - 1][1];
2093                 bus_data[0].bus_type = default_data[type - 1][2];
2094                 bus_data[1].bus_id = default_data[type - 1][3];
2095                 bus_data[1].bus_type = default_data[type - 1][4];
2096                 break;
2097
2098         /* case 4: case 7:                 MCA NOT supported */
2099         default:                /* illegal/reserved */
2100                 panic("BAD default MP config: %d", type);
2101                 /* NOTREACHED */
2102         }
2103
2104         /* general cases from MP v1.4, table 5-2 */
2105         for (pin = 0; pin < 16; ++pin) {
2106                 io_apic_ints[pin].int_type = 0;
2107                 io_apic_ints[pin].int_flags = 0x05;     /* edge/active-hi */
2108                 io_apic_ints[pin].src_bus_id = 0;
2109                 io_apic_ints[pin].src_bus_irq = pin;    /* IRQ2 caught below */
2110                 io_apic_ints[pin].dst_apic_id = io_apic_id;
2111                 io_apic_ints[pin].dst_apic_int = pin;   /* 1-to-1 */
2112         }
2113
2114         /* special cases from MP v1.4, table 5-2 */
2115         if (type == 2) {
2116                 io_apic_ints[2].int_type = 0xff;        /* N/C */
2117                 io_apic_ints[13].int_type = 0xff;       /* N/C */
2118 #if !defined(APIC_MIXED_MODE)
2119                 /** FIXME: ??? */
2120                 panic("sorry, can't support type 2 default yet");
2121 #endif  /* APIC_MIXED_MODE */
2122         }
2123         else
2124                 io_apic_ints[2].src_bus_irq = 0;        /* ISA IRQ0 is on APIC INT 2 */
2125
2126         if (type == 7)
2127                 io_apic_ints[0].int_type = 0xff;        /* N/C */
2128         else
2129                 io_apic_ints[0].int_type = 3;   /* vectored 8259 */
2130 }
2131
2132 /*
2133  * Map a physical memory address representing I/O into KVA.  The I/O
2134  * block is assumed not to cross a page boundary.
2135  */
2136 void *
2137 ioapic_map(vm_paddr_t pa)
2138 {
2139         KKASSERT(pa < 0x100000000LL);
2140
2141         return pmap_mapdev_uncacheable(pa, PAGE_SIZE);
2142 }
2143
2144 /*
2145  * start each AP in our list
2146  */
2147 static int
2148 start_all_aps(u_int boot_addr)
2149 {
2150         vm_offset_t va = boot_address + KERNBASE;
2151         u_int64_t *pt4, *pt3, *pt2;
2152         int     x, i, pg;
2153         int     shift;
2154         int     smicount;
2155         int     smibest;
2156         int     smilast;
2157         u_char  mpbiosreason;
2158         u_long  mpbioswarmvec;
2159         struct mdglobaldata *gd;
2160         struct privatespace *ps;
2161
2162         POSTCODE(START_ALL_APS_POST);
2163
2164         /* install the AP 1st level boot code */
2165         pmap_kenter(va, boot_address);
2166         cpu_invlpg((void *)va);         /* JG XXX */
2167         bcopy(mptramp_start, (void *)va, bootMP_size);
2168
2169         /* Locate the page tables, they'll be below the trampoline */
2170         pt4 = (u_int64_t *)(uintptr_t)(mptramp_pagetables + KERNBASE);
2171         pt3 = pt4 + (PAGE_SIZE) / sizeof(u_int64_t);
2172         pt2 = pt3 + (PAGE_SIZE) / sizeof(u_int64_t);
2173
2174         /* Create the initial 1GB replicated page tables */
2175         for (i = 0; i < 512; i++) {
2176                 /* Each slot of the level 4 pages points to the same level 3 page */
2177                 pt4[i] = (u_int64_t)(uintptr_t)(mptramp_pagetables + PAGE_SIZE);
2178                 pt4[i] |= PG_V | PG_RW | PG_U;
2179
2180                 /* Each slot of the level 3 pages points to the same level 2 page */
2181                 pt3[i] = (u_int64_t)(uintptr_t)(mptramp_pagetables + (2 * PAGE_SIZE));
2182                 pt3[i] |= PG_V | PG_RW | PG_U;
2183
2184                 /* The level 2 page slots are mapped with 2MB pages for 1GB. */
2185                 pt2[i] = i * (2 * 1024 * 1024);
2186                 pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
2187         }
2188
2189         /* save the current value of the warm-start vector */
2190         mpbioswarmvec = *((u_int32_t *) WARMBOOT_OFF);
2191         outb(CMOS_REG, BIOS_RESET);
2192         mpbiosreason = inb(CMOS_DATA);
2193
2194         /* setup a vector to our boot code */
2195         *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
2196         *((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4);
2197         outb(CMOS_REG, BIOS_RESET);
2198         outb(CMOS_DATA, BIOS_WARM);     /* 'warm-start' */
2199
2200         /*
2201          * If we have a TSC we can figure out the SMI interrupt rate.
2202          * The SMI does not necessarily use a constant rate.  Spend
2203          * up to 250ms trying to figure it out.
2204          */
2205         smibest = 0;
2206         if (cpu_feature & CPUID_TSC) {
2207                 set_apic_timer(275000);
2208                 smilast = read_apic_timer();
2209                 for (x = 0; x < 20 && read_apic_timer(); ++x) {
2210                         smicount = smitest();
2211                         if (smibest == 0 || smilast - smicount < smibest)
2212                                 smibest = smilast - smicount;
2213                         smilast = smicount;
2214                 }
2215                 if (smibest > 250000)
2216                         smibest = 0;
2217                 if (smibest) {
2218                         smibest = smibest * (int64_t)1000000 /
2219                                   get_apic_timer_frequency();
2220                 }
2221         }
2222         if (smibest)
2223                 kprintf("SMI Frequency (worst case): %d Hz (%d us)\n",
2224                         1000000 / smibest, smibest);
2225
2226         /* start each AP */
2227         for (x = 1; x <= mp_naps; ++x) {
2228
2229                 /* This is a bit verbose, it will go away soon.  */
2230
2231                 /* first page of AP's private space */
2232                 pg = x * x86_64_btop(sizeof(struct privatespace));
2233
2234                 /* allocate new private data page(s) */
2235                 gd = (struct mdglobaldata *)kmem_alloc(&kernel_map, 
2236                                 MDGLOBALDATA_BASEALLOC_SIZE);
2237
2238                 gd = &CPU_prvspace[x].mdglobaldata;     /* official location */
2239                 bzero(gd, sizeof(*gd));
2240                 gd->mi.gd_prvspace = ps = &CPU_prvspace[x];
2241
2242                 /* prime data page for it to use */
2243                 mi_gdinit(&gd->mi, x);
2244                 cpu_gdinit(gd, x);
2245                 gd->mi.gd_ipiq = (void *)kmem_alloc(&kernel_map, sizeof(lwkt_ipiq) * (mp_naps + 1));
2246                 bzero(gd->mi.gd_ipiq, sizeof(lwkt_ipiq) * (mp_naps + 1));
2247
2248                 /* setup a vector to our boot code */
2249                 *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
2250                 *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4);
2251                 outb(CMOS_REG, BIOS_RESET);
2252                 outb(CMOS_DATA, BIOS_WARM);     /* 'warm-start' */
2253
2254                 /*
2255                  * Setup the AP boot stack
2256                  */
2257                 bootSTK = &ps->idlestack[UPAGES*PAGE_SIZE/2];
2258                 bootAP = x;
2259
2260                 /* attempt to start the Application Processor */
2261                 CHECK_INIT(99); /* setup checkpoints */
2262                 if (!start_ap(gd, boot_addr, smibest)) {
2263                         kprintf("\nAP #%d (PHY# %d) failed!\n",
2264                                 x, CPU_TO_ID(x));
2265                         CHECK_PRINT("trace");   /* show checkpoints */
2266                         /* better panic as the AP may be running loose */
2267                         kprintf("panic y/n? [y] ");
2268                         if (cngetc() != 'n')
2269                                 panic("bye-bye");
2270                 }
2271                 CHECK_PRINT("trace");           /* show checkpoints */
2272
2273                 /* record its version info */
2274                 cpu_apic_versions[x] = cpu_apic_versions[0];
2275         }
2276
2277         /* set ncpus to 1 + highest logical cpu.  Not all may have come up */
2278         ncpus = x;
2279
2280         /* ncpus2 -- ncpus rounded down to the nearest power of 2 */
2281         for (shift = 0; (1 << shift) <= ncpus; ++shift)
2282                 ;
2283         --shift;
2284         ncpus2_shift = shift;
2285         ncpus2 = 1 << shift;
2286         ncpus2_mask = ncpus2 - 1;
2287
2288         /* ncpus_fit -- ncpus rounded up to the nearest power of 2 */
2289         if ((1 << shift) < ncpus)
2290                 ++shift;
2291         ncpus_fit = 1 << shift;
2292         ncpus_fit_mask = ncpus_fit - 1;
2293
2294         /* build our map of 'other' CPUs */
2295         mycpu->gd_other_cpus = smp_startup_mask & ~CPUMASK(mycpu->gd_cpuid);
2296         mycpu->gd_ipiq = (void *)kmem_alloc(&kernel_map, sizeof(lwkt_ipiq) * ncpus);
2297         bzero(mycpu->gd_ipiq, sizeof(lwkt_ipiq) * ncpus);
2298
2299         /* fill in our (BSP) APIC version */
2300         cpu_apic_versions[0] = lapic->version;
2301
2302         /* restore the warmstart vector */
2303         *(u_long *) WARMBOOT_OFF = mpbioswarmvec;
2304         outb(CMOS_REG, BIOS_RESET);
2305         outb(CMOS_DATA, mpbiosreason);
2306
2307         /*
2308          * NOTE!  The idlestack for the BSP was setup by locore.  Finish
2309          * up, clean out the P==V mapping we did earlier.
2310          */
2311         pmap_set_opt();
2312
2313         /*
2314          * Wait all APs to finish initializing LAPIC
2315          */
2316         mp_finish_lapic = 1;
2317         if (bootverbose)
2318                 kprintf("SMP: Waiting APs LAPIC initialization\n");
2319         if (cpu_feature & CPUID_TSC)
2320                 tsc0_offset = rdtsc();
2321         tsc_offsets[0] = 0;
2322         rel_mplock();
2323         while (smp_lapic_mask != smp_startup_mask) {
2324                 cpu_lfence();
2325                 if (cpu_feature & CPUID_TSC)
2326                         tsc0_offset = rdtsc();
2327         }
2328         while (try_mplock() == 0)
2329                 ;
2330
2331         /* number of APs actually started */
2332         return ncpus - 1;
2333 }
2334
2335
2336 /*
2337  * load the 1st level AP boot code into base memory.
2338  */
2339
2340 /* targets for relocation */
2341 extern void bigJump(void);
2342 extern void bootCodeSeg(void);
2343 extern void bootDataSeg(void);
2344 extern void MPentry(void);
2345 extern u_int MP_GDT;
2346 extern u_int mp_gdtbase;
2347
2348 #if 0
2349
2350 static void
2351 install_ap_tramp(u_int boot_addr)
2352 {
2353         int     x;
2354         int     size = *(int *) ((u_long) & bootMP_size);
2355         u_char *src = (u_char *) ((u_long) bootMP);
2356         u_char *dst = (u_char *) boot_addr + KERNBASE;
2357         u_int   boot_base = (u_int) bootMP;
2358         u_int8_t *dst8;
2359         u_int16_t *dst16;
2360         u_int32_t *dst32;
2361
2362         POSTCODE(INSTALL_AP_TRAMP_POST);
2363
2364         for (x = 0; x < size; ++x)
2365                 *dst++ = *src++;
2366
2367         /*
2368          * modify addresses in code we just moved to basemem. unfortunately we
2369          * need fairly detailed info about mpboot.s for this to work.  changes
2370          * to mpboot.s might require changes here.
2371          */
2372
2373         /* boot code is located in KERNEL space */
2374         dst = (u_char *) boot_addr + KERNBASE;
2375
2376         /* modify the lgdt arg */
2377         dst32 = (u_int32_t *) (dst + ((u_int) & mp_gdtbase - boot_base));
2378         *dst32 = boot_addr + ((u_int) & MP_GDT - boot_base);
2379
2380         /* modify the ljmp target for MPentry() */
2381         dst32 = (u_int32_t *) (dst + ((u_int) bigJump - boot_base) + 1);
2382         *dst32 = ((u_int) MPentry - KERNBASE);
2383
2384         /* modify the target for boot code segment */
2385         dst16 = (u_int16_t *) (dst + ((u_int) bootCodeSeg - boot_base));
2386         dst8 = (u_int8_t *) (dst16 + 1);
2387         *dst16 = (u_int) boot_addr & 0xffff;
2388         *dst8 = ((u_int) boot_addr >> 16) & 0xff;
2389
2390         /* modify the target for boot data segment */
2391         dst16 = (u_int16_t *) (dst + ((u_int) bootDataSeg - boot_base));
2392         dst8 = (u_int8_t *) (dst16 + 1);
2393         *dst16 = (u_int) boot_addr & 0xffff;
2394         *dst8 = ((u_int) boot_addr >> 16) & 0xff;
2395 }
2396
2397 #endif
2398
2399 /*
2400  * This function starts the AP (application processor) identified
2401  * by the APIC ID 'physicalCpu'.  It does quite a "song and dance"
2402  * to accomplish this.  This is necessary because of the nuances
2403  * of the different hardware we might encounter.  It ain't pretty,
2404  * but it seems to work.
2405  *
2406  * NOTE: eventually an AP gets to ap_init(), which is called just 
2407  * before the AP goes into the LWKT scheduler's idle loop.
2408  */
2409 static int
2410 start_ap(struct mdglobaldata *gd, u_int boot_addr, int smibest)
2411 {
2412         int     physical_cpu;
2413         int     vector;
2414         u_long  icr_lo, icr_hi;
2415
2416         POSTCODE(START_AP_POST);
2417
2418         /* get the PHYSICAL APIC ID# */
2419         physical_cpu = CPU_TO_ID(gd->mi.gd_cpuid);
2420
2421         /* calculate the vector */
2422         vector = (boot_addr >> 12) & 0xff;
2423
2424         /* We don't want anything interfering */
2425         cpu_disable_intr();
2426
2427         /* Make sure the target cpu sees everything */
2428         wbinvd();
2429
2430         /*
2431          * Try to detect when a SMI has occurred, wait up to 200ms.
2432          *
2433          * If a SMI occurs during an AP reset but before we issue
2434          * the STARTUP command, the AP may brick.  To work around
2435          * this problem we hold off doing the AP startup until
2436          * after we have detected the SMI.  Hopefully another SMI
2437          * will not occur before we finish the AP startup.
2438          *
2439          * Retries don't seem to help.  SMIs have a window of opportunity
2440          * and if USB->legacy keyboard emulation is enabled in the BIOS
2441          * the interrupt rate can be quite high.
2442          *
2443          * NOTE: Don't worry about the L1 cache load, it might bloat
2444          *       ldelta a little but ndelta will be so huge when the SMI
2445          *       occurs the detection logic will still work fine.
2446          */
2447         if (smibest) {
2448                 set_apic_timer(200000);
2449                 smitest();
2450         }
2451
2452         /*
2453          * first we do an INIT/RESET IPI this INIT IPI might be run, reseting
2454          * and running the target CPU. OR this INIT IPI might be latched (P5
2455          * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be
2456          * ignored.
2457          *
2458          * see apic/apicreg.h for icr bit definitions.
2459          *
2460          * TIME CRITICAL CODE, DO NOT DO ANY KPRINTFS IN THE HOT PATH.
2461          */
2462
2463         /*
2464          * Setup the address for the target AP.  We can setup
2465          * icr_hi once and then just trigger operations with
2466          * icr_lo.
2467          */
2468         icr_hi = lapic->icr_hi & ~APIC_ID_MASK;
2469         icr_hi |= (physical_cpu << 24);
2470         icr_lo = lapic->icr_lo & 0xfff00000;
2471         lapic->icr_hi = icr_hi;
2472
2473         /*
2474          * Do an INIT IPI: assert RESET
2475          *
2476          * Use edge triggered mode to assert INIT
2477          */
2478         lapic->icr_lo = icr_lo | 0x00004500;
2479         while (lapic->icr_lo & APIC_DELSTAT_MASK)
2480                  /* spin */ ;
2481
2482         /*
2483          * The spec calls for a 10ms delay but we may have to use a
2484          * MUCH lower delay to avoid bricking an AP due to a fast SMI
2485          * interrupt.  We have other loops here too and dividing by 2
2486          * doesn't seem to be enough even after subtracting 350us,
2487          * so we divide by 4.
2488          *
2489          * Our minimum delay is 150uS, maximum is 10ms.  If no SMI
2490          * interrupt was detected we use the full 10ms.
2491          */
2492         if (smibest == 0)
2493                 u_sleep(10000);
2494         else if (smibest < 150 * 4 + 350)
2495                 u_sleep(150);
2496         else if ((smibest - 350) / 4 < 10000)
2497                 u_sleep((smibest - 350) / 4);
2498         else
2499                 u_sleep(10000);
2500
2501         /*
2502          * Do an INIT IPI: deassert RESET
2503          *
2504          * Use level triggered mode to deassert.  It is unclear
2505          * why we need to do this.
2506          */
2507         lapic->icr_lo = icr_lo | 0x00008500;
2508         while (lapic->icr_lo & APIC_DELSTAT_MASK)
2509                  /* spin */ ;
2510         u_sleep(150);                           /* wait 150us */
2511
2512         /*
2513          * Next we do a STARTUP IPI: the previous INIT IPI might still be
2514          * latched, (P5 bug) this 1st STARTUP would then terminate
2515          * immediately, and the previously started INIT IPI would continue. OR
2516          * the previous INIT IPI has already run. and this STARTUP IPI will
2517          * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
2518          * will run.
2519          */
2520         lapic->icr_lo = icr_lo | 0x00000600 | vector;
2521         while (lapic->icr_lo & APIC_DELSTAT_MASK)
2522                  /* spin */ ;
2523         u_sleep(200);           /* wait ~200uS */
2524
2525         /*
2526          * Finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
2527          * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
2528          * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
2529          * recognized after hardware RESET or INIT IPI.
2530          */
2531         lapic->icr_lo = icr_lo | 0x00000600 | vector;
2532         while (lapic->icr_lo & APIC_DELSTAT_MASK)
2533                  /* spin */ ;
2534
2535         /* Resume normal operation */
2536         cpu_enable_intr();
2537
2538         /* wait for it to start, see ap_init() */
2539         set_apic_timer(5000000);/* == 5 seconds */
2540         while (read_apic_timer()) {
2541                 if (smp_startup_mask & CPUMASK(gd->mi.gd_cpuid))
2542                         return 1;       /* return SUCCESS */
2543         }
2544
2545         return 0;               /* return FAILURE */
2546 }
2547
2548 static
2549 int
2550 smitest(void)
2551 {
2552         int64_t ltsc;
2553         int64_t ntsc;
2554         int64_t ldelta;
2555         int64_t ndelta;
2556         int count;
2557
2558         ldelta = 0;
2559         ndelta = 0;
2560         while (read_apic_timer()) {
2561                 ltsc = rdtsc();
2562                 for (count = 0; count < 100; ++count)
2563                         ntsc = rdtsc(); /* force loop to occur */
2564                 if (ldelta) {
2565                         ndelta = ntsc - ltsc;
2566                         if (ldelta > ndelta)
2567                                 ldelta = ndelta;
2568                         if (ndelta > ldelta * 2)
2569                                 break;
2570                 } else {
2571                         ldelta = ntsc - ltsc;
2572                 }
2573         }
2574         return(read_apic_timer());
2575 }
2576
2577 /*
2578  * Synchronously flush the TLB on all other CPU's.  The current cpu's
2579  * TLB is not flushed.  If the caller wishes to flush the current cpu's
2580  * TLB the caller must call cpu_invltlb() in addition to smp_invltlb().
2581  *
2582  * NOTE: If for some reason we were unable to start all cpus we cannot
2583  *       safely use broadcast IPIs.
2584  */
2585
2586 static cpumask_t smp_invltlb_req;
2587
2588 #define SMP_INVLTLB_DEBUG
2589
2590 void
2591 smp_invltlb(void)
2592 {
2593 #ifdef SMP
2594         struct mdglobaldata *md = mdcpu;
2595 #ifdef SMP_INVLTLB_DEBUG
2596         long count = 0;
2597         long xcount = 0;
2598 #endif
2599
2600         crit_enter_gd(&md->mi);
2601         md->gd_invltlb_ret = 0;
2602         ++md->mi.gd_cnt.v_smpinvltlb;
2603         atomic_set_cpumask(&smp_invltlb_req, md->mi.gd_cpumask);
2604 #ifdef SMP_INVLTLB_DEBUG
2605 again:
2606 #endif
2607         if (smp_startup_mask == smp_active_mask) {
2608                 all_but_self_ipi(XINVLTLB_OFFSET);
2609         } else {
2610                 selected_apic_ipi(smp_active_mask & ~md->mi.gd_cpumask,
2611                                   XINVLTLB_OFFSET, APIC_DELMODE_FIXED);
2612         }
2613
2614 #ifdef SMP_INVLTLB_DEBUG
2615         if (xcount)
2616                 kprintf("smp_invltlb: ipi sent\n");
2617 #endif
2618         while ((md->gd_invltlb_ret & smp_active_mask & ~md->mi.gd_cpumask) !=
2619                (smp_active_mask & ~md->mi.gd_cpumask)) {
2620                 cpu_mfence();
2621                 cpu_pause();
2622 #ifdef SMP_INVLTLB_DEBUG
2623                 /* DEBUGGING */
2624                 if (++count == 400000000) {
2625                         print_backtrace(-1);
2626                         kprintf("smp_invltlb: endless loop %08lx %08lx, "
2627                                 "rflags %016jx retry",
2628                               (long)md->gd_invltlb_ret,
2629                               (long)smp_invltlb_req,
2630                               (intmax_t)read_rflags());
2631                         __asm __volatile ("sti");
2632                         ++xcount;
2633                         if (xcount > 2)
2634                                 lwkt_process_ipiq();
2635                         if (xcount > 3) {
2636                                 int bcpu = BSFCPUMASK(~md->gd_invltlb_ret &
2637                                                       ~md->mi.gd_cpumask &
2638                                                       smp_active_mask);
2639                                 globaldata_t xgd;
2640
2641                                 kprintf("bcpu %d\n", bcpu);
2642                                 xgd = globaldata_find(bcpu);
2643                                 kprintf("thread %p %s\n", xgd->gd_curthread, xgd->gd_curthread->td_comm);
2644                         }
2645                         if (xcount > 5)
2646                                 Debugger("giving up");
2647                         count = 0;
2648                         goto again;
2649                 }
2650 #endif
2651         }
2652         atomic_clear_cpumask(&smp_invltlb_req, md->mi.gd_cpumask);
2653         crit_exit_gd(&md->mi);
2654 #endif
2655 }
2656
2657 #ifdef SMP
2658
2659 /*
2660  * Called from Xinvltlb assembly with interrupts disabled.  We didn't
2661  * bother to bump the critical section count or nested interrupt count
2662  * so only do very low level operations here.
2663  */
2664 void
2665 smp_invltlb_intr(void)
2666 {
2667         struct mdglobaldata *md = mdcpu;
2668         struct mdglobaldata *omd;
2669         cpumask_t mask;
2670         int cpu;
2671
2672         cpu_mfence();
2673         mask = smp_invltlb_req;
2674         cpu_invltlb();
2675         while (mask) {
2676                 cpu = BSFCPUMASK(mask);
2677                 mask &= ~CPUMASK(cpu);
2678                 omd = (struct mdglobaldata *)globaldata_find(cpu);
2679                 atomic_set_cpumask(&omd->gd_invltlb_ret, md->mi.gd_cpumask);
2680         }
2681 }
2682
2683 #endif
2684
2685 /*
2686  * When called the executing CPU will send an IPI to all other CPUs
2687  *  requesting that they halt execution.
2688  *
2689  * Usually (but not necessarily) called with 'other_cpus' as its arg.
2690  *
2691  *  - Signals all CPUs in map to stop.
2692  *  - Waits for each to stop.
2693  *
2694  * Returns:
2695  *  -1: error
2696  *   0: NA
2697  *   1: ok
2698  *
2699  * XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
2700  *            from executing at same time.
2701  */
2702 int
2703 stop_cpus(cpumask_t map)
2704 {
2705         map &= smp_active_mask;
2706
2707         /* send the Xcpustop IPI to all CPUs in map */
2708         selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
2709         
2710         while ((stopped_cpus & map) != map)
2711                 /* spin */ ;
2712
2713         return 1;
2714 }
2715
2716
2717 /*
2718  * Called by a CPU to restart stopped CPUs. 
2719  *
2720  * Usually (but not necessarily) called with 'stopped_cpus' as its arg.
2721  *
2722  *  - Signals all CPUs in map to restart.
2723  *  - Waits for each to restart.
2724  *
2725  * Returns:
2726  *  -1: error
2727  *   0: NA
2728  *   1: ok
2729  */
2730 int
2731 restart_cpus(cpumask_t map)
2732 {
2733         /* signal other cpus to restart */
2734         started_cpus = map & smp_active_mask;
2735
2736         while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
2737                 /* spin */ ;
2738
2739         return 1;
2740 }
2741
2742 /*
2743  * This is called once the mpboot code has gotten us properly relocated
2744  * and the MMU turned on, etc.   ap_init() is actually the idle thread,
2745  * and when it returns the scheduler will call the real cpu_idle() main
2746  * loop for the idlethread.  Interrupts are disabled on entry and should
2747  * remain disabled at return.
2748  */
2749 void
2750 ap_init(void)
2751 {
2752         u_int   apic_id;
2753
2754         /*
2755          * Adjust smp_startup_mask to signal the BSP that we have started
2756          * up successfully.  Note that we do not yet hold the BGL.  The BSP
2757          * is waiting for our signal.
2758          *
2759          * We can't set our bit in smp_active_mask yet because we are holding
2760          * interrupts physically disabled and remote cpus could deadlock
2761          * trying to send us an IPI.
2762          */
2763         smp_startup_mask |= CPUMASK(mycpu->gd_cpuid);
2764         cpu_mfence();
2765
2766         /*
2767          * Interlock for LAPIC initialization.  Wait until mp_finish_lapic is
2768          * non-zero, then get the MP lock.
2769          *
2770          * Note: We are in a critical section.
2771          *
2772          * Note: we are the idle thread, we can only spin.
2773          *
2774          * Note: The load fence is memory volatile and prevents the compiler
2775          * from improperly caching mp_finish_lapic, and the cpu from improperly
2776          * caching it.
2777          */
2778         while (mp_finish_lapic == 0)
2779                 cpu_lfence();
2780         while (try_mplock() == 0)
2781                 ;
2782
2783         if (cpu_feature & CPUID_TSC) {
2784                 /*
2785                  * The BSP is constantly updating tsc0_offset, figure out
2786                  * the relative difference to synchronize ktrdump.
2787                  */
2788                 tsc_offsets[mycpu->gd_cpuid] = rdtsc() - tsc0_offset;
2789         }
2790
2791         /* BSP may have changed PTD while we're waiting for the lock */
2792         cpu_invltlb();
2793
2794 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
2795         lidt(&r_idt);
2796 #endif
2797
2798         /* Build our map of 'other' CPUs. */
2799         mycpu->gd_other_cpus = smp_startup_mask & ~CPUMASK(mycpu->gd_cpuid);
2800
2801         /* A quick check from sanity claus */
2802         apic_id = (apic_id_to_logical[(lapic->id & 0xff000000) >> 24]);
2803         if (mycpu->gd_cpuid != apic_id) {
2804                 kprintf("SMP: cpuid = %d\n", mycpu->gd_cpuid);
2805                 kprintf("SMP: apic_id = %d lapicid %d\n",
2806                         apic_id, (lapic->id & 0xff000000) >> 24);
2807 #if JGXXX
2808                 kprintf("PTD[MPPTDI] = %p\n", (void *)PTD[MPPTDI]);
2809 #endif
2810                 panic("cpuid mismatch! boom!!");
2811         }
2812
2813         /* Initialize AP's local APIC for irq's */
2814         lapic_init(FALSE);
2815
2816         /* LAPIC initialization is done */
2817         smp_lapic_mask |= CPUMASK(mycpu->gd_cpuid);
2818         cpu_mfence();
2819
2820         /* Let BSP move onto the next initialization stage */
2821         rel_mplock();
2822
2823         /*
2824          * Interlock for finalization.  Wait until mp_finish is non-zero,
2825          * then get the MP lock.
2826          *
2827          * Note: We are in a critical section.
2828          *
2829          * Note: we are the idle thread, we can only spin.
2830          *
2831          * Note: The load fence is memory volatile and prevents the compiler
2832          * from improperly caching mp_finish, and the cpu from improperly
2833          * caching it.
2834          */
2835         while (mp_finish == 0)
2836                 cpu_lfence();
2837         while (try_mplock() == 0)
2838                 ;
2839
2840         /* BSP may have changed PTD while we're waiting for the lock */
2841         cpu_invltlb();
2842
2843         /* Set memory range attributes for this CPU to match the BSP */
2844         mem_range_AP_init();
2845
2846         /*
2847          * Once we go active we must process any IPIQ messages that may
2848          * have been queued, because no actual IPI will occur until we
2849          * set our bit in the smp_active_mask.  If we don't the IPI
2850          * message interlock could be left set which would also prevent
2851          * further IPIs.
2852          *
2853          * The idle loop doesn't expect the BGL to be held and while
2854          * lwkt_switch() normally cleans things up this is a special case
2855          * because we returning almost directly into the idle loop.
2856          *
2857          * The idle thread is never placed on the runq, make sure
2858          * nothing we've done put it there.
2859          */
2860         KKASSERT(get_mplock_count(curthread) == 1);
2861         smp_active_mask |= CPUMASK(mycpu->gd_cpuid);
2862
2863         /*
2864          * Enable interrupts here.  idle_restore will also do it, but
2865          * doing it here lets us clean up any strays that got posted to
2866          * the CPU during the AP boot while we are still in a critical
2867          * section.
2868          */
2869         __asm __volatile("sti; pause; pause"::);
2870         bzero(mdcpu->gd_ipending, sizeof(mdcpu->gd_ipending));
2871
2872         initclocks_pcpu();      /* clock interrupts (via IPIs) */
2873         lwkt_process_ipiq();
2874
2875         /*
2876          * Releasing the mp lock lets the BSP finish up the SMP init
2877          */
2878         rel_mplock();
2879         KKASSERT((curthread->td_flags & TDF_RUNQ) == 0);
2880 }
2881
2882 /*
2883  * Get SMP fully working before we start initializing devices.
2884  */
2885 static
2886 void
2887 ap_finish(void)
2888 {
2889         mp_finish = 1;
2890         if (bootverbose)
2891                 kprintf("Finish MP startup\n");
2892         rel_mplock();
2893         while (smp_active_mask != smp_startup_mask)
2894                 cpu_lfence();
2895         while (try_mplock() == 0)
2896                 ;
2897         if (bootverbose) {
2898                 kprintf("Active CPU Mask: %016jx\n",
2899                         (uintmax_t)smp_active_mask);
2900         }
2901 }
2902
2903 SYSINIT(finishsmp, SI_BOOT2_FINISH_SMP, SI_ORDER_FIRST, ap_finish, NULL)
2904
2905 void
2906 cpu_send_ipiq(int dcpu)
2907 {
2908         if (CPUMASK(dcpu) & smp_active_mask)
2909                 single_apic_ipi(dcpu, XIPIQ_OFFSET, APIC_DELMODE_FIXED);
2910 }
2911
2912 #if 0   /* single_apic_ipi_passive() not working yet */
2913 /*
2914  * Returns 0 on failure, 1 on success
2915  */
2916 int
2917 cpu_send_ipiq_passive(int dcpu)
2918 {
2919         int r = 0;
2920         if (CPUMASK(dcpu) & smp_active_mask) {
2921                 r = single_apic_ipi_passive(dcpu, XIPIQ_OFFSET,
2922                                         APIC_DELMODE_FIXED);
2923         }
2924         return(r);
2925 }
2926 #endif
2927
2928 static int
2929 mptable_bus_info_callback(void *xarg, const void *pos, int type)
2930 {
2931         struct mptable_bus_info *bus_info = xarg;
2932         const struct BUSENTRY *ent;
2933         struct mptable_bus *bus;
2934
2935         if (type != 1)
2936                 return 0;
2937
2938         ent = pos;
2939         TAILQ_FOREACH(bus, &bus_info->mbi_list, mb_link) {
2940                 if (bus->mb_id == ent->bus_id) {
2941                         kprintf("mptable_bus_info_alloc: duplicated bus id "
2942                                 "(%d)\n", bus->mb_id);
2943                         return EINVAL;
2944                 }
2945         }
2946
2947         bus = NULL;
2948         if (strncmp(ent->bus_type, "PCI", 3) == 0) {
2949                 bus = kmalloc(sizeof(*bus), M_TEMP, M_WAITOK | M_ZERO);
2950                 bus->mb_type = MPTABLE_BUS_PCI;
2951         } else if (strncmp(ent->bus_type, "ISA", 3) == 0) {
2952                 bus = kmalloc(sizeof(*bus), M_TEMP, M_WAITOK | M_ZERO);
2953                 bus->mb_type = MPTABLE_BUS_ISA;
2954         }
2955
2956         if (bus != NULL) {
2957                 bus->mb_id = ent->bus_id;
2958                 TAILQ_INSERT_TAIL(&bus_info->mbi_list, bus, mb_link);
2959         }
2960         return 0;
2961 }
2962
2963 static void
2964 mptable_bus_info_alloc(const mpcth_t cth, struct mptable_bus_info *bus_info)
2965 {
2966         int error;
2967
2968         bzero(bus_info, sizeof(*bus_info));
2969         TAILQ_INIT(&bus_info->mbi_list);
2970
2971         error = mptable_iterate_entries(cth, mptable_bus_info_callback, bus_info);
2972         if (error)
2973                 mptable_bus_info_free(bus_info);
2974 }
2975
2976 static void
2977 mptable_bus_info_free(struct mptable_bus_info *bus_info)
2978 {
2979         struct mptable_bus *bus;
2980
2981         while ((bus = TAILQ_FIRST(&bus_info->mbi_list)) != NULL) {
2982                 TAILQ_REMOVE(&bus_info->mbi_list, bus, mb_link);
2983                 kfree(bus, M_TEMP);
2984         }
2985 }
2986
2987 struct mptable_lapic_cbarg1 {
2988         int     cpu_count;
2989         int     ht_fixup;
2990         u_int   ht_apicid_mask;
2991 };
2992
2993 static int
2994 mptable_lapic_pass1_callback(void *xarg, const void *pos, int type)
2995 {
2996         const struct PROCENTRY *ent;
2997         struct mptable_lapic_cbarg1 *arg = xarg;
2998
2999         if (type != 0)
3000                 return 0;
3001         ent = pos;
3002
3003         if ((ent->cpu_flags & PROCENTRY_FLAG_EN) == 0)
3004                 return 0;
3005
3006         arg->cpu_count++;
3007         if (ent->apic_id < 32) {
3008                 arg->ht_apicid_mask |= 1 << ent->apic_id;
3009         } else if (arg->ht_fixup) {
3010                 kprintf("MPTABLE: lapic id > 32, disable HTT fixup\n");
3011                 arg->ht_fixup = 0;
3012         }
3013         return 0;
3014 }
3015
3016 struct mptable_lapic_cbarg2 {
3017         int     cpu;
3018         int     logical_cpus;
3019         int     found_bsp;
3020 };
3021
3022 static int
3023 mptable_lapic_pass2_callback(void *xarg, const void *pos, int type)
3024 {
3025         const struct PROCENTRY *ent;
3026         struct mptable_lapic_cbarg2 *arg = xarg;
3027
3028         if (type != 0)
3029                 return 0;
3030         ent = pos;
3031
3032         if (ent->cpu_flags & PROCENTRY_FLAG_BP) {
3033                 KKASSERT(!arg->found_bsp);
3034                 arg->found_bsp = 1;
3035         }
3036
3037         if (processor_entry(ent, arg->cpu))
3038                 arg->cpu++;
3039
3040         if (arg->logical_cpus) {
3041                 struct PROCENTRY proc;
3042                 int i;
3043
3044                 /*
3045                  * Create fake mptable processor entries
3046                  * and feed them to processor_entry() to
3047                  * enumerate the logical CPUs.
3048                  */
3049                 bzero(&proc, sizeof(proc));
3050                 proc.type = 0;
3051                 proc.cpu_flags = PROCENTRY_FLAG_EN;
3052                 proc.apic_id = ent->apic_id;
3053
3054                 for (i = 1; i < arg->logical_cpus; i++) {
3055                         proc.apic_id++;
3056                         processor_entry(&proc, arg->cpu);
3057                         arg->cpu++;
3058                 }
3059         }
3060         return 0;
3061 }
3062
3063 static void
3064 mptable_lapic_default(void)
3065 {
3066         int ap_apicid, bsp_apicid;
3067
3068         mp_naps = 1; /* exclude BSP */
3069
3070         /* Map local apic before the id field is accessed */
3071         lapic_map(DEFAULT_APIC_BASE);
3072
3073         bsp_apicid = APIC_ID(lapic->id);
3074         ap_apicid = (bsp_apicid == 0) ? 1 : 0;
3075
3076         /* BSP */
3077         mp_set_cpuids(0, bsp_apicid);
3078         /* one and only AP */
3079         mp_set_cpuids(1, ap_apicid);
3080 }
3081
3082 /*
3083  * Configure:
3084  *     mp_naps
3085  *     ID_TO_CPU(N), APIC ID to logical CPU table
3086  *     CPU_TO_ID(N), logical CPU to APIC ID table
3087  */
3088 static void
3089 mptable_lapic_enumerate(struct lapic_enumerator *e)
3090 {
3091         struct mptable_pos mpt;
3092         struct mptable_lapic_cbarg1 arg1;
3093         struct mptable_lapic_cbarg2 arg2;
3094         mpcth_t cth;
3095         int error, logical_cpus = 0;
3096         vm_offset_t lapic_addr;
3097
3098         if (mptable_use_default) {
3099                 mptable_lapic_default();
3100                 return;
3101         }
3102  
3103         error = mptable_map(&mpt);
3104         if (error)
3105                 panic("mptable_lapic_enumerate mptable_map failed\n");
3106         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
3107
3108         cth = mpt.mp_cth;
3109  
3110         /* Save local apic address */
3111         lapic_addr = (vm_offset_t)cth->apic_address;
3112         KKASSERT(lapic_addr != 0);
3113  
3114         /*
3115          * Find out how many CPUs do we have
3116          */
3117         bzero(&arg1, sizeof(arg1));
3118         arg1.ht_fixup = 1; /* Apply ht fixup by default */
3119
3120         error = mptable_iterate_entries(cth,
3121                     mptable_lapic_pass1_callback, &arg1);
3122         if (error)
3123                 panic("mptable_iterate_entries(lapic_pass1) failed\n");
3124         KKASSERT(arg1.cpu_count != 0);
3125  
3126         /* See if we need to fixup HT logical CPUs. */
3127         if (arg1.ht_fixup) {
3128                 logical_cpus = mptable_hyperthread_fixup(arg1.ht_apicid_mask,
3129                                                          arg1.cpu_count);
3130                 if (logical_cpus != 0)
3131                         arg1.cpu_count *= logical_cpus;
3132         }
3133         mp_naps = arg1.cpu_count;
3134  
3135         /* Qualify the numbers again, after possible HT fixup */
3136         if (mp_naps > MAXCPU) {
3137                 kprintf("Warning: only using %d of %d available CPUs!\n",
3138                         MAXCPU, mp_naps);
3139                 DELAY(1000000);
3140                 mp_naps = MAXCPU;
3141         }
3142
3143         --mp_naps;      /* subtract the BSP */
3144
3145         /*
3146          * Link logical CPU id to local apic id
3147          */
3148         bzero(&arg2, sizeof(arg2));
3149         arg2.cpu = 1;
3150         arg2.logical_cpus = logical_cpus;
3151
3152         error = mptable_iterate_entries(cth,
3153                     mptable_lapic_pass2_callback, &arg2);
3154         if (error)
3155                 panic("mptable_iterate_entries(lapic_pass2) failed\n");
3156         KKASSERT(arg2.found_bsp);
3157
3158         /* Map local apic */
3159         lapic_map(lapic_addr);
3160
3161         mptable_unmap(&mpt);
3162 }
3163
3164 struct mptable_lapic_probe_cbarg {
3165         int     cpu_count;
3166         int     found_bsp;
3167 };
3168
3169 static int
3170 mptable_lapic_probe_callback(void *xarg, const void *pos, int type)
3171 {
3172         const struct PROCENTRY *ent;
3173         struct mptable_lapic_probe_cbarg *arg = xarg;
3174
3175         if (type != 0)
3176                 return 0;
3177         ent = pos;
3178
3179         if ((ent->cpu_flags & PROCENTRY_FLAG_EN) == 0)
3180                 return 0;
3181         arg->cpu_count++;
3182
3183         if (ent->cpu_flags & PROCENTRY_FLAG_BP) {
3184                 if (arg->found_bsp) {
3185                         kprintf("more than one BSP in base MP table\n");
3186                         return EINVAL;
3187                 }
3188                 arg->found_bsp = 1;
3189         }
3190         return 0;
3191 }
3192
3193 static int
3194 mptable_lapic_probe(struct lapic_enumerator *e)
3195 {
3196         struct mptable_pos mpt;
3197         struct mptable_lapic_probe_cbarg arg;
3198         mpcth_t cth;
3199         int error;
3200
3201         if (mptable_fps_phyaddr == 0)
3202                 return ENXIO;
3203
3204         if (mptable_use_default)
3205                 return 0;
3206
3207         error = mptable_map(&mpt);
3208         if (error)
3209                 return error;
3210         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
3211
3212         error = EINVAL;
3213         cth = mpt.mp_cth;
3214
3215         if (cth->apic_address == 0)
3216                 goto done;
3217
3218         bzero(&arg, sizeof(arg));
3219         error = mptable_iterate_entries(cth,
3220                     mptable_lapic_probe_callback, &arg);
3221         if (!error) {
3222                 if (arg.cpu_count == 0) {
3223                         kprintf("MP table contains no processor entries\n");
3224                         error = EINVAL;
3225                 } else if (!arg.found_bsp) {
3226                         kprintf("MP table does not contains BSP entry\n");
3227                         error = EINVAL;
3228                 }
3229         }
3230 done:
3231         mptable_unmap(&mpt);
3232         return error;
3233 }
3234
3235 static struct lapic_enumerator  mptable_lapic_enumerator = {
3236         .lapic_prio = LAPIC_ENUM_PRIO_MPTABLE,
3237         .lapic_probe = mptable_lapic_probe,
3238         .lapic_enumerate = mptable_lapic_enumerate
3239 };
3240
3241 static void
3242 mptable_lapic_enum_register(void)
3243 {
3244         lapic_enumerator_register(&mptable_lapic_enumerator);
3245 }
3246 SYSINIT(mptable_lapic, SI_BOOT2_PRESMP, SI_ORDER_ANY,
3247         mptable_lapic_enum_register, 0);
3248
3249 static int
3250 mptable_ioapic_list_callback(void *xarg, const void *pos, int type)
3251 {
3252         const struct IOAPICENTRY *ent;
3253         struct mptable_ioapic *nioapic, *ioapic;
3254
3255         if (type != 2)
3256                 return 0;
3257         ent = pos;
3258
3259         if ((ent->apic_flags & IOAPICENTRY_FLAG_EN) == 0)
3260                 return 0;
3261
3262         if (ent->apic_address == 0) {
3263                 kprintf("mptable_ioapic_create_list: zero IOAPIC addr\n");
3264                 return EINVAL;
3265         }
3266
3267         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
3268                 if (ioapic->mio_apic_id == ent->apic_id) {
3269                         kprintf("mptable_ioapic_create_list: duplicated "
3270                                 "apic id %d\n", ioapic->mio_apic_id);
3271                         return EINVAL;
3272                 }
3273                 if (ioapic->mio_addr == ent->apic_address) {
3274                         kprintf("mptable_ioapic_create_list: overlapped "
3275                                 "IOAPIC addr 0x%08x", ioapic->mio_addr);
3276                         return EINVAL;
3277                 }
3278         }
3279
3280         nioapic = kmalloc(sizeof(*nioapic), M_DEVBUF, M_WAITOK | M_ZERO);
3281         nioapic->mio_apic_id = ent->apic_id;
3282         nioapic->mio_addr = ent->apic_address;
3283
3284         /*
3285          * Create IOAPIC list in ascending order of APIC ID
3286          */
3287         TAILQ_FOREACH_REVERSE(ioapic, &mptable_ioapic_list,
3288             mptable_ioapic_list, mio_link) {
3289                 if (nioapic->mio_apic_id > ioapic->mio_apic_id) {
3290                         TAILQ_INSERT_AFTER(&mptable_ioapic_list,
3291                             ioapic, nioapic, mio_link);
3292                         break;
3293                 }
3294         }
3295         if (ioapic == NULL)
3296                 TAILQ_INSERT_HEAD(&mptable_ioapic_list, nioapic, mio_link);
3297
3298         return 0;
3299 }
3300
3301 static void
3302 mptable_ioapic_create_list(void)
3303 {
3304         struct mptable_ioapic *ioapic;
3305         struct mptable_pos mpt;
3306         int idx, error;
3307
3308         if (mptable_fps_phyaddr == 0)
3309                 return;
3310
3311         if (mptable_use_default) {
3312                 ioapic = kmalloc(sizeof(*ioapic), M_DEVBUF, M_WAITOK | M_ZERO);
3313                 ioapic->mio_idx = 0;
3314                 ioapic->mio_apic_id = 0;        /* NOTE: any value is ok here */
3315                 ioapic->mio_addr = 0xfec00000;  /* XXX magic number */
3316
3317                 TAILQ_INSERT_HEAD(&mptable_ioapic_list, ioapic, mio_link);
3318                 return;
3319         }
3320
3321         error = mptable_map(&mpt);
3322         if (error)
3323                 panic("mptable_ioapic_create_list: mptable_map failed\n");
3324         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
3325
3326         error = mptable_iterate_entries(mpt.mp_cth,
3327                     mptable_ioapic_list_callback, NULL);
3328         if (error) {
3329                 while ((ioapic = TAILQ_FIRST(&mptable_ioapic_list)) != NULL) {
3330                         TAILQ_REMOVE(&mptable_ioapic_list, ioapic, mio_link);
3331                         kfree(ioapic, M_DEVBUF);
3332                 }
3333                 goto done;
3334         }
3335
3336         /*
3337          * Assign index number for each IOAPIC
3338          */
3339         idx = 0;
3340         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
3341                 ioapic->mio_idx = idx;
3342                 ++idx;
3343         }
3344 done:
3345         mptable_unmap(&mpt);
3346 }
3347 SYSINIT(mptable_ioapic_list, SI_BOOT2_PRESMP, SI_ORDER_SECOND,
3348         mptable_ioapic_create_list, 0);
3349
3350 static int
3351 mptable_pci_int_callback(void *xarg, const void *pos, int type)
3352 {
3353         const struct mptable_bus_info *bus_info = xarg;
3354         const struct mptable_ioapic *ioapic;
3355         const struct mptable_bus *bus;
3356         struct mptable_pci_int *pci_int;
3357         const struct INTENTRY *ent;
3358         int pci_pin, pci_dev;
3359
3360         if (type != 3)
3361                 return 0;
3362         ent = pos;
3363
3364         if (ent->int_type != 0)
3365                 return 0;
3366
3367         TAILQ_FOREACH(bus, &bus_info->mbi_list, mb_link) {
3368                 if (bus->mb_type == MPTABLE_BUS_PCI &&
3369                     bus->mb_id == ent->src_bus_id)
3370                         break;
3371         }
3372         if (bus == NULL)
3373                 return 0;
3374
3375         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
3376                 if (ioapic->mio_apic_id == ent->dst_apic_id)
3377                         break;
3378         }
3379         if (ioapic == NULL) {
3380                 kprintf("MPTABLE: warning PCI int dst apic id %d "
3381                         "does not exist\n", ent->dst_apic_id);
3382                 return 0;
3383         }
3384
3385         pci_pin = ent->src_bus_irq & 0x3;
3386         pci_dev = (ent->src_bus_irq >> 2) & 0x1f;
3387
3388         TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link) {
3389                 if (pci_int->mpci_bus == ent->src_bus_id &&
3390                     pci_int->mpci_dev == pci_dev &&
3391                     pci_int->mpci_pin == pci_pin) {
3392                         if (pci_int->mpci_ioapic_idx == ioapic->mio_idx &&
3393                             pci_int->mpci_ioapic_pin == ent->dst_apic_int) {
3394                                 kprintf("MPTABLE: warning duplicated "
3395                                         "PCI int entry for "
3396                                         "bus %d, dev %d, pin %d\n",
3397                                         pci_int->mpci_bus,
3398                                         pci_int->mpci_dev,
3399                                         pci_int->mpci_pin);
3400                                 return 0;
3401                         } else {
3402                                 kprintf("mptable_pci_int_register: "
3403                                         "conflict PCI int entry for "
3404                                         "bus %d, dev %d, pin %d, "
3405                                         "IOAPIC %d.%d -> %d.%d\n",
3406                                         pci_int->mpci_bus,
3407                                         pci_int->mpci_dev,
3408                                         pci_int->mpci_pin,
3409                                         pci_int->mpci_ioapic_idx,
3410                                         pci_int->mpci_ioapic_pin,
3411                                         ioapic->mio_idx,
3412                                         ent->dst_apic_int);
3413                                 return EINVAL;
3414                         }
3415                 }
3416         }
3417
3418         pci_int = kmalloc(sizeof(*pci_int), M_DEVBUF, M_WAITOK | M_ZERO);
3419
3420         pci_int->mpci_bus = ent->src_bus_id;
3421         pci_int->mpci_dev = pci_dev;
3422         pci_int->mpci_pin = pci_pin;
3423         pci_int->mpci_ioapic_idx = ioapic->mio_idx;
3424         pci_int->mpci_ioapic_pin = ent->dst_apic_int;
3425
3426         TAILQ_INSERT_TAIL(&mptable_pci_int_list, pci_int, mpci_link);
3427
3428         return 0;
3429 }
3430
3431 static void
3432 mptable_pci_int_register(void)
3433 {
3434         struct mptable_bus_info bus_info;
3435         const struct mptable_bus *bus;
3436         struct mptable_pci_int *pci_int;
3437         struct mptable_pos mpt;
3438         int error, force_pci0, npcibus;
3439         mpcth_t cth;
3440
3441         if (mptable_fps_phyaddr == 0)
3442                 return;
3443
3444         if (mptable_use_default)
3445                 return;
3446
3447         if (TAILQ_EMPTY(&mptable_ioapic_list))
3448                 return;
3449
3450         error = mptable_map(&mpt);
3451         if (error)
3452                 panic("mptable_pci_int_register: mptable_map failed\n");
3453         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
3454
3455         cth = mpt.mp_cth;
3456
3457         mptable_bus_info_alloc(cth, &bus_info);
3458         if (TAILQ_EMPTY(&bus_info.mbi_list))
3459                 goto done;
3460
3461         force_pci0 = 0;
3462         npcibus = 0;
3463         TAILQ_FOREACH(bus, &bus_info.mbi_list, mb_link) {
3464                 if (bus->mb_type == MPTABLE_BUS_PCI)
3465                         ++npcibus;
3466         }
3467         if (npcibus == 0) {
3468                 mptable_bus_info_free(&bus_info);
3469                 goto done;
3470         } else if (npcibus == 1) {
3471                 force_pci0 = 1;
3472         }
3473
3474         error = mptable_iterate_entries(cth,
3475                     mptable_pci_int_callback, &bus_info);
3476
3477         mptable_bus_info_free(&bus_info);
3478
3479         if (error) {
3480                 while ((pci_int = TAILQ_FIRST(&mptable_pci_int_list)) != NULL) {
3481                         TAILQ_REMOVE(&mptable_pci_int_list, pci_int, mpci_link);
3482                         kfree(pci_int, M_DEVBUF);
3483                 }
3484                 goto done;
3485         }
3486
3487         if (force_pci0) {
3488                 TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link)
3489                         pci_int->mpci_bus = 0;
3490         }
3491 done:
3492         mptable_unmap(&mpt);
3493 }
3494 SYSINIT(mptable_pci, SI_BOOT2_PRESMP, SI_ORDER_ANY,
3495         mptable_pci_int_register, 0);
3496
3497 struct mptable_ioapic_probe_cbarg {
3498         const struct mptable_bus_info *bus_info;
3499 };
3500
3501 static int
3502 mptable_ioapic_probe_callback(void *xarg, const void *pos, int type)
3503 {
3504         struct mptable_ioapic_probe_cbarg *arg = xarg;
3505         const struct mptable_ioapic *ioapic;
3506         const struct mptable_bus *bus;
3507         const struct INTENTRY *ent;
3508
3509         if (type != 3)
3510                 return 0;
3511         ent = pos;
3512
3513         if (ent->int_type != 0)
3514                 return 0;
3515
3516         TAILQ_FOREACH(bus, &arg->bus_info->mbi_list, mb_link) {
3517                 if (bus->mb_type == MPTABLE_BUS_ISA &&
3518                     bus->mb_id == ent->src_bus_id)
3519                         break;
3520         }
3521         if (bus == NULL)
3522                 return 0;
3523
3524         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
3525                 if (ioapic->mio_apic_id == ent->dst_apic_id)
3526                         break;
3527         }
3528         if (ioapic == NULL) {
3529                 kprintf("MPTABLE: warning ISA int dst apic id %d "
3530                         "does not exist\n", ent->dst_apic_id);
3531                 return 0;
3532         }
3533
3534         /* XXX magic number */
3535         if (ent->src_bus_irq >= 16) {
3536                 kprintf("mptable_ioapic_probe: invalid ISA irq (%d)\n",
3537                         ent->src_bus_irq);
3538                 return EINVAL;
3539         }
3540         return 0;
3541 }
3542
3543 static int
3544 mptable_ioapic_probe(struct ioapic_enumerator *e)
3545 {
3546         struct mptable_ioapic_probe_cbarg arg;
3547         struct mptable_bus_info bus_info;
3548         struct mptable_pos mpt;
3549         mpcth_t cth;
3550         int error;
3551
3552         if (mptable_fps_phyaddr == 0)
3553                 return ENXIO;
3554
3555         if (mptable_use_default)
3556                 return 0;
3557
3558         if (TAILQ_EMPTY(&mptable_ioapic_list))
3559                 return ENXIO;
3560
3561         error = mptable_map(&mpt);
3562         if (error)
3563                 panic("mptable_ioapic_probe: mptable_map failed\n");
3564         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
3565
3566         cth = mpt.mp_cth;
3567
3568         mptable_bus_info_alloc(cth, &bus_info);
3569
3570         bzero(&arg, sizeof(arg));
3571         arg.bus_info = &bus_info;
3572
3573         error = mptable_iterate_entries(cth,
3574                     mptable_ioapic_probe_callback, &arg);
3575
3576         mptable_bus_info_free(&bus_info);
3577         mptable_unmap(&mpt);
3578
3579         return error;
3580 }
3581
3582 struct mptable_ioapic_int_cbarg {
3583         const struct mptable_bus_info *bus_info;
3584         int     ioapic_nint;
3585 };
3586
3587 static int
3588 mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
3589 {
3590         struct mptable_ioapic_int_cbarg *arg = xarg;
3591         const struct mptable_ioapic *ioapic;
3592         const struct mptable_bus *bus;
3593         const struct INTENTRY *ent;
3594
3595         if (type != 3)
3596                 return 0;
3597
3598         arg->ioapic_nint++;
3599
3600         ent = pos;
3601         if (ent->int_type != 0)
3602                 return 0;
3603
3604         TAILQ_FOREACH(bus, &arg->bus_info->mbi_list, mb_link) {
3605                 if (bus->mb_type == MPTABLE_BUS_ISA &&
3606                     bus->mb_id == ent->src_bus_id)
3607                         break;
3608         }
3609         if (bus == NULL)
3610                 return 0;
3611
3612         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
3613                 if (ioapic->mio_apic_id == ent->dst_apic_id)
3614                         break;
3615         }
3616         if (ioapic == NULL) {
3617                 kprintf("MPTABLE: warning ISA int dst apic id %d "
3618                         "does not exist\n", ent->dst_apic_id);
3619                 return 0;
3620         }
3621
3622         if (!ioapic_use_old) {
3623                 int gsi;
3624
3625                 if (ent->dst_apic_int >= ioapic->mio_npin) {
3626                         panic("mptable_ioapic_enumerate: invalid I/O APIC "
3627                               "pin %d, should be < %d",
3628                               ent->dst_apic_int, ioapic->mio_npin);
3629                 }
3630                 gsi = ioapic->mio_gsi_base + ent->dst_apic_int;
3631
3632                 if (ent->src_bus_irq != gsi) {
3633                         if (bootverbose) {
3634                                 kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
3635                                         ent->src_bus_irq, gsi);
3636                         }
3637                         ioapic_intsrc(ent->src_bus_irq, gsi,
3638                             INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
3639                 }
3640         } else {
3641                 /* XXX rough estimation */
3642                 if (ent->src_bus_irq != ent->dst_apic_int) {
3643                         if (bootverbose) {
3644                                 kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
3645                                         ent->src_bus_irq, ent->dst_apic_int);
3646                         }
3647                 }
3648         }
3649         return 0;
3650 }
3651
3652 static void
3653 mptable_ioapic_enumerate(struct ioapic_enumerator *e)
3654 {
3655         struct mptable_bus_info bus_info;
3656         struct mptable_ioapic *ioapic;
3657         struct mptable_pos mpt;
3658         mpcth_t cth;
3659         int error;
3660
3661         KKASSERT(mptable_fps_phyaddr != 0);
3662         KKASSERT(!TAILQ_EMPTY(&mptable_ioapic_list));
3663
3664         TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
3665                 if (!ioapic_use_old) {
3666                         const struct mptable_ioapic *prev_ioapic;
3667                         uint32_t ver;
3668                         void *addr;
3669
3670                         addr = ioapic_map(ioapic->mio_addr);
3671
3672                         ver = ioapic_read(addr, IOAPIC_VER);
3673                         ioapic->mio_npin = ((ver & IOART_VER_MAXREDIR)
3674                                             >> MAXREDIRSHIFT) + 1;
3675
3676                         prev_ioapic = TAILQ_PREV(ioapic,
3677                                         mptable_ioapic_list, mio_link);
3678                         if (prev_ioapic == NULL) {
3679                                 ioapic->mio_gsi_base = 0;
3680                         } else {
3681                                 ioapic->mio_gsi_base =
3682                                         prev_ioapic->mio_gsi_base +
3683                                         prev_ioapic->mio_npin;
3684                         }
3685                         ioapic_add(addr, ioapic->mio_gsi_base,
3686                             ioapic->mio_npin);
3687                 }
3688                 if (bootverbose) {
3689                         kprintf("MPTABLE: IOAPIC addr 0x%08x, "
3690                                 "apic id %d, idx %d, gsi base %d, npin %d\n",
3691                                 ioapic->mio_addr,
3692                                 ioapic->mio_apic_id,
3693                                 ioapic->mio_idx,
3694                                 ioapic->mio_gsi_base,
3695                                 ioapic->mio_npin);
3696                 }
3697         }
3698
3699         if (mptable_use_default) {
3700                 if (bootverbose)
3701                         kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (default)\n");
3702                 ioapic_intsrc(0, 2, INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
3703                 return;
3704         }
3705
3706         error = mptable_map(&mpt);
3707         if (error)
3708                 panic("mptable_ioapic_probe: mptable_map failed\n");
3709         KKASSERT(!MPTABLE_POS_USE_DEFAULT(&mpt));
3710
3711         cth = mpt.mp_cth;
3712
3713         mptable_bus_info_alloc(cth, &bus_info);
3714
3715         if (TAILQ_EMPTY(&bus_info.mbi_list)) {
3716                 if (bootverbose)
3717                         kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (no bus)\n");
3718                 ioapic_intsrc(0, 2, INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
3719         } else {
3720                 struct mptable_ioapic_int_cbarg arg;
3721
3722                 bzero(&arg, sizeof(arg));
3723                 arg.bus_info = &bus_info;
3724
3725                 error = mptable_iterate_entries(cth,
3726                             mptable_ioapic_int_callback, &arg);
3727                 if (error)
3728                         panic("mptable_ioapic_int failed\n");
3729
3730                 if (arg.ioapic_nint == 0) {
3731                         if (bootverbose) {
3732                                 kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 "
3733                                         "(no int)\n");
3734                         }
3735                         ioapic_intsrc(0, 2, INTR_TRIGGER_EDGE,
3736                             INTR_POLARITY_HIGH);
3737                 }
3738         }
3739
3740         mptable_bus_info_free(&bus_info);
3741
3742         mptable_unmap(&mpt);
3743 }
3744
3745 static struct ioapic_enumerator mptable_ioapic_enumerator = {
3746         .ioapic_prio = IOAPIC_ENUM_PRIO_MPTABLE,
3747         .ioapic_probe = mptable_ioapic_probe,
3748         .ioapic_enumerate = mptable_ioapic_enumerate
3749 };
3750
3751 static void
3752 mptable_ioapic_enum_register(void)
3753 {
3754         ioapic_enumerator_register(&mptable_ioapic_enumerator);
3755 }
3756 SYSINIT(mptable_ioapic, SI_BOOT2_PRESMP, SI_ORDER_ANY,
3757         mptable_ioapic_enum_register, 0);
3758
3759 void
3760 mptable_pci_int_dump(void)
3761 {
3762         const struct mptable_pci_int *pci_int;
3763
3764         TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link) {
3765                 kprintf("MPTABLE: %d:%d INT%c -> IOAPIC %d.%d\n",
3766                         pci_int->mpci_bus,
3767                         pci_int->mpci_dev,
3768                         pci_int->mpci_pin + 'A',
3769                         pci_int->mpci_ioapic_idx,
3770                         pci_int->mpci_ioapic_pin);
3771         }
3772 }
3773
3774 int
3775 mptable_pci_int_route(int bus, int dev, int pin, int intline)
3776 {
3777         const struct mptable_pci_int *pci_int;
3778         int irq = -1;
3779
3780         KKASSERT(pin >= 1);
3781         --pin;  /* zero based */
3782
3783         TAILQ_FOREACH(pci_int, &mptable_pci_int_list, mpci_link) {
3784                 if (pci_int->mpci_bus == bus &&
3785                     pci_int->mpci_dev == dev &&
3786                     pci_int->mpci_pin == pin)
3787                         break;
3788         }
3789         if (pci_int != NULL) {
3790                 int gsi;
3791
3792                 gsi = ioapic_gsi(pci_int->mpci_ioapic_idx,
3793                         pci_int->mpci_ioapic_pin);
3794                 if (gsi >= 0) {
3795                         irq = ioapic_abi_find_gsi(gsi,
3796                                 INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
3797                 }
3798         }
3799
3800         if (irq < 0) {
3801                 if (bootverbose) {
3802                         kprintf("MPTABLE: fixed interrupt routing "
3803                                 "for %d:%d INT%c\n", bus, dev, pin + 'A');
3804                 }
3805
3806                 irq = ioapic_abi_find_irq(intline,
3807                         INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
3808         }
3809
3810         if (irq >= 0 && bootverbose) {
3811                 kprintf("MPTABLE: %d:%d INT%c routed to irq %d\n",
3812                         bus, dev, pin + 'A', irq);
3813         }
3814         return irq;
3815 }